## CryptoHack Courses * #### ASCII 1. ASCII is a 7-bit encoding standard which allows the representation of text using the integers 0-127. 1. In Python, the `chr()` function can be used to convert an ASCII ordinal number to a character (the `ord()` function does the opposite). > **CHALLENGE** ```python= ascii = [99, 114, 121, 112, 116, 111, 123, 65, 83, 67, 73, 73, 95, 112, 114, 49, 110, 116, 52, 98, 108, 51, 125] for i in range(len(ascii)): print(chr(ascii[i]), end="") #chr(),數字轉字符 #end=""用途為讓每次輸出後不換行(預設為end="\n") # Output: crypto{ASCII_pr1nt4bl3} ``` * #### HEX 1. In Python, the `bytes.fromhex()` function can be used to convert hex to bytes. The `.hex()` instance method can be called on byte strings to get the hex representation. > **CHALLENGE** ```python= hex = "63727970746f7b596f755f77696c6c5f62655f776f726b696e675f776974685f6865785f737472696e67735f615f6c6f747d" result = bytes.fromhex(hex).decode('utf-8') print(result) # Output: crypto{You_will_be_working_with_hex_strings_a_lot} ``` * #### Base64 1. Represent binary data as an ASCII string using an alphabet of 64 characters. 2. One character of a Base64 string encodes 6 binary digits (bits), and so 4 characters of Base64 encode three 8-bit bytes. 3. In Python, after importing the base64 module with `import base64`, you can use the `base64.b64encode()` function. Remember to decode the hex first as the challenge description states. > **CHALLENGE** ```python= import base64 a = "72bca9b68fc16ac7beeb8f849dca1d8a783e8acf9679bf9269f7bf" print(base64.b64encode(bytes.fromhex(a)).decode()) # base64.b64encode(),將bytes轉換為base64編碼 # Output: crypto/Base+64+Encoding+is+Web+Safe/ ``` * #### Bytes and Big Integers 1. Python's PyCryptodome library implements this with the methods `bytes_to_long()` and `long_to_bytes()`. You will first have to install PyCryptodome and import it with `from Crypto.Util.number import *` > **CHALLENGE** ```python= from Crypto.Util.number import * print(long_to_bytes(11515195063862318899931685488813747395775516287289682636499965282714637259206269).decode()) #long_to_bytes(),將數字轉換為bytes #Output: crypto{3nc0d1n6_4ll_7h3_w4y_d0wn} ``` * #### XOR | A | B | Output | | --- | --- | ------ | | 0 | 0 | 0 | | 0 | 1 | 1 | | 1 | 0 | 1 | | 1 | 1 | 0 | ``` EX: 0110 ^ 1010 = 1100 ``` > **CHALLENGE** ```python= from pwn import xor result = xor(b'label', 13) print(result.decode()) #將label與13做XOR運算 #Output: aloha ``` ``` 交換律: A ⊕ B = B ⊕ A 結合律: A ⊕ (B ⊕ C) = (A ⊕ B) ⊕ C 恆等律: A ⊕ 0 = A 歸零律: A ⊕ A = 0 ``` > **CHALLENGE** ```python= from pwn import xor #KEY1 = a6c8b6733c9b22de7bc0253266a3867df55acde8635e19c73313 #KEY2 ^ KEY1 = 37dcb292030faa90d07eec17e3b1c6d8daf94c35d4c9191a5e1e #KEY2 ^ KEY3 = c1545756687e7573db23aa1c3452a098b71a7fbf0fddddde5fc1 #FLAG ^ KEY1 ^ KEY3 ^ KEY2 = 04ee9855208a2cd59091d04767ae47963170d1660df7f56f5faf key1 = bytes.fromhex('a6c8b6733c9b22de7bc0253266a3867df55acde8635e19c73313') key2_1 = bytes.fromhex('37dcb292030faa90d07eec17e3b1c6d8daf94c35d4c9191a5e1e') # key2^key1 key2_3 = bytes.fromhex('c1545756687e7573db23aa1c3452a098b71a7fbf0fddddde5fc1') # key2^key3 flag_132 = bytes.fromhex('04ee9855208a2cd59091d04767ae47963170d1660df7f56f5faf') # flag^key1^key3^key2 print(xor(flag_132, key2_3, key1).decode()) # Output: crypto{x0r_i5_ass0c1at1v3} ``` > **CHALLENGE** ```python= from pwn import xor str = bytes.fromhex('73626960647f6b206821204f21254f7d694f7624662065622127234f726927756d') for i in range(256): result = xor(str, i).decode() if 'crypto{' in result: print(result) break #用迴圈去爆破,之後如果xor出來的字串有crypto就輸出 #Output: crypto{0x10_15_my_f4v0ur173_by7e} ``` ```python= from pwn import * str = bytes.fromhex("0e0b213f26041e480b26217f27342e175d0e070a3c5b103e2526217f27342e175d0e077e263451150104") keyword = b"crypto{" for i in range(0, len(keyword)): print(xor(str[i], keyword[i]).decode(),end="") print("") #用"crypto{"推出他secretkey前面的7個字元 #得出"myXORke" 可猜測完整secretkey為"myXORkey" print(xor(str, b"myXORkey").decode()) #將str與"myXORkey"做XOR運算 #Output: crypto{1f_y0u_Kn0w_En0uGH_y0u_Kn0w_1t_4ll} ``` * 圖片XOR圖片 ```python= from PIL import Image lemur = Image.open(r'lemur.png') flag = Image.open(r'flag.png') pixels_lemur = lemur.load() # create the pixel map pixels_flag = flag.load() for i in range(lemur.size[0]): # for every pixel: for j in range(lemur.size[1]): # Gather each pixel l = pixels_lemur[i,j] f = pixels_flag[i,j] # XOR each part of the pixel tuple r = l[0] ^ f[0] g = l[1] ^ f[1] b = l[2] ^ f[2] # Store the resulatant tuple back into an image pixels_flag[i,j] = (r, g, b) flag.save("result.png") ``` `flag.png` ![flag](https://hackmd.io/_uploads/r1Fauidkgg.png) `lemur.png` ![lemur](https://hackmd.io/_uploads/SyFauodygl.png) `result.png` ![result](https://hackmd.io/_uploads/rJqfYiuyel.png) * #### python找最大公因數 ```python= from math import gcd a=66528 b=52920 print(gcd(a,b)) # Output: 1512 ``` * #### 擴展歐基里德算法 (Extended Euclidean algorithm) -> https://hackmd.io/@Koios/rJ_lER719 -> https://ithelp.ithome.com.tw/m/articles/10320272 EGCD 除了求出最大公因數外,還能找到一組整數解 x 和 y,滿足: ``` ax + by = gcd(a, b) ``` > **CHALLENGE** 找出當p=26513 和 q=32321 時滿足pu+qv=gcd(p,q)時的u和v ```python= from egcd import egcd p=26513 q=32321 print(egcd(p,q)) # Output: (1, 10245, -8404) ``` > **CHALLENGE** ``` 11 ≡ x mod 6 #11跟x在除以6的情況下,有相同的餘數 8146798528947 ≡ y mod 17 ``` ```python= x = 11 % 6 y = 8146798528947 % 17 print(x, y) ```