# CryptoHack Part1: Introduction and General
## Introduction
### Finding flag

- Nhìn vào ta có thu được `flag` với format là: `crypto{...}`
- Mục đích challeng này yêu cầu ta nhận định được đâu là `flag` cần lấy
### Great Snakes

- Challeng cho ta file python và yêu cầu ta sử dụng python để run để lấy flag.

- Mục đích challeng này là yêu cầu ta học cách sử dụng python.
### Network Attacks

- Challenge gợi ý cho ta cách để giao tiếp với máy chủ để giải quyết vấn đề một cách trực tiếp.
- Đọc file python challenge cung cấp ta thu được cách để lấy flag là câu lệnh `{"buy": "flag"}` sau khi kết nối với máy chủ bằng câu lệnh ` nc socket.cryptohack.org 11112`

## General
### ENCODING
#### ASCII

- Challenge cho ta các số, dựa vào tên bài ta xác định được các số này liên quan đến bảng mã `ACSII`
- Challenge cũng gợi ý ta sử dụng `chr` trong python để giải quyết.
- `ord()`: chuyển 1 ký tự về mã tương ứng trên Unicode, nhận type str trả về type int.
- `chr()`: chuyển số về mã Unicode tương ứng, nhận type int trả về type str.
```Python
c= [99, 114, 121, 112, 116, 111, 123, 65, 83, 67, 73, 73, 95, 112, 114, 49, 110, 116, 52, 98, 108, 51, 125]
flag= str()
for i in c:
flag += chr(i)
print(flag)
```

#### Hex

- Challenge cho ta một chuỗi ký tự và dựa vào tên bài ta xác định được chuỗi đó chính là chuỗi `hex` và có gợi ý cho ta hàm `bytes.fromhex()` để chuyển chuỗi từ `hex` sang `bytes`
```Python
c='63727970746f7b596f755f77696c6c5f62655f776f726b696e675f776974685f6865785f737472696e67735f615f6c6f747d'
flag= bytes.fromhex(c)
print(flag)
```

#### Base64

- Challenge cho ta một chuỗi ký tự và dựa vào tên bài ta xác định chuỗi đó có liên quan đến `Base64`, ta sẽ thử decode theo base64.
```Python
import base64
flag= bytes.fromhex('72bca9b68fc16ac7beeb8f849dca1d8a783e8acf9679bf9269f7bf')
flag= base64.b64encode(flag)
print(flag)
```

#### Bytes and Big Integers

- Challenge giới thiệu một vài kiểu dữ liệu căn bản như `ascii`, `hex`, `base10`, `base64` và yêu cầu ta chuyển chuỗi cung cấp bằng cách cách sử dụng hàm `long_to_bytes` trong thư viện `Crypto.Util.number`.
```Python
from Crypto.Util.number import *
flag= long_to_bytes(11515195063862318899931685488813747395775516287289682636499965282714637259206269)
print(flag)
```

#### Encoding Challenge

- Challenge cung cấp thông tin cho ta như sau:
- Ta cần giải quyết 100 challenge về chuyển đổi loại dữ liệu.
- Sử dụng `json` để giải quyết vấn đề.
- File mẫu sử dụng `json`.
- Code solve challenge:
```Python
from Crypto.Util.number import *
import json
import telnetlib
import base64
import codecs
host = "socket.cryptohack.org"
p = 13377
telnet = telnetlib.Telnet(host, p)
def readline():
return telnet.read_until(b"\n")
def json_recv():
return json.loads(readline().decode())
def json_send(hsh):
telnet.write(json.dumps(hsh).encode())
for i in range(100):
data = json_recv()
encoding, encoded = data['type'], data['encoded']
# print(f"{i + 1} {encoding}:")
if encoding == "base64":
decoded = base64.b64decode(encoded).decode()
elif encoding == "hex":
decoded = bytes.fromhex(encoded).decode()
elif encoding == "rot13":
decoded = codecs.decode(encoded, "rot_13")
elif encoding == "bigint":
decoded = long_to_bytes(int(encoded, 16)).decode()
elif encoding == "utf-8":
decoded = "".join(chr(o) for o in encoded)
json_send({"decoded": decoded})
print(f"{data}==> decode: {decoded}")
flag = json_recv()
print(flag)
```

### Xor
#### XOR Starter

- XOR của hai giá trị cùng là 0 hoặc cùng là 1:
- 0⊕0=0
- 1⊕1=0
- 0⊕1=1
- 1⊕0=1
- XOR với 0 luôn là số chính nó:
- a⊕0=a
- XOR một số với chính nó luôn là 0:
- a⊕a=0
- XOR có tính chất hoán vị (commutative):
- a⊕b=b⊕a
- XOR có tính chất kết hợp (associative):
- (a⊕b)⊕c=a⊕(b⊕c)
```Python
from pwn import *
flag= xor(13, 'label')
print(flag)
```

#### XOR Properties

- Challenge yêu cầu ta giải hệ:

- Ta sẽ sử dụng 2 tính chất sau để giải quyết challenge:
- a⊕b=c <=> a= b⊕c
- (a⊕b)⊕c=a⊕(b⊕c)
```Python
from pwn import *
import binascii
key1= binascii.unhexlify('a6c8b6733c9b22de7bc0253266a3867df55acde8635e19c73313')
key2= xor(binascii.unhexlify('37dcb292030faa90d07eec17e3b1c6d8daf94c35d4c9191a5e1e'), key1)
key3= xor(binascii.unhexlify('c1545756687e7573db23aa1c3452a098b71a7fbf0fddddde5fc1'), key2)
flag= xor(binascii.unhexlify('04ee9855208a2cd59091d04767ae47963170d1660df7f56f5faf'), key1, key2, key3)
print(flag)
```

#### Favourite byte

- Challenge cho ta một chuỗi ký tự và bảo ta dùng phép xor để tìm flag. Tuy nhiên ta chẳng biết xor với chuỗi nào để thu được flag nên ta sẽ thử brute force.
```Python
from pwn import xor
import binascii
c= binascii.unhexlify('73626960647f6b206821204f21254f7d694f7624662065622127234f726927756d')
for i in range (0, 256):
flag= xor(i, c)
print(flag)
```

- Hoặc ta cũng có thể thử cách sau. Ta biết format của flag là `crypto{}` và ta biết a⊕b= c <=> a= b⊕c nên ta sẽ xor chuỗi đó với format.
- Ta thu được kết quả sau:

- Sau đó ta lấy 7 bytes đầu xor ngược lại với chuỗi ký tự để thu được flag.
```Python
from pwn import xor
import binascii
c= binascii.unhexlify('73626960647f6b206821204f21254f7d694f7624662065622127234f726927756d')
a= 'crypto{'
x= xor(c, a)
a= x[:7]
flag= xor(c, a)
print(flag)
```

#### You either know, XOR you don't

- Bài này tương tự bài `Favourite byte` nên ta sẽ làm tương tự thử.
```Python
from pwn import xor
import binascii
c= binascii.unhexlify('0e0b213f26041e480b26217f27342e175d0e070a3c5b103e2526217f27342e175d0e077e263451150104')
a= 'crypto{'
x= xor(c, a)
print(x)
a= x[:7]
flag= xor(c, a)
print(flag)
```
- Tuy nhiên ta lại không thu được flag đúng.

- Challenge kêu ta đoán thử xem key là gì đồng thời ta dựa trên kết quả được in ra ta đoán được key chính là `myXORkey`. Xor chuỗi với key ta thu được flag.
```Python
from pwn import xor
import binascii
c= bytes.fromhex('0e0b213f26041e480b26217f27342e175d0e070a3c5b103e2526217f27342e175d0e077e263451150104')
print(xor('crypto{',c))
print(xor('myXORkey'.encode(), c))
```

#### Lemur XOR

- Bài này ta xor 2 ảnh.
```Python
from binascii import unhexlify
with open("lemur.png", mode='rb') as fl:
lemur = fl.read()
with open("flag.png", mode='rb') as ff:
flag = ff.read()
d = b''
for b1, b2 in zip(lemur, flag):
d += bytes([b1^b2])
with open("new.png", mode='wb') as fn:
fn.write(d)
```

### MATHEMATICS
#### Greatest Common Divisor

- Challenge yêu cầu ta tính gcd(a,b).
```Python
def gcd(a, b):
while b:
a, b = b, a % b
return a
a = 66528
b = 52920
print(gcd(a, b))
```
#### Extended GCD

- Challenge này ta sẽ dựa vào thuật toán Euclid mở rộng. Mình cũng có trình bày về thuật toán này ở [đây](https://github.com/Caycon/Algorithm).
```Python
def extended_gcd(a, b):
if b == 0:
return a, 1, 0
else:
d, x, y = extended_gcd(b, a % b)
return d, y, x - y * (a // b)
p = 26513
q = 32321
gcd_value, u, v = extended_gcd(p, q)
if u > v:
u, v = v, u
print(v, u)
```
- `flag: -8404`
#### Modular Arithmetic 1

- Challenge này yêu cầu ta tìm mod, tham khảo thêm về modulo tại [đây](https://github.com/Caycon/Algorithm).
```Python
print(8146798528947%17)
print(11%6)
```
`flag: 4`.
#### Modular Arithmetic 2

- Áp dụng kiến thức về modulo tại [đây](https://github.com/Caycon/Algorithm) để giải quyết challenge.
- Ta có `a^(p−1) ≡1(mod p)` với p là số nguyên tố. Nên kết quả cần tìm sẽ là 1.
- `flag: 1`.
#### Modular Inverting

- Bài toán này ta sẽ kiến thức của áp dụng thuật toán Euclid mở rộng để tìm d hay nói cách khác là tìm nghịch đảo modul của 3 mod 13.
```Python
from Crypto.Util.number import *
print(inverse(3, 13))
```
- Hoặc:
```Python
print(pow(3, -1, 13))
# flag: 9
```
### DATA FORMATS
#### Privacy-Enhanced Mail?:

- Challenge cho ta file `pem` ta mở file và decode pem đó bằng tool trên `dcode.fr` va thu được d chính là flag.
- File `pem` là file lưu trữ các khóa mật mã.
- Thông tin trong file pem được mã hóa bằng `base64` nên ta hoàn toàn có thể tìm được plantext chỉ bằng cách decode base64.

- Hoặc ta cũng có thể dùng code để lấy dữ liệu trong file pem nếu không mở được file pem.
```Python
from Crypto.PublicKey import *
f = open('privacy_enhanced_mail_1f696c053d76a78c2c531bb013a92d4a.pem','rb').read()
flag = RSA.importKey(f)
print(flag.d)
```

#### CERTainly not

- Challenge cho ta một file `der` ta sẽ mở file và lấy dữ liệu trong file bằng code sau:
```Python
from Crypto.PublicKey import *
f = open('2048b-rsa-example-cert_3220bd92e30015fe4fbeb84a755e7ca5.der','rb').read()
flag = RSA.importKey(f)
print(flag.n)
```

#### SSH Keys

- Challenge cho ta file `pub` ta sẽ mở và lấy thông tin tương tự những bài trên.
```Python
from Crypto.PublicKey import *
f = open('bruce_rsa_6e7ecd53b443a97013397b1a1ea30e14.pub','rb').read()
flag = RSA.importKey(f)
print(flag.n)
```

#### Transparency
- 
- Challenge cung cấp một vài thông tin về `TLS` và miền phụ đồng thời yêu cầu ta tìm miền phụ của `cryptohack.org`.
- Ta sẽ sử dụng web `https://crt.sh/` để tìm miền phụ của `cryptohack.org`
- Lưu ý tên challenge là `Transparency` để tìm được miền phụ.

- Đây chính là miền phụ mà ta cần truy cập. Truy cập vào miền phụ này ta sẽ có được flag.
