{"id":13537445,"url":"https://github.com/hellman/xortool","last_synced_at":"2025-05-14T12:12:06.546Z","repository":{"id":1322718,"uuid":"1267824","full_name":"hellman/xortool","owner":"hellman","description":"A tool to analyze multi-byte xor cipher","archived":false,"fork":false,"pushed_at":"2023-05-09T12:44:51.000Z","size":291,"stargazers_count":1432,"open_issues_count":7,"forks_count":177,"subscribers_count":48,"default_branch":"master","last_synced_at":"2025-05-10T01:06:29.277Z","etag":null,"topics":["cryptanalysis","cryptography","xor-cipher","xortool"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hellman.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2011-01-18T17:26:05.000Z","updated_at":"2025-05-02T05:38:49.000Z","dependencies_parsed_at":"2023-07-05T17:15:21.531Z","dependency_job_id":null,"html_url":"https://github.com/hellman/xortool","commit_stats":{"total_commits":100,"total_committers":19,"mean_commits":"5.2631578947368425","dds":0.6799999999999999,"last_synced_commit":"c01ec91dfcd0ea7fbbf6fc4bf04ef8a85ce2500a"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hellman%2Fxortool","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hellman%2Fxortool/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hellman%2Fxortool/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hellman%2Fxortool/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hellman","download_url":"https://codeload.github.com/hellman/xortool/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254140768,"owners_count":22021220,"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":["cryptanalysis","cryptography","xor-cipher","xortool"],"created_at":"2024-08-01T09:00:59.196Z","updated_at":"2025-05-14T12:12:06.527Z","avatar_url":"https://github.com/hellman.png","language":"Python","readme":"xortool.py\n====================\n\nA tool to do some xor analysis:\n\n  - guess the key length (based on count of equal chars)\n  - guess the key (base on knowledge of most frequent char)\n\n**Notice:** xortool is now only running on Python 3. The old Python 2 version is accessible at the `py2` branch. The **pip** package has been updated.\n\n## Installation\n\n```bash\n$ pip3 install xortool\n```\n\nFor development or building this repository, [poetry](https://python-poetry.org/) is needed.\n\n\n```bash\npoetry build\npip install dist/xortool*.whl\n```\n\nUsage\n---------------------\n\n```\nxortool\n  A tool to do some xor analysis:\n  - guess the key length (based on count of equal chars)\n  - guess the key (base on knowledge of most frequent char)\n\nUsage:\n  xortool [-x] [-m MAX-LEN] [-f] [-t CHARSET] [FILE]\n  xortool [-x] [-l LEN] [-c CHAR | -b | -o] [-f] [-t CHARSET] [-p PLAIN] [FILE]\n  xortool [-x] [-m MAX-LEN| -l LEN] [-c CHAR | -b | -o] [-f] [-t CHARSET] [-p PLAIN] [FILE]\n  xortool [-h | --help]\n  xortool --version\n\nOptions:\n  -x --hex                          input is hex-encoded str\n  -l LEN, --key-length=LEN          length of the key\n  -m MAX-LEN, --max-keylen=MAX-LEN  maximum key length to probe [default: 65]\n  -c CHAR, --char=CHAR              most frequent char (one char or hex code)\n  -b --brute-chars                  brute force all possible most frequent chars\n  -o --brute-printable              same as -b but will only check printable chars\n  -f --filter-output                filter outputs based on the charset\n  -t CHARSET --text-charset=CHARSET target text character set [default: printable]\n  -p PLAIN --known-plaintext=PLAIN  use known plaintext for decoding\n  -h --help                         show this help\n\nNotes:\n  Text character set:\n    * Pre-defined sets: printable, base32, base64\n    * Custom sets:\n      - a: lowercase chars\n      - A: uppercase chars\n      - 1: digits\n      - !: special chars\n      - *: printable chars\n\nExamples:\n  xortool file.bin\n  xortool -l 11 -c 20 file.bin\n  xortool -x -c ' ' file.hex\n  xortool -b -f -l 23 -t base64 message.enc\n  xortool -b -p \"xctf{\" message.enc\n```\n\nExample 1\n---------------------\n\n```bash\n# xor is xortool/xortool-xor\ntests $ xor -f /bin/ls -s \"secret_key\" \u003e binary_xored\n\ntests $ xortool binary_xored\nThe most probable key lengths:\n   2:   5.0%\n   5:   8.7%\n   8:   4.9%\n  10:   15.4%\n  12:   4.8%\n  15:   8.5%\n  18:   4.8%\n  20:   15.1%\n  25:   8.4%\n  30:   14.9%\nKey-length can be 5*n\nMost possible char is needed to guess the key!\n\n# 00 is the most frequent byte in binaries\ntests $ xortool binary_xored -l 10 -c 00\n...\n1 possible key(s) of length 10:\nsecret_key\n\n# decrypted ciphertexts are placed in ./xortool_out/Number_\u003ckey repr\u003e\n# ( have no better idea )\ntests $ md5sum xortool_out/0_secret_key /bin/ls\n29942e290876703169e1b614d0b4340a  xortool_out/0_secret_key\n29942e290876703169e1b614d0b4340a  /bin/ls\n```\n\nThe most common use is to pass just the encrypted file and the most frequent character (usually 00 for binaries and 20 for text files) - length will be automatically chosen:\n\n```bash\ntests $ xortool tool_xored -c 20\nThe most probable key lengths:\n   2:   5.6%\n   5:   7.8%\n   8:   6.0%\n  10:   11.7%\n  12:   5.6%\n  15:   7.6%\n  20:   19.8%\n  25:   7.8%\n  28:   5.7%\n  30:   11.4%\nKey-length can be 5*n\n1 possible key(s) of length 20:\nan0ther s3cret \\xdd key\n```\n\nHere, the key is longer then default 32 limit:\n\n```bash\ntests $ xortool ls_xored -c 00 -m 64\nThe most probable key lengths:\n   3:   3.3%\n   6:   3.3%\n   9:   3.3%\n  11:   7.0%\n  22:   6.9%\n  24:   3.3%\n  27:   3.2%\n  33:   18.4%\n  44:   6.8%\n  55:   6.7%\nKey-length can be 3*n\n1 possible key(s) of length 33:\nreally long s3cr3t k3y... PADDING\n```\n\nSo, if automated decryption fails, you can calibrate:\n\n- (`-m`) max length to try longer keys\n- (`-l`) selected length to see some interesting keys\n- (`-c`) the most frequent char to produce right plaintext\n\nExample 2\n---------------------\n\nWe are given a message in encoded in Base64 and XORed with an unknown key.\n\n```bash\n# xortool message.enc\nThe most probable key lengths:\n   2:   12.3%\n   4:   13.8%\n   6:   10.5%\n   8:   11.5%\n  10:   8.6%\n  12:   9.4%\n  14:   7.1%\n  16:   7.8%\n  23:   10.4%\n  46:   8.7%\nKey-length can be 4*n\nMost possible char is needed to guess the key!\n```\n\nWe can now test the key lengths while filtering the outputs so that it only keeps the plaintexts holding the character set of Base64. After trying a few lengths, we come to the right one, which gives only 1 plaintext with a percentage of valid characters above the default threshold of 95%.\n\n```bash\n$ xortool message.enc -b -f -l 23 -t base64\n256 possible key(s) of length 23:\n\\x01=\\x121#\"0\\x17\\x13\\t\\x7f ,\u0026/\\x12s\\x114u\\x170#\n\\x00\u003c\\x130\"#1\\x16\\x12\\x08~!-\\'.\\x13r\\x105t\\x161\"\n\\x03?\\x103! 2\\x15\\x11\\x0b}\".$-\\x10q\\x136w\\x152!\n\\x02\u003e\\x112 !3\\x14\\x10\\n|#/%,\\x11p\\x127v\\x143\n\\x059\\x165\\'\u00264\\x13\\x17\\r{$(\"+\\x16w\\x150q\\x134\\'\n...\nFound 1 plaintexts with 95.0%+ valid characters\nSee files filename-key.csv, filename-char_used-perc_valid.csv\n```\n\nBy filtering the outputs on the character set of Base64, we directly keep the only solution.\n\nInformation\n---------------------\n\nAuthor: hellman\n\nLicense: [MIT License](https://opensource.org/licenses/MIT)\n","funding_links":[],"categories":["Deobfuscation","Tools","\u003ca id=\"9eee96404f868f372a6cbc6769ccb7f8\"\u003e\u003c/a\u003e新添加的","Python","3. [↑](#-content) Cryptography","\u003ca id=\"862af330f45f21fbb0d495837fc7e879\"\u003e\u003c/a\u003e工具","Crypto","Cryptography","工具"],"sub_categories":["Other Resources","Tools","\u003ca id=\"31185b925d5152c7469b963809ceb22d\"\u003e\u003c/a\u003e新添加的","3.1 [↑](#-content) Cryptography","\u003ca id=\"20bf2e2fefd6de7aadbf0774f4921824\"\u003e\u003c/a\u003e未分类-Password","工具"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhellman%2Fxortool","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhellman%2Fxortool","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhellman%2Fxortool/lists"}