{"id":18265892,"url":"https://github.com/mpgn/poodle-poc","last_synced_at":"2025-04-09T09:06:35.413Z","repository":{"id":26804407,"uuid":"30262874","full_name":"mpgn/poodle-PoC","owner":"mpgn","description":":poodle: Poodle (Padding Oracle On Downgraded Legacy Encryption) attack CVE-2014-3566 :poodle:","archived":false,"fork":false,"pushed_at":"2023-10-06T16:11:26.000Z","size":68,"stargazers_count":256,"open_issues_count":5,"forks_count":72,"subscribers_count":16,"default_branch":"master","last_synced_at":"2025-04-02T06:07:58.312Z","etag":null,"topics":["attacker","cryptography","padding","poc","poodle","python","sslv3"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mpgn.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null},"funding":{"github":["mpgn"]}},"created_at":"2015-02-03T20:28:27.000Z","updated_at":"2025-03-14T10:33:33.000Z","dependencies_parsed_at":"2023-01-14T05:19:20.238Z","dependency_job_id":"182339b9-0803-469b-b202-4bd67992cf5d","html_url":"https://github.com/mpgn/poodle-PoC","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mpgn%2Fpoodle-PoC","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mpgn%2Fpoodle-PoC/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mpgn%2Fpoodle-PoC/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mpgn%2Fpoodle-PoC/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mpgn","download_url":"https://codeload.github.com/mpgn/poodle-PoC/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248008630,"owners_count":21032556,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["attacker","cryptography","padding","poc","poodle","python","sslv3"],"created_at":"2024-11-05T11:20:31.673Z","updated_at":"2025-04-09T09:06:35.392Z","avatar_url":"https://github.com/mpgn.png","language":"Python","funding_links":["https://github.com/sponsors/mpgn"],"categories":[],"sub_categories":[],"readme":"# Poodle PoC :poodle: :poodle: :poodle: \n\nA proof of concept of the Poodle Attack (Padding Oracle On Downgraded Legacy Encryption) :\n\n\u003e a man-in-the-middle exploit which takes advantage of Internet and security software clients' fallback to SSL 3.0\n\nThe Poodle attack allow you to retrieve encrypted data send by a client to a server if the Transport Layer Security used is SSLv3. It does not allow you to retrieve the private key used to encrypt the request. \n\n![imgonline-com-ua-twotoone-luefsrwi2n8iqy](https://user-images.githubusercontent.com/5891788/38616224-81b01940-3d93-11e8-9d59-e825e7ff6f4b.jpg)\n\n### 1. :poodle: Concept of the attack :poodle:\n\n#### SSLv3 and CBC cipher mode\n\nSSLv3 is a protocol to encrypt/decrypt and secure your data. In our case, he uses the [CBC cipher mode chainning](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher_Block_Chaining_.28CBC.29) . The plaintext is divided into block regarding the encryption alogithm (AES,DES, 3DES) and the length is a mulitple of 8 or 16. If the plaintext don't fill the length, a [padding](https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7) is added at the end to complete the missing space. I strongly advice you to open this images of [encryption](https://upload.wikimedia.org/wikipedia/commons/thumb/8/80/CBC_encryption.svg/601px-CBC_encryption.svg.png) and [decryption](https://upload.wikimedia.org/wikipedia/commons/thumb/2/2a/CBC_decryption.svg/601px-CBC_decryption.svg.png) to read this readme.\n\n\nEncryption | Decryption\n--- | --- \nC\u003csub\u003ei\u003c/sub\u003e = E\u003csub\u003ek\u003c/sub\u003e(P\u003csub\u003ei\u003c/sub\u003e ⊕ C\u003csub\u003ei-1\u003c/sub\u003e), and C\u003csub\u003e0\u003c/sub\u003e = IV | P\u003csub\u003ei\u003c/sub\u003e = D\u003csub\u003ek\u003c/sub\u003e(C\u003csub\u003ei\u003c/sub\u003e) ⊕ C\u003csub\u003ei-1\u003c/sub\u003e, and C\u003csub\u003e0\u003c/sub\u003e = IV\n \nBasically this is just some simple XOR, you can also watch this video (not me) https://www.youtube.com/watch?v=0D7OwYp6ZEc.\n\nA request send over HTTPS using SSLv3 will be ciphered with AES/DES and the mode CBC. The particularity of SSlv3 over TLS1.x is the padding. In SSLv3 the padding is fill with random bytes except the last byte equal to the length of the padding.\n\nExample:\n\n`T|E|X|T|0xab|0x10|0x02` where `0xab|0x10|0x02` is the padding. \u003cbr /\u003e\n`T|E|X|T|E|0x5c|0x01`    where `0x5c|0x01` is the padding.\n\nAlso the last block can be fill with a full block of padding meaning the last block can be full a random byte except the last byte.\n\n`T|E|X|T|E|0x5c|0x01|0x3c|0x09|0x5d|0x08|0x04|0x07`    where `|0x5c|0x01|0x3c|0x09|0x5d|0x08|0x04|0x07` is the padding on only the `0x07` is know by the attacker. So if an attacker is able to influence the padding block, he will be able to know that the last byte of the last block is equal to the length of a block.\n\n#### Influence the padding\n\nAn attacker must be able to make the victim send requests (using javascript by exploiting an XSS for example). Then he can control the path and the data of each request: \n\nExample: adding \"A\" byte to the path of the request\n```\nGET / HTTP/1.1\\r\\nSECRET COOKIE\\r\\n\\r\\n\nGET /AAA HTTP/1.1\\r\\nSECRET COOKIE\\r\\n\\r\\nDATA\n```\n\nWith this technique he can influence the padding.\n\n#### HMAC\n\nSSLv3 also use [HMAC](https://en.wikipedia.org/wiki/Hash-based_message_authentication_code) to check the integrity and authenticate of the plaintext.\n\n\u003e keyed-hash message authentication code (HMAC) is a specific type of message authentication code (MAC) involving a cryptographic hash function (hence the 'H') in combination with a secret cryptographic key\n\nWith this an attacker can't intercept and alter the request then send it back. If the server encounter a problem, he will send an HMAC error.\n\n#### MAC-then-encrypt\n\nThe protocl SSLv3 use the following routine: he receives the data from the client, decrypt the data, check the integrity with the HMAC.\n\n\u003e MAC-then-Encrypt:\n\u003e Does not provide any integrity on the ciphertext, since we have no way of knowing until we decrypt the message whether it was indeed authentic or spoofed.\n\u003e Plaintext integrity.\n\u003e If the cipher scheme is malleable it may be possible to alter the message to appear valid and have a valid MAC. This is a theoretical point, of course, since practically speaking the MAC secret \u003e should provide protection.\n\u003e Here, the MAC cannot provide any information on the plaintext either, since it is encrypted.\n\nhttps://crypto.stackexchange.com/questions/202/should-we-mac-then-encrypt-or-encrypt-then-mac\n\nThis mean that we can alter the ciphered text without the server knowing it. this is great, really :)\n\n### 2. :key: Cryptography :key: \n\nFirst the last block need to be full of padding, like we see previously the attacker use path of the request and check the length of the request. \n\n* He saves the length of the original cipher\n* He adds one byte in the path and check the length. \n\t- If the length doesn't change he adds another byte etc.\n\t- Else : the length of the cipher request change, he knows the last block is full of padding. \n\nSince the last block except the last byte is full of random bytes he can replace this last block C\u003csub\u003en\u003c/sub\u003e by the block he wants to decrypt C\u003csub\u003ei\u003c/sub\u003e. The altered request is send to the server.\n\nThe server :\n* remove the padding regarding the length of the last byte\n* get the hmac from the request = HMAC\n* get the plaintext\n* compare hmac(plaintext) and HMAC\n\t- if equal =\u003e good padding\n\t- else =\u003e bad padding\n\n\nBy replacing the last block the attacker also changes the the last byte of the last block (the length of the padding). There is 1/256 the last byte replace in the padding block is the same than the orginal, in this case there will be no padding error and the attacker can use this XOR operation to retrieve the last byte of the block C\u003csub\u003ei\u003c/sub\u003e by following this operation :\n\nP\u003csub\u003en\u003c/sub\u003e = D\u003csub\u003ek\u003c/sub\u003e(C\u003csub\u003en\u003c/sub\u003e) ⊕ C\u003csub\u003en-1\u003c/sub\u003e\u003cbr /\u003e\nP\u003csub\u003en\u003c/sub\u003e = D\u003csub\u003ek\u003c/sub\u003e(C\u003csub\u003ei\u003c/sub\u003e) ⊕ C\u003csub\u003en-1\u003c/sub\u003e\u003cbr /\u003e\nP\u003csub\u003en\u003c/sub\u003e = D\u003csub\u003ek\u003c/sub\u003e(C\u003csub\u003ei\u003c/sub\u003e) ⊕ C\u003csub\u003en-1\u003c/sub\u003e\u003cbr /\u003e\nxxxxxxx7\t  = D\u003csub\u003ek\u003c/sub\u003e(C\u003csub\u003ei\u003c/sub\u003e) ⊕ C\u003csub\u003en-1\u003c/sub\u003e\u003cbr /\u003e\nD\u003csub\u003ek\u003c/sub\u003e(C\u003csub\u003ei\u003c/sub\u003e) = xxxxxxx7 ⊕ C\u003csub\u003en-1\u003c/sub\u003e\u003cbr /\u003e\nP\u003csub\u003ei\u003c/sub\u003e ⊕ C\u003csub\u003ei-1\u003c/sub\u003e = xxxxxxx7 ⊕ C\u003csub\u003en-1\u003c/sub\u003e\u003cbr /\u003e\nP\u003csub\u003ei\u003c/sub\u003e = C\u003csub\u003ei-1\u003c/sub\u003e ⊕ xxxxxxx7 ⊕ C\u003csub\u003en-1\u003c/sub\u003e\u003cbr /\u003e\n\n(xxxxxxx7 or xxxxxxx15 and x random byte)\n\nThe last byte of the block can be retrieve P\u003csub\u003ei\u003c/sub\u003e[7] = C\u003csub\u003ei-1\u003c/sub\u003e[7] ⊕ xxxxxxx7 ⊕ C\u003csub\u003en-1\u003c/sub\u003e[7]\nIn case of padding the attacker need to close the SSL session to make another handshake (new AES key) and get new cipher then replace the last block etc. (generaly +300 handshake needed)\n\nOnce one byte is retrieve he will get all the other byte of the block by adding a byte in the path and remove one byte in the data :\n\n\n| Request to retrieve  byte E,I,K,O |\n|---|\n| GET /a SECRET_COOKIE dataazerty PADDING_7 |\n| GET /aa SECRET_COOKIE dataazert PADDING_7 |\n| GET /aaa SECRET_COOKIE dataazer PADDING_7 |\n| GET /aaaa SECRET_COOKIE dataaze PADDING_7 |\n\n\n#### About TLS1.0\n\n\u003e Even though TLS specifications require servers to check the padding, some implementations fail to validate it properly, which makes some servers vulnerable to POODLE even if they disable SSL 3.0\n\nTLS is normaly safe against Poodle, but some implementations don't check the padding, it's like if we used SSLv3, this is why some TLS version are vulnerable.\n\n### 3. :boom: Start the attack :boom:\n\nThere is three files in this repository:\n- poodle-poc.py -\u003e A Proof Of Concept that doesn't require any prerequise\n- parallelization-poodle.py -\u003e ANother Proof Of Concept but using parallelization (really fast)\n- poodle-exploit.py -\u003e An exploit for real-case scenario\n\n##### 1. The poodle-poc.py file\n\nThis poc explore the cryptography behind the attack. This file allow us to understand how the attack works in a simple way.\n\n```bash\npython3 poodle-poc.py\n```\n\n##### 2. The poodle-poc.py file\n\nThe file `parallelization-poodle.py` is a project, and idea :) check https://github.com/mpgn/poodle-PoC/issues/1\n```bash\npython3 parallelization-poodle.py\n```\n\n[![asciicast](https://asciinema.org/a/cuj891xnb8djk5luiwilr9igk.png)](https://asciinema.org/a/cuj891xnb8djk5luiwilr9igk)\n\n\n##### 3. The poodle-exploit.py file\n\nThis is the real exploit. Really usefull with you want to make a proof a concept about the Poodle Attack for a client during a pentest if he used old server and browser. Just put the ip of your malicious proxy into the config browser with the correct port, the proxy will take care of the rest.\n\n**Requirement:**\n- make sure the client and the browser can communicate with the protocol SSLv3 **only**, force only SSLv3 in firefox using `security.tls.version.min: 0` for example. Alternatively, if the client also use TLS you can force the downgrade\n- make sure the server is vulnerable, use the tool [testssl.sh](https://testssl.sh/)\n![image](https://user-images.githubusercontent.com/5891788/51736286-f97f7900-2089-11e9-9bc2-814c5b30213f.png)\n- make sure you can inject Javascript on the client side (XSS)\n- make sure you can intercept the connection between the client and the server\n\n:skull: **If you have these prerequisites you can start the attack** :skull::\n\nTow options ara available for this exploit:\n\n1. Setup the IP adress and the port of the proxy directly on the client side and run the exploit ( go to the part 3)\n2. Setup an ARP spoofing attack to redirect all the traffic between the client and the server on your machine\n\n  - Enable the forwarding and set an Iptable rule to redirect the traffic from the client to your proxy\n```bash\n$\u003e echo 1 \u003e /proc/sys/net/ipv4/ip_forward\n$\u003e iptables -i vmnet1 -t nat -A PREROUTING -p tcp --dport 1337 -j REDIRECT --to-ports 1337\n```\n\n  - Use the tool `arpspoof`, `ettercap` or `bettercap` to run an ARP spoofing attack\n```bash\n$\u003e bettercap -iface vmnet1\nnet.show\nset arp.spoof.internal true\narp.spoof on\n```\n\n3. Run the proxy\n\n```zsh\n⋊\u003e ~/T/poodle-Poc on master ⨯ python3 poodle-exploit.py -h              13:10:24\nusage: poodle-exploit.py [-h] [--start-block START_BLOCK]\n                         [--stop-block STOP_BLOCK] [--simpleProxy SIMPLEPROXY]\n                         proxy port server rport\n\nPoodle Exploit by @mpgn_x64\n\npositional arguments:\n  proxy                 ip of the proxy\n  port                  port of the proxy\n  server                ip of the remote server\n  rport                 port of the remote server\n\noptional arguments:\n  -h, --help            show this help message and exit\n  --start-block START_BLOCK\n                        start the attack at this block\n  --stop-block STOP_BLOCK\n                        stop the attack at this block\n  --simpleProxy SIMPLEPROXY\n                        Direct proxy, no ARP spoofing attack\n\n$\u003e python3 poodle-exploit.py 192.168.13.1 4443 192.168.13.133 443 --start-block 46 --stop-block 50\n```\nChoosing a block: if you don't specify the block option, all the block will be decrypted but this can take a long time. I strongly advise you 'know' how the request will be formated and use the script `request-splitter.py` to know the block you want to decrypt (idealy the cookie block ! :)\n\nThen insert the javascript malicious code (`poodle.js`) into the vulnerable website using an XSS for example. Launch the python script and type `help`, then `search`, and finaly `active`. During that time, only two interactions with the javascript will be needed (search and active command).\n\n**Update 01/04/2018**: downgrade option has been added to the exploit. When the exploit detect the TLS protocol, enter the command `downgrade` to downgrade to SSLv3.0. \n\nHow it works ? during the handshake (after the hello client), the exploit send a __handshake_failure__ `15030000020228` then the browser should resend a hello client with SSLv3.0 as default protocol. Tested on chrome version 15 but it's not working on Firefox (I think he doesn't support protocol renegociation), check [#4](https://github.com/mpgn/poodle-PoC/issues/4)\n\nFull video of the exploitation: \n\n![ezgif-3-90a926f34356](https://user-images.githubusercontent.com/5891788/52007165-399d8c00-24ce-11e9-8934-919493401c65.gif)\n\nAsciinema: \n\n[![asciicast](https://asciinema.org/a/174901.png)](https://asciinema.org/a/174901)\n\n## Contributor\n\n[mpgn](https://github.com/mpgn) \n\n### Licence\n\n[licence MIT](https://github.com/mpgn/poodle-PoC/blob/master/LICENSE)\n\n## References\n\n* https://en.wikipedia.org/wiki/POODLE\n* https://www.openssl.org/~bodo/ssl-poodle.pdf\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmpgn%2Fpoodle-poc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmpgn%2Fpoodle-poc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmpgn%2Fpoodle-poc/lists"}