Created
April 12, 2020 20:43
-
-
Save obormot/73f251e16b6396a2bab1f303e50ad0c3 to your computer and use it in GitHub Desktop.
cryptohack.org/challenges
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # py2 | |
| # for each character of plaintext we could observe many variants of ciphertext value (XORed) | |
| # but we'll never observe the actual value (no leaks!) | |
| # so we could collect enough data and exclude what we have observed | |
| # we end up with something we've never observed - the actual bytes of the key | |
| import base64, socket, json | |
| conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
| conn.connect(('socket.cryptohack.org', 13370)) | |
| conn.recv(100) # "No leaks" | |
| req = json.dumps({"msg": "request"}) + '\n' # const request | |
| chars = [set(range(256)) for _ in range(12)] # 12 = length of the actual flag | |
| for i in range(10000): # will break earlier | |
| conn.send(req) | |
| resp = json.loads(conn.recv(50)) | |
| if 'error' in resp: | |
| continue | |
| ct = base64.b64decode(resp['ciphertext']) | |
| ct = ct[7:-1] # omit 'crypto{' and '}' | |
| for pos in range(12): | |
| chars[pos].discard(ord(ct[pos])) | |
| # show progress | |
| print i, [len(cc) for cc in chars] | |
| # this can be optimized to the target character set to run faster | |
| if all(len(cc) == 1 for cc in chars): | |
| print '** took', i, 'iterations' | |
| break | |
| print 'flag: crypto{{{}}}'.format(''.join(chr(list(c)[0]) for c in chars)) | |
| conn.close() | |
| # >>> chars | |
| # [{117}, {110}, {114}, {52}, {110}, {100}, {48}, {109}, {95}, {48}, {55}, {112}] | |
| # ** took 2125 iterations | |
| # flag: crypto{unr4nd0m_07p} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment