# [Write-Up RootMe] Cracking - Part 1
## :blue_book: Challenge List
- [1. ELF x64 - Crackme automating](#ELF-x64---Crackme-automating)
- [2. PE x86 - SEHVEH](#PE-x86---SEHVEH)
## :book: ELF x64 - Crackme automating
### :pencil: Đề bài

### :massage: Tổng quan
Nhận được một file bin thực thi trên linux với thông tin như sau

Kiểm tra sơ bộ

Kiểm tra qua <span style="color:green">strings.exe</span>


Bài thuộc dạng check password
### :knife: Phân tích
1. Mở file bằng <span style="color:blue">ida pro</span>
2. Phân tích hàm <span style="color:red">main</span>

- Chương trình nhận input là đường dẫn 1 file
- Hàm <span style="color:red">check</span> là hàm cấn quan tâm để phân tích quy trình xác thực mật khẩu của chương trình
3. Phân tích hàm <span style="color:red">check</span>

- Hàm có hơn 1000 node bắt đầu bằng đặt 2 giá trị tmp và kết thúc bằng gọi hàm <span style="color:red">badboy</span> nếu kết quả xác thực không đúng, <span style="color:red">ida pro</span> không thể tạo graph trên 1000 node nên ta buộc phải giải mã bằng tay
- Phân tích node đầu

- Phân tích node thứ 2

> Các node còn lại cũng sử dụng quy luật tương tự, cơ bản tại mỗi node sẽ tìm được một byte của file bằng cách xor **tmp2** và một giá trị **constant**
- Công việc cần làm là viết một đoạn **IDA Python** để xử lý tất cả các node từ địa chỉ **0x0AD1** đến địa chỉ **0x03EC2B0**
```python!
import idautils
import ida_bytes
import idc
start_address = 0xad8
end_address = 0x03EC2B0
flag = []
def find_instruction(start_address, end_address):
current_address = start_address
tmp2 = 0
const = 0
while current_address < end_address:
mnem = idc.print_insn_mnem(current_address)
if mnem == 'mov':
operand_type = idc.get_operand_type(current_address, 0)
if operand_type == idc.o_displ:
operand_value = idc.get_operand_value(current_address, 1)
print(f"tmp2: {hex(operand_value)}")
tmp2 = operand_value
elif mnem == 'xor':
operand_type = idc.get_operand_type(current_address, 0)
if operand_type == idc.o_reg:
operand_value = idc.get_operand_value(current_address, 1)
print(f"const: {hex(operand_value)}")
const = operand_value
if tmp2 != 0 and const != 0:
flag.append(tmp2 ^ const)
current_address = idc.next_head(current_address)
find_instruction(start_address, end_address)
with open("out.txt","wb") as f:
f.write(bytes(flag))
f.close()
```
- Giải mã và nhận được file sau

Đây là một file thực thi của MSDOS ta tiến hành chạy thử bằng DOSBOX

## :book: PE x86 - SEHVEH
### :pencil: Đề bài

### :massage: Tổng quan
Bài yêu cầu tìm password nhập vào
Gọi một số hàm đáng nghi liên quan đến xử lý ngoại lệ

Thông tin rõ ràng hơn từ 2 resource của challenge

### :knife: Phân tích
Hàm start nơ bản như sau

#### Phân tích hàm **check_paswd**
- Hàm lấy địa chỉ của chuỗi nhập vào, kiểm tra độ dài của chuỗi xem có bằng 12 không, nếu không thì sẽ nhảy đến **loc_E414AD** và thoát hàm

- Load 4 bytes đầu của password vào thanh ghi eax sau đó xor với **0x5A643059** và so sánh với **0x3628552E** để tìm xác thực 4 byte đầu từ đó ta lấy được 4 byte đầu của password

- Hàm đăng ký **off_E430A0 - 0x1000** để làm địa chỉ xử lý ngoại lệ và load tiếp 4 bytes tiếp theo của password vào eax, đưa **0x495F4265** vào ebx và tạo ngoại lệ để nhảy đến đoạn code xử lý sau đó xor giá trị trong eax với ebx và so sánh 4 bytes sau khi xử lý với **0x0FF2CF8E5**

- Đoạn code xử lý ngoại lệ được đăng ký

- Vậy là nó sẽ cộng 4 bytes input được load vào eax với **0x48335621** khi đã biết được quy luật ta có thể tìm ljai được mật khẩu
- Tiếp theo nó đăng ký một **AddVectoredExceptionHandler** trong đó 2 vùng code được push vào stack như sau

- Đầu tiên nó trừ 4 bytes cuối với **0x21486553**

- Sau đó nó cộng kết quả với **0x48335621**

- Cuối cùng nó xor kết quả với **0x74406653** và so sánh với **0x3C4C7440**

- Giải ngược lại ta có thể tìm được 4 bytes cuối của password
:::spoiler
password: weLl_d@nE!!!
:::