# Checker

Bài cho thẳng 1 file Python luôn.

Như tên bài thì nó là 1 checker
Mình sẽ comment bên cạnh code luôn cho dễ trace, đi từ hàm main cho dễ hiểu
Source code
```python
import sys
import hmac
import hashlib
ITERS = 1
SALT_A = bytes([196,8,106,71,60,169,89,72,228,89,219,245,149,143,29,107])
SALT_B = bytes([216,251,234,149,154,121,170,190,74,117,44,154,47,109,237,188])
DK_A = bytes([168,87,241,174,190,23,101,74,127,86,161,217,164,88,65,190,100,69,213,45,148,65,34,199,151,253,153,172,85,101,193,107])
DK_B = bytes([13,235,207,168,10,48,191,193,16,238,246,98,11,190,50,45,165,65,185,179,171,25,190,199,203,84,57,172,216,245,0,219])
def xorb(a: bytes, b: bytes) -> bytes:
if len(a) != len(b): #khác len thì báo lỗi
raise ValueError("xor length mismatch")
return bytes(x ^ y for x, y in zip(a, b)) #so 2 chuỗi bytes với nhau rồi return
def derive(user_flag: bytes) -> bytes:
salt = xorb(SALT_A, SALT_B) #tính salt
return hashlib.pbkdf2_hmac("sha256", user_flag, salt, ITERS, dklen=32) #thêm salt vào và băm input bằng sha256 với 1 vòng lặp PBKDF2
def expected() -> bytes:
return xorb(DK_A, DK_B) #trả về giá trị sau khi xor
def normalize(s: str) -> bytes: # hàm chuẩn hoá
s = s.strip()
return s.encode("utf-8", "strict")
def main():
if len(sys.argv) >= 2:
inp = sys.argv[1] # nếu truyền tham số khi run thì lấy argv[1] làm input
else:
inp = input("Flag: ") #nhập input
try:
candidate = normalize(inp) #gọi hàm normalize để chuẩn hoá input
except UnicodeError:
print("Invalid input.")
return 1
dk = derive(candidate) #tính derived key từ input
ok = hmac.compare_digest(dk, expected()) #cmp dk với expected()
if ok:
print("Correct!")
return 0
else:
print("Wrong!")
return 1
if __name__ == "__main__": # gọi main
raise SystemExit(main())
```
Nói 1 cách dễ hiểu thì chương trình lấy input, sau đó thêm salt rồi tạo hash, và so sánh cái hash đó với 1 giá trị expected()
Ở đây giá trị expected thì đơn giản rồi, tự tính ra được
Ta chỉ cần chú ý đoạn `return hashlib.pbkdf2_hmac("sha256", user_flag, salt, ITERS, dklen=32)`. Với việc sử dụng hàm băm nên là việc giải ngược là vô x, bắt buộc phải thử sai, và do ITER = 1 nên việc bruteforce là khả thi (đề bài cũng hint như thế)
Solve:
```python
import itertools,string,hashlib,hmac,sys
SALT_A = bytes([196,8,106,71,60,169,89,72,228,89,219,245,149,143,29,107])
SALT_B = bytes([216,251,234,149,154,121,170,190,74,117,44,154,47,109,237,188])
DK_A = bytes([168,87,241,174,190,23,101,74,127,86,161,217,164,88,65,190,100,69,213,45,148,65,34,199,151,253,153,172,85,101,193,107])
DK_B = bytes([13,235,207,168,10,48,191,193,16,238,246,98,11,190,50,45,165,65,185,179,171,25,190,199,203,84,57,172,216,245,0,219])
ITERS = 1
def xorb(a,b): return bytes(x^y for x,y in zip(a,b))
salt = xorb(SALT_A,SALT_B)
expected = xorb(DK_A,DK_B)
pref,suff="InfosecPTIT{","}"
lib = string.ascii_letters + string.digits + "_{}-@!#$%^&*()+=:;,.?/\\|<>[]~`\"'"
for i in itertools.count(1):
for char in itertools.product(lib,repeat=i):
mid="".join(char)
flag = (pref + mid + suff).encode()
dk = hashlib.pbkdf2_hmac("sha256",flag,salt,ITERS,dklen=32)
if hmac.compare_digest(dk,expected):
print("Flag : ",flag.decode())
sys.exit(0)
```
<details>
<summary><b>FLAG</b></summary>
InfosecPTIT{gggg}
</details>