# crypto hack ## Great Snakes Run python code -> get flag: ```python #!/usr/bin/env python3 import sys # import this if sys.version_info.major == 2: print("You are running Python 2, which is no longer supported. Please update to Python 3.") ords = [81, 64, 75, 66, 70, 93, 73, 72, 1, 92, 109, 2, 84, 109, 66, 75, 70, 90, 2, 92, 79] print("Here is your flag:") print("".join(chr(o ^ 0x32) for o in ords)) ``` flag: `crypto{z3n_0f_pyth0n}` ## ASCII ASCII là mã chuẩn hóa 7bits cho phép biểu diễn văn bản bằng số nguyên -> có thể dùng chr() để convert từ số thứ tự sang char và ord là ngược lại. [99, 114, 121, 112, 116, 111, 123, 65, 83, 67, 73, 73, 95, 112, 114, 49, 110, 116, 52, 98, 108, 51, 125] -> chuyển thành flag: ```python ints = [99, 114, 121, 112, 116, 111, 123, 65, 83, 67, 73, 73, 95, 112, 114, 49, 110, 116, 52, 98, 108, 51, 125] print("".join([chr(i) for i in ints]))``` flag: `crypto{ASCII_pr1nt4bl3}` ## Hex Thông thường trong những chall này, thì kết quả khi được mã hóa(hay còn gọi là ciphertext sẽ thường có các bytes không thể in được các kí tự ASCII) -> do đó những output được gửi cho ta thành một cái gì đó thân thiện và di động hơn trên các hệ thống khác nhau là cần thiết. Và hexadecimal(hệ 16) có thể sử dụng như vậy để biểu diễn chúng: đầu tiên từng ký tự sẽ chuyển bằng ord() sang số thứ tự -> tiếp đó hệ decimal được chuyển thành hệ hexadecimal -> các số nối lại tạo thành chuỗi dài. Python có thể dùng `bytes.fromhex()` để chuyển đổi hex thành byte và `.hex()` để chuyển byte thành hex. ```python hex = "63727970746f7b596f755f77696c6c5f62655f776f726b696e675f776974685f6865785f737472696e67735f615f6c6f747d" print(bytes.fromhex(hex)) ``` flag: `crypto{You_will_be_working_with_hex_strings_a_lot}` ## Base64 base64 biểu diễn mã hóa bằng bảng chữ cái 64 kí tự `import base64`, `base64.b64encode()` ```python import base64 hex = "72bca9b68fc16ac7beeb8f849dca1d8a783e8acf9679bf9269f7bf" bytes = bytes.fromhex(hex) print(base64.b64encode(bytes)) ``` flag: `b'crypto/Base+64+Encoding+is+Web+Safe/'` ## Bytes and Big Integers các hệ thống mã hóa trên rsa hoạt động trên các số, nhưng các thông điệp được tạo thành từ các ký tự, để chuyển đổi các thông điệp của mình thành các số để các phép toán có thể được áp dụng. Cách phổ biến là lất từng byte của tin nhắn -> chuyển đổi chúng thành hex. Ví dụ: ``` message: HELLO ascii bytes: [72, 69, 76, 76, 79] hex bytes: [0x48, 0x45, 0x4c, 0x4c, 0x4f] base-16: 0x48454c4c4f base-10: 310400273487 ``` Trong python có PyCryptodome thực hiện nó với các phương thức`bytes_to_long()` và `long_to_bytes()` -> cài đặt PyCryptodome và import bằng `from Crypto.Util.number import *` ``` from Crypto.Util.number import * print(long_to_bytes(11515195063862318899931685488813747395775516287289682636499965282714637259206269)) crypto{3nc0d1n6_4ll_7h3_w4y_d0wn} ``` ## XOR Starter là một toán tử bitwise trả về 0 nếu các bit same nhau và 1 nếu không. kí hiệu `^` ``` ------------ |A|B|output| ------------ |0|0|0| ------- |0|1|1| ------- |1|0|1| ------- |1|1|0| ------- ``` trong python có `pwntools` tiện lợi để `xor()` Để XOR hai chuỗi: Chuyển từng ký tự sang mã Unicode (ord()) XOR từng cặp ký tự tương ứng Sau đó có thể chuyển kết quả về ký tự (chr()), nếu muốn kết quả là chuỗi XOR giữa các số nguyên (decimal): ``` a = 6 # 0110 b = 10 # 1010 c = a ^ b # 1100 = 12 print(c) # Output: 12 ``` ``` from pwn import xor label = b"label" key = 13 result = xor(label, key) print(f"crypto{{{result.decode()}}}") label = "label" new_str = "" for c in label: new_str += chr(ord(c) ^ 13) print(f"crypto{{{new_str}}}") ``` flag: `crypto{aloha}` ## XOR attribute Commutative: A ⊕ B = B ⊕ A Associative: A ⊕ (B ⊕ C) = (A ⊕ B) ⊕ C Identity: A ⊕ 0 = A Self-Inverse: A ⊕ A = 0 ``` KEY1 = a6c8b6733c9b22de7bc0253266a3867df55acde8635e19c73313 KEY2 ^ KEY1 = 37dcb292030faa90d07eec17e3b1c6d8daf94c35d4c9191a5e1e KEY2 ^ KEY3 = c1545756687e7573db23aa1c3452a098b71a7fbf0fddddde5fc1 FLAG ^ KEY1 ^ KEY3 ^ KEY2 = 04ee9855208a2cd59091d04767ae47963170d1660df7f56f5faf ``` Tư duy đơn giản, kiểu giải toán thôi: k1 xor k2 xor k1 = (k1 xor k1) xor k1 = 0 xor k2 = k2 -> tìm ra k2 tương tự k2 xor k2 xor k3 -> tìm được k3 FLAG xor k1 xor k2 xor k3 xor k1 xor k2 xor k3 = FLAG XOR 0 XOR 0 XOR 0 = FLAG ```python from pwn import xor KEY1 = bytes.fromhex("a6c8b6733c9b22de7bc0253266a3867df55acde8635e19c73313") XOR_KEY2_KEY1 = bytes.fromhex("37dcb292030faa90d07eec17e3b1c6d8daf94c35d4c9191a5e1e") XOR_KEY2_KEY3 = bytes.fromhex("c1545756687e7573db23aa1c3452a098b71a7fbf0fddddde5fc1") XOR_ALL_KEYS_FLAG = bytes.fromhex("04ee9855208a2cd59091d04767ae47963170d1660df7f56f5faf") #KEY2: XOR_KEY2_KEY1 ^ KEY1 KEY2 = xor(XOR_KEY2_KEY1, KEY1) #KEY3: XOR_KEY2_KEY3 ^ KEY2 KEY3 = xor(XOR_KEY2_KEY3, KEY2) #FLAG: XOR_ALL_KEYS_FLAG ^ KEY1 ^ KEY2 ^ KEY3 FLAG = xor(xor(xor(XOR_ALL_KEYS_FLAG, KEY1), KEY2), KEY3) print(f"{FLAG.decode()}") ``` flag: `crypto{x0r_i5_ass0c1at1v3}` ## Favourite byte I've hidden some data using XOR with a single byte, but that byte is a secret. Don't forget to decode from hex first. `73626960647f6b206821204f21254f7d694f7624662065622127234f726927756d` ```python from pwn import xor flagBytes = bytes.fromhex("73626960647f6b206821204f21254f7d694f7624662065622127234f726927756d") byte=0x00 for i in range(256): flag=xor(flagBytes, byte).decode("utf-8") if("crypto" in flag): print(flag) break byte=byte + 0x01 ``` flag: `crypto{0x10_15_my_f4v0ur173_by7e}` # Modular Arithmetic ## Greatest Common Divisor (GCD) ước chung lớn nhất của 2 số - số lớn nhất trong giao của 2 tập hợp ước chung của từng số. có nhiều thuật toán tìm như sàng, euclid, millerabin. -> ở đây sẽ dùng euclid để tính gcd(66528, 52920). ```python def gcd(a,b): if a<b: a,b = b,a while b!=0: a,b = b,a%b return a print(gcd(66528,52920)) ``` answer: 1512 ## Extended GCD(euclid mở rộng) cho a và b là số nguyên dương -> Extend Euclide là cách hiệu quả tìm u,v sao cho: `u.a+b.v = gcd(a,b)` -> này hay được dùng trong RSA. ```python def extended_gcd(a, b): if b == 0: return (a, 1, 0) else: g, x1, y1 = extended_gcd(b, a % b) x = y1 y = x1 - (a // b) * y1 return (g, x, y) g, x, y = extended_gcd(26513, 32321) print(g ,x, y) 1, 10245, -8404 ``` ## Modular Arithmetic 1 giống toán chuyên đề thôi: ![image](https://hackmd.io/_uploads/Hy_XirWmlg.png) ```python x = 11 % 6 y = 8146798528947 % 17 print(x if (x < y) else y) 4 ``` ## Modular Arithmetic 2 giống toán chuyên đề, fermat thôi: ![image](https://hackmd.io/_uploads/SJ6tnBbQlx.png) ```python print(pow(273246787654, 65536, 65537)) 1 ``` ## Modular Inverting (Nghịch đảo modulo)