# [Write-Up RE] RE01 - FPTSec

Bài có một số kiến thức mới, mọi người xem và tham khảo 😴😴😪
## Ý tưởng
Bài dựa trên sự kết hợp của anti-debug và anti-diassembly kết hợp một số kỹ thuật thao tác cơ bản với z3.
Tài liệu về anti-diassembly: http://staff.ustc.edu.cn/~bjhua/courses/security/2014/readings/anti-disas.pdf
## Thực hành
### anti-Diassembly
Khi tải bài về ta có một file PE32 **RE01.exe** khi chjay thử chương trình sẽ cho phép ta nhập flag và check:

Load file vào IDA và follow theo strings của chương trình ta thấy chương trình kiểm tra input nhập vào sau đó sẽ load qua một hàm tại **loc_401150** để kiểm tra điều kiện xem in ra thông báo sai hoặc đúng. Vì một số lý do nào đó mà IDA không thể nhận ra tại address đó là một hàm mặc dù vẫn phát hiện ra tại đó có tham số.

Ta tiến hành nhảy đến vị trí 0x401150 để kiểm tra shellcode

Tại đây IDA chỉ nhận diện được một vài dòng code đầu tróng vài dòng đó ta nhận diện được hai dòng **jo short near ptr loc_401160+1** và **jo short near ptr loc_401160+1**
là những dòng code khá lạ, chúng đều nhảy về cùng một địa chỉ mặc dù là hai lệnh nhảy khác khau và vị trí nhảy đến là lệnh nhảy phía dưới chúng. Đây chính là dấu hiệu của anti-diassembly mà được gắn ở tài liệu đầu bài viết:

Ta kiểm tra shellcode tại vị trí nhảy thì thấy được đây chính là byte giả mạo ***0xe9***

Không chỉ thế bên dưới đoạn code nhận diện được xuất hiện khá nhiều các byte giả ***(0xe8 và 0xe9)*** bắt đầu từ địa chỉ đầu hàm là 0x401150 đến 0x4020A0, Fell ngồi sửa hết đống này chắc ốm 🙄😶😶
Mình viết một đoạn IDAPython để patch tất cả các byet này thành nop như sau:
```
import ida_bytes
start = 0x00401150 # Có thể khác trên máy bạn
finish = 0x004020A0 # Có thể khác trên máy bạn
for i in range(start, finish + 1):
b = ida_bytes.get_byte(i)
if b == 0xE8 or b == 0xe9:
ida_bytes.patch_byte(i, 0x90)
```
Đoạn Script trên sẽ patch giúp ta như cách Thanos búng tay, sau đó việc của ta chỉ là phân tích lại toàn bộ chương trình bằng cách chọn ***Options -> General -> Analysis -> Reanalyze program***
Lúc này shellcode đã đẹp rồi

Ta make functions trên địa chỉ đó bằng cách bôi đen toàn bộ code sau đó nhấn 'P' sau đó nhấn 'f5' để xem được giả mã, thành quả sẽ như thế này:

### anti-Debug
Sau khi phân tích xong hàm này ta nhận thấy rằng hàm có sử dụng kỹ thuật lấy giá trị trong PEB để phát hiện debug khi thấy được debug hàm sẽ thay đổi giá trị các kết quả của các hàm tính toán trong lệnh if như thế sẽ làm ta đoán sai toàn bộ kết quả:

Chỉ còn cách giải mã bằng tay mà không debug thôi, viến đoạn python sử dụng z3 để giải mã hệ phương trình 49 ẩn 😑😑😑:
```
from z3 import *
# 0xKai báo biến
this = [BitVec(f"this{i}", 8) for i in range(49)]
solver = Solver()
results = [0x00000072, 0x00000087, 0x00000565, 0x00000039, 0x000000EE, 0x000008D7, 0x00000082, 0x000000A5, 0x0000083F, 0x0000006F, 0x000000BF, 0x0000095E, 0x00000032, 0x000000B8, 0x00000AB0, 0x00000074, 0x0000007D, 0x0000050B, 0x00000042, 0x000000F9, 0x00000B9D, 0x0000007D, 0x000000E5, 0x00000B6C, 0x0000007B, 0x000000B6, 0x000005CF, 0x00000086, 0x000000C2, 0x0000058F, 0x000005BB, 0x000018CE, 0x0000A97E, 0x00006B00, 0x0000DA17, 0x000892B4, 0x0012F064, 0x00024859, 0x00024A29, 0x000003E7, 0x000A50C7, 0x00008BEF, 0x0000036D, 0x00000133, 0x000002CF, 0x000001A1, 0x00000038, 0x00000033, 0x00000066, 0x00000035, 0x00000032, 0x00000031, 0x00000034, 0x00000034]
# 0xĐịn 0xngĩa các 0xpương 0xtrìn
equations = [
this[1] + this[0] % 19 == results[0],
this[2] + this[0] + 19 == results[1],
this[3] + 19 * this[0] == results[2],
this[5] + this[4] % 20 == results[3],
this[4] + this[6] + 20 == results[4],
this[7] + 20 * this[4] == results[5],
this[9] + this[8] % 21 == results[6],
this[8] + this[10] + 21 == results[7],
this[11] + 21 * this[8] == results[8],
this[13] + this[12] % 22 == results[9],
this[12] + this[14] + 22 == results[10],
this[15] + 22 * this[12] == results[11],
this[17] + this[16] % 23 == results[12],
this[18] + this[16] + 23 == results[13],
this[19] + 23 * this[16] == results[14],
this[21] + this[20] % 24 == results[15],
this[20] + this[22] + 24 == results[16],
this[23] + 24 * this[20] == results[17],
this[25] + this[24] % 25 == results[18],
this[24] + this[26] + 25 == results[19],
this[27] + 25 * this[24] == results[20],
this[29] + this[28] % 26 == results[21],
this[28] + this[30] + 26 == results[22],
this[31] + 26 * this[28] == results[23],
this[33] + this[32] % 27 == results[24],
this[34] + this[32] + 27 == results[25],
this[35] + 27 * this[32] == results[26],
this[37] + this[36] % 28 == results[27],
this[36] + this[38] + 28 == results[28],
this[39] + 28 * this[36] == results[29],
this[40] + 28 * this[36] == results[30],
this[43] + this[47] + this[42] + this[46] + this[41] + this[45] + this[44] + this[48] + (this[33] ^ this[34]) * (this[38] + this[39] + this[36] + this[37] + this[40] + this[35]) == results[31],
this[43] + this[47] + this[42] + this[46] + this[41] + this[45] + this[44] + this[48] + (this[33] ^ this[35] ^ this[34]) * (this[38] + this[39] + this[36] + this[37] + this[40]) == results[32],
(this[33] + this[34] + this[35]) * (this[39] ^ this[38] ^ this[36] ^ this[40] ^ this[37]) - this[48] - this[44] - this[45] - this[41] - this[46] - this[42] - this[47] - this[43] == results[33],
this[43] + this[47] + this[42] + this[46] + this[41] + this[45] + this[44] + this[48] + (this[26] ^ this[25]) * (this[29] + this[32] + this[27] + this[30] + this[31] + this[28]) == results[34],
this[29] + this[28] + (this[27] ^ this[26] ^ this[25]) + this[32] * this[30] * this[31] - this[48] - this[44] - this[45] - this[41] - this[46] - this[42] - this[47] - this[43] == results[35],
this[26] + this[27] + this[25] + (this[32] ^ this[31] ^ (this[29] * this[30] * this[28])) - this[48] - this[44] - this[45] - this[41] - this[46] - this[42] - this[47] - this[43] == results[36],
this[17] * this[18] * this[19] + (this[23] ^ this[22] ^ this[20] ^ this[24] ^ this[21]) - this[48] - this[44] - this[45] - this[41] - this[46] - this[42] - this[47] - this[43] == results[37],
this[43] + this[47] + this[20] + this[42] + this[46] + this[41] + this[45] + this[44] + this[48] + this[17] * this[18] * this[19] - this[24] - this[21] - this[23] - this[22] == results[38],
this[22] + this[23] + this[43] + this[47] + this[20] + this[42] + this[46] + this[21] + this[24] + this[41] + this[45] + this[44] + this[48] + (this[17] ^ this[19] ^ this[18]) == results[39],
this[10] * this[11] * this[9] + (this[16] ^ this[13] ^ this[15] ^ this[14] ^ this[12]) - this[48] - this[44] - this[45] - this[41] - this[46] - this[42] - this[47] - this[43] == results[40],
(this[10] + this[9]) * (this[16] ^ this[13] ^ this[15] ^ this[14] ^ (this[11] + this[12])) - this[48] - this[44] - this[45] - this[41] - this[46] - this[42] - this[47] - this[43] == results[41],
this[13] + this[16] + this[43] + this[47] + this[10] + this[42] + this[46] + this[15] + this[41] + this[45] + this[9] + this[12] + this[44] + this[48] - this[14] - this[11] == results[42],
this[43] + this[47] + this[42] + this[46] + this[2] + this[41] + this[45] + this[44] + this[48] - (this[7] ^ this[6] ^ this[4] ^ this[8] ^ this[5] ^ this[3]) - this[1] == results[43],
this[1] + this[6] + this[7] + this[4] + this[5] + this[8] + this[3] + (this[47] ^ this[43] ^ this[46] ^ this[42] ^ this[45] ^ this[41] ^ this[48] ^ this[44]) - this[2] == results[44],
this[1] + this[43] + this[47] + this[42] + this[46] + this[41] + this[45] + this[44] + this[48] - (this[7] ^ this[6] ^ this[4] ^ this[8] ^ this[5] ^ this[3]) - this[2] == results[45],
this[41] == results[46],
this[42] == results[47],
this[43] == results[48],
this[44] == results[49],
this[45] == results[50],
this[46] == results[51],
this[47] == results[52],
this[48] == results[53]
]
# 0xTêm các 0xpương 0xtrìn vào bộ giải
for eq in equations:
solver.add(eq)
flag = ""
# Kiểm tra và in kết quả
if solver.check() == sat:
model = solver.model()
for var in this:
# print(f"{model[var]}")
flag += chr(model[var].as_long() & 0xFF)
else:
print("Không tìm thấy giải pháp.")
print("FUSec{" + flag + "}")
```
## Flag: FUSec{Ch1ll1ng_w1th_Ant1-D1s4ss3mbly_t3chn1qu3_83f52144}
🤑🤑🤑
--Ckagngoc--