You are on page 1of 56

Chào các Hackers!

Chúng tôi là Sapheads,


những con người may mắn được tham dự
trận chung kết của Defcon CTF :)

Đây là write-up cho bài b300, được chúng tôi xây


dựng dưới dạng hoạt hình.

Các nhân vật được chúng tôi xây dựng như dưới đây

MONG: Trưởng nhóm.Phân tích mẫu


và gợi ý hướng để giải quyết
MITBOL: Cung cấp binary
các dấu hiệu
rất quan trọng

GUTA: Đưa ra các ý


tưởng sáng tạo

Tiffany:Chuyên gia về
Forensic, Cryptography,
Coding

*Dựa trên bài writeup b300 của KOrUPt@Sapheads,


với kỹ thuật Anti-debugging.
http://korupt.co.uk/?p=132

*Lời cảm ơn đặc biệt tới hội thảo Defcon và DDTek, người
khiến chúng tôi đứng chung một đội và nhắm tới cùng một mục
tiêu.

Source:http://hackerschool.org/DefconCTF/17/B300.html
Giờ là lúc để giải bài
Binary 300. Tôi đoán challenge này có số điểm là 300,
vậy khả năng là nó sẽ khó hơn các bài khác.

Hehe,
đừng lo MONG. Ồ, khả năng lần này tôi
Có tôi đây :) sẽ cổ vũ cho anh.
Phải không Tiffany? Bài về Binary thực sự
không phải sở trường
của tôi.

Source:http://hackerschool.org/DefconCTF/17/B300.html
Tôi đoán nó là
Windows PE binary. Định dạng PE?

PE là viết tắt của


Portable Executable.
Nó thường được sử dụng
trong môi trường
HĐH Windows.

Tôi hiểu rồi


À, vậy đây là một file
thực thi chạy trên
HĐH Windows

Gợi ý là
gì thế?
Tìm 16 bytes của key?
Khả năng là một bài liên
quan đến crypto?

Source:http://hackerschool.org/DefconCTF/17/B300.html
Do bài này nằm ở phần binary,
Tôi đã upload file tại đường link
vậy nên không thể liên http://sapheads.org/b300.exe
quan đến Crypto. Hãy thử phân tích nó theo cách cậu biết.

Trước tiên, tôi sẽ kiểm tra


Có thể gửi tôi công cụ đó được không?
xem thông tin về tập tin
này bằng cách sử dụng PEID Tôi cũng muốn thử

Nó là một công cụ miễn Tôi đoán cậu sẽ không muốn


phí,dùng google để tìm gửi nó cho tôi.
kiếm và cậu sẽ thấy nó
nằm ngay đầu tiên.

Không, giờ tôi cũng đang


download nó đây. Huh

Source:http://hackerschool.org/DefconCTF/17/B300.html
Đã xong

Cái quái gì thế ....


Chẳng có thông tin gì.

Theo lý thuyết, nó phải hiển thị các


Này Mong,
thông tin liên quan tới compiler và
Tớ đã quét file đó bằng
compression chứ nhỉ.
PEID,nhưng chả có
thông tin gì hữu ích.

Source:http://hackerschool.org/DefconCTF/17/B300.html
Thấy không?
Giống như
thế này.

Tôi thử mở một


binary khác.

Huh? Nếu cậu nhấn vào biểu


Cậu đã thử kiểm
Entropy? tượng[>>], cậu sẽ thấy
tra entropy
thông tin bổ sung,
chưa?
kiểm tra xem nếu cậu
nhìn thấy Entropy ở đó.

Vậy thì tức là file này


Wow! đã bị packed. :)
Nó cho biết file này
đã bị packed.

Source:http://hackerschool.org/DefconCTF/17/B300.html
À tôi đã hiểu, Entropy cho cậu biết
nhưng Entropy là gì? cách thức tổ chức của
file như thế nào.

Lấy ví dụ,
nếu một cái bàn được sắp xếp một Ngược lại, nếu cài bàn đó được sắp
cách ngăn nắp, giá trị entropy xếp một cách bừa bãi, giá trị
của nó sẽ thấp. entropy của nó sẽ cao.

Wow...
Quá hay...

Nếu một binary bị packed,


điều đó có nghĩa là các
đoạn code sẽ bị bố trí
Họ đã áp dụng khái niệm
lộn xộn. Do vậy, giá trị
này cho các file.
entroy sẽ tăng lên.

Source:http://hackerschool.org/DefconCTF/17/B300.html
À, vậy có nghĩa là
file này đã bị nén và packed.

Chính xác,
giờ cậu thử dùng Olly Debugger
để debug xem.

Khả năng cậu sẽ không thể.


File này đá áp dụng các cơ chế
Anti-Debugging.

Tức là nó chống lại việc các chương trình


khác debug nó?
Làm sao ông biết được điều này?

Hãy thử thực thi file b300.exe

Source:http://hackerschool.org/DefconCTF/17/B300.html
Cô sẽ thấy có file helloworld.txt
được tạo ra.

Nhưng nếu ta thực thi file này thông qua Olly


Debugger, file helloworld.txt sẽ không được
tạo ra.

Tại Olly, ta sẽ nhận được thông báo lỗi.

Source:http://hackerschool.org/DefconCTF/17/B300.html
Thông thường,
nếu như có bất kỳ sự khác biệt nào giữa
việc thực thi file một cách bình thường Vậy để tôi thử tìm xem có
và thực thi filethông qua một chương những cơ chế Anti-Debugging
trình debugger,thì khả năng lớn file nào đã được áp dụng.
đó có áp dụng Anti-Debugging.

Cuối cùng ...


Uhm....

Có quá nhiều thủ thuật


được che dấu trong file
này.

Source:http://hackerschool.org/DefconCTF/17/B300.html
Đầu tiên, đây là entry point của file này.

Tại đây có hai điểm mà chúng ta


cần phải chú ý.

Một là tại chỗ nó gọi tới một


sub function "ESI".

Source:http://hackerschool.org/DefconCTF/17/B300.html
Và một chỗ khác gọi tới hàm ExitThread()

ExitThread là một API của nhưng đó lại là


kernel32.dll, do vậy có thể cái bẫy đầu
nghĩ đây là một function tiên.
hợp lệ,

Thực tế là,
sub function đầu tiên tôi đã nói về việc chỉnh ...

Source:http://hackerschool.org/DefconCTF/17/B300.html
Chính xác, nó sửa địa chỉ của một hàm mà
ExitThread gọi.

Bây giờ, hãy cố gắng quan sát bên


trong sub function đầu tiên mà
chỉnh sửa ExitThread().

Từ chỗ đang chọn


cho tới lệnh RETN
cuối cùng là thuộc
về sub function.

Source:http://hackerschool.org/DefconCTF/17/B300.html
Thoạt nhìn, trông nó khá phức tạp,
nhưng bạn sẽ sớm nhận ra rằng chúng "Gibberish codes" có nghĩa là
đơn giản chỉ là những đoạn mã không đoạn codes đó chẳng thực hiện
có ý nghĩa "gibberish" nhằm mục đích bất kỳ công việc gì.
làm bạn bị phân tâm. Giống như đoạn mã này...

Nếu ta loại bỏ các đoạn mã này, ta sẽ có được các câu lệnh


chính thực sự quan trọng như dưới đây.

Tôi sẽ đi từ từ từng câu lệnh một.

Source:http://hackerschool.org/DefconCTF/17/B300.html
Reversing thực sự không phải chuyên môn của tôi.
Nhưng tôi chờ tới Crypto hay Forensic,
tôi sẽ cân hết !!

Source:http://hackerschool.org/DefconCTF/17/B300.html
TEB là viết tắt của Thread Environment Block,
và nó là một cấu trúc bao gồm các thông tin về
thread hiện tại.

Còn PEB là viết tắt của Process Enviroment Block,


nó cũng là một cấu trúc bao gồm các thông tin về
process hiện tại.

Nó là một hàm để đồng bộ hóa của


PEB area.
Nó bảo vệ các hàm khác truy cập
tới PEB area bằng cách gọi
Và nó trước
FastPeb
LockRoutine là....
uhm..

Ban đầu FastPebLockRoutine trỏ tới hàm


RtlEnterCriticalSection(). Nhưng nó thay
đổi con trỏ tới một số hàm khác.
Kỹ thuật này thường hay
được sử dụng trong Heap Overflow.

Source:http://hackerschool.org/DefconCTF/17/B300.html
Sau khi trở về từ sub function sẽ thực hiện tiếp
lời gọi hàm ExitThread().

0x0046367F

Sau đó,
hàm ExitThread() sẽ thực hiện theo trình tự sau và gọi tới 0x0046367F

Source:http://hackerschool.org/DefconCTF/17/B300.html
Bây giờ ta đang ở tại địa chỉ 0x0046367F,
theo quan sát thì thấy đây không phải
là một vùng code hợp lệ, nên chúng ta
không thể debug nó được.

Khi code đoạn code thế này, lựa chọn


vùng code

Source:http://hackerschool.org/DefconCTF/17/B300.html
và nhấn Ctrl+E để áp dụng chỉnh sửa code, sau đó vùng code
trông sẽ ổn hơn.

Giống như vậy ...

Source:http://hackerschool.org/DefconCTF/17/B300.html
Tại vùng code đang đứng, binary này sử dụng một thủ thuật khác để
chống lại việc debug,thủ thuật này thực hiện việc chèn thêm các giá
trị rác vào giữa các câu lệnh.

Với thủ thuật này sẽ khiến cho


trình debugger sẽ không biết làm
cách nào để disassemble những
đoạn code đó. Nhưng CPU sẽ không thể thực
hiện các mã rác này.

Vì vậy nó làm cho nó nhảy


qua các giá trị rác.

Source:http://hackerschool.org/DefconCTF/17/B300.html
Ví dụ, tôi sẽ thử sửa
một lệnh.

Để giải quyết vấn đề này, thử Ctrl+E


để sửa code và thay đổi code đại
loại như thành lệnh nop (0x90).

Tại 0x00463688, đó là một câu lệnh nhảy tới địa chỉ


0x0046368B.

Source:http://hackerschool.org/DefconCTF/17/B300.html
Như cậu thấy, tại 0x0046368A, tại đó có một giá trị lạ là
0x1D nhằm đánh lạc hướng của ta.

Giờ, nếu ta thử đổi 0x1D thành 0x90...

Source:http://hackerschool.org/DefconCTF/17/B300.html
Đoạn code khác tại địa chỉ 0x0046368B sẽ được
khôi phục.

Wow,
Thật tuyệt quá...
Nếu cậu tiếp tục thay thế toàn
bộ các giá trị rác tương tự
như vậy

Source:http://hackerschool.org/DefconCTF/17/B300.html
Cậu sẽ thấy có lệnh Call tới hàm
VirtualProtect()

Hàm VirtualProtect() được định nghĩa như sau

Source:http://hackerschool.org/DefconCTF/17/B300.html
Nếu cậu quan sát tại cửa sổ Stack,
cậu có thể kiểm tra được các tham số được
truyền vào cho hàm này.

Vậy nó sẽ thay đổi thuộc


tính của địa chỉ vùng nhớ
Trong trường hợp này, nó được gọi thành RWE.
giống như sau.

Source:http://hackerschool.org/DefconCTF/17/B300.html
Và nếu quan sát tại địa chỉ bộ nhớ và kích thước
vùng nhớ,cậu sẽ biết rằng các mã hiện tại đã
được bao gồm trong vùng này.

Sau đó, mã thật sẽ


hiện ra.
Đó là để chuẩn bị cho
việc Self-Modifying,
thay đổi mã.

Vùng được lựa chọn chính là nơi


sau khi Self-modification đã thực
hiện xong.

Source:http://hackerschool.org/DefconCTF/17/B300.html
Và vùng màu đỏ chính là vùng mã đã
thay đổi.

Giờ, nếu cậu thực thi Cậu sẽ thấy một đoạn mã nơi mà nó
từng lệnh một của thêm SEH
đoạn mã đã thay đổi,

Điểm đầu của SEH chain là tại FS:[0],


và nó được thay đổi tới địa chỉ của SEH mới.

Source:http://hackerschool.org/DefconCTF/17/B300.html
Sau đó ta sẽ tới lệnh int 0x2D.

Arrg....
Tôi cảm thấy bị loạn
rồi.
Hmm,
anti-debugging bằng
cách sử dụng int 0x2D.

Ngắt 0x2d có thể gây ra exception là


Tôi từ bỏ BREAKPOINT (0x80000003),
cuộc chơi nhưng nếu trình debugger đang hoạt động,
:P SEH sẽ không được thực thi.

Source:http://hackerschool.org/DefconCTF/17/B300.html
Nhưng cậu cần phải nhớ rằng exception
ILLEGAL INSTRUCTION đã xảy ra, thay vì
exception BREAK POINT.

Do vậy, hiện ta đang ở tại SEH mà binary đã tạo ra.

Sau khi thay thế các giá trị rác bằng NOPs,
các lệnh sẽ trông như sau.

Source:http://hackerschool.org/DefconCTF/17/B300.html
Yeah, tôi nghĩ rằng có
thể đây là kỹ thuật
Hmm... Giờ, lại thêm cơ chế cuối cùng rồi.
Anti-debugging
bằng int 3.

Int3, là software breakpoint, sẽ gây ra BREAK POINT exception,


nhưng nếu trình debugger đang chạy, thì SEH của chương trình
sẽ không được thực thi.

À ha,
Vậy thì điều đó có nghĩa là SEH đã thực hiện
gần đây sẽ được thực hiện lại đúng không?

Source:http://hackerschool.org/DefconCTF/17/B300.html
Không, đoạn code này thực ra có một đoạn code khác
dùng để tạo một SEH khác.

Tại đây, bạn có thể nhìn thấy một


giá trị là 0xFFBE3465, nó trông
có vẻ như là không có ý nghĩa gì lắm,

Source:http://hackerschool.org/DefconCTF/17/B300.html
nhưng nếu cậu trace qua lệnh XOR,
nó sẽ chuyển đổi thành một địa chỉ
của một vùng code.

Thanh ghi EDX, trước khi được đem đi XOR sẽ có giá trị là 0xFFFC03FF,
giá trị này có được từ câu lênh phía trên.

Source:http://hackerschool.org/DefconCTF/17/B300.html
Nếu cậu XOR FFBE3465 với FFFC03FF, cậu sẽ nhận được
kết quả là 0042379A, đây là một địa chỉ.

Nhưng nếu cậu quan Đó là bởi vì giá trị


sát tại địa chỉ của thanh ghi EDX Nhưng trong trường hợp này,
này, được hình thành từ nó lại là ILLEGAL
các đoạn code ở đó giá trị exception INSTRUCTION,
thực sự không phải đã được truyền thông mà không phải là
là các đoạn code qua stack BREAK POINT
hợp lệ.

Source:http://hackerschool.org/DefconCTF/17/B300.html
Mà ngược lại ILLEGAL INSTRUCTION
Đó là bởi vì khi cậu đang debug,
exception lại văng ra bởi vì có
BREAK POINT exception tại
câu lệnh không hợp lệ liền sau đó.
int 0x2d sẽ không xảy ra.

Do vậy, chúng ta cần phải thực hiện lại


nó một lần nữa cho tới khi giá trị của
thanh ghi EDX được khởi tạo, và ta thay
đổi giá trị trên stack từ
0xC0000001D thành 0x80000003

Source:http://hackerschool.org/DefconCTF/17/B300.html
Vậy là, sau đó nó sẽ tính toán ra giá trị
đúng là 0x0046379A.

Sau đó địa chỉ này được lưu tại ESP+0x18, đó là nơi mà ban
đầu có một SEH khác.

Điều này có nghĩa là, chúng ta đã thay thế


SEH hiện tại bằng một SEH mới.

Source:http://hackerschool.org/DefconCTF/17/B300.html
Bây giờ chúng ta cần
thay đổi tùy chọn
trong Olly cho
int3 exception.

Tích chọn giống như hình.

Như vậy là ta đã hoàn


Sau đó, nếu cậu thực
toàn vượt qua được các
thi, SEH thứ hai
kĩ thuật Anti-debugging.
được tạo mới sẽ
được thực hiện

Từ lúc này, code đã không còn bị packed nữa,


cậu có thể thấy là tập tin helloworld.txt
đã được tạo ra chuẩn xác.

Source:http://hackerschool.org/DefconCTF/17/B300.html
Tổng kết lại toàn bộ
như sau.

Binary này áp dụng khá nhiều


kỹ thuật anti-debugging.

Đầu tiên, nó đã chèn thêm các giá trị rác để gây nhiễu trong khi
disassembling.

Thứ hai, nó đã thay đổi FastPebLock routine function, do vậy bên trong
lời gọi của ExitThread(),nó lại gọi tới một đoạn code khác.

Source:http://hackerschool.org/DefconCTF/17/B300.html
Sau đó nó áp dụng kĩ thuật tự thay đổi code
(self-modifying)để chèn thêm các lệnh.

Tiếp theo, bằng kỹ thuật int 0x2D nó đã


thực thi SEH đầu tiên.

Source:http://hackerschool.org/DefconCTF/17/B300.html
Cuối cùng, bằng kỹ thuật int 3,
nó đã thực thi SEH thứ hai.

Như vậy, nó đã sử dụng giá trị exception để tạo


ra một giá trị nhất định.

Phew, phần của tôi Tôi xin dành phần còn


vậy là đã xong! lại cho MITBOL và các
cậu.

Source:http://hackerschool.org/DefconCTF/17/B300.html
Source:http://hackerschool.org/DefconCTF/17/B300.html
Không, có quá Chúng ta sẽ lãng phí
Cần phải tìm ra một
nhiều codes. thời gian, nếu chúng
cách nào đó hiệu
ta cứ tiếp tục
quả hơn.
như vậy.

Hừ ..tìm một cách khác... Hừ ..tìm một cách khác...

Source:http://hackerschool.org/DefconCTF/17/B300.html
Nếu nó giải mã băng một key...

Điều đó có nghĩa là nó sẽ giải mã một dữ


liệu nào đó mà nó đã mã hóa....

Và nếu đó là một quá trình mã hóa và giải mã,


thì nhất định phải luôn có một vòng lặp
thực hiện ...

và nếu khóa giải mã là 16 bytes...

Source:http://hackerschool.org/DefconCTF/17/B300.html
Vòng lặp nên sẽ lại với 16 bytes của khóa để
mã hóa hoặc giải mã

Đúng rồi,
chính là nó!!

Source:http://hackerschool.org/DefconCTF/17/B300.html
Chúng ta cần phải tìm các lệnh
thực hiện lặp lại nhiều lần.

Trước tiên, chúng ta cần


vượt qua hết các cơ chế
Anti-debugging đã.

Source:http://hackerschool.org/DefconCTF/17/B300.html
Sau đó, xóa toàn bộ các
breakpoints đã đặt.

Để tiến hành thực Trace nghĩa Nó sẽ thực hiện việc ghi lại
hiện Trace là sao? từng lệnh một đã được thực
hiện.

Source:http://hackerschool.org/DefconCTF/17/B300.html
Mở cửa sổ Run Trace trong View menu.

Sau đó vào Debug và


thực hiện Trace Into.

Source:http://hackerschool.org/DefconCTF/17/B300.html
Giờ thì ta ngồi chờ cho
tới khi nó thực hiện
xong.
Có lẽ sẽ phải mất
một lúc.

Ồ!!!

Đã xong.
Nó hiện thông báo
"Terminated"

Source:http://hackerschool.org/DefconCTF/17/B300.html
Các câu lệnh thực hiện có thể được tìm
thấy tại đây.

Tại màn hình Run Trace, nhấn chuột phải và chọn Global
profile.

Source:http://hackerschool.org/DefconCTF/17/B300.html
Sau đó, nó sẽ được sắp xếp theo thứ
tự các lệnh có số lần lặp nhiều nhất.

Tại đây, xuất hiện


những địa chỉ của
DLL mà bắt đầu bằng
0x7c,
chúng ta không cần quan
tâm tới các lệnh này,
do vậy hãy bỏ qua chúng.

Source:http://hackerschool.org/DefconCTF/17/B300.html
Nếu không phải là câu lệnh này ...

Thì sẽ phải là những câu lệnh này.


Nếu mọi người nhìn vào các địa chỉ này,
ta thấy đây là thuộc cùng một đoạn code.

Source:http://hackerschool.org/DefconCTF/17/B300.html
Ồ, như vậy không phải ở đây.
Thử xem
Đây không có gì là giải mã cả,
tại
nó đơn giản chỉ là việc sao
địa chỉ
chép dữ liệu thôi.
đầu
tiên xem
thế
nào.

Tiếp tục
tìm
với các
địa
chỉ thứ
hai.
Nó lặp lại
từ đây tới đây.

Source:http://hackerschool.org/DefconCTF/17/B300.html
Hmmm, Huh?
nó só sánh 16

Tại đây, vì nó là 10
ở hệ hex, có nghĩa
là 16 ở hệ mười.

Ồ, vậy nó so sánh
với kích thước Vậy có nghĩa là,
của khóa giải mã!! chúng ta đã
đi đúng
hướng có
phải không?

Source:http://hackerschool.org/DefconCTF/17/B300.html
Vì lệnh XOR được sử dụng nhiều lần,
Tôi đang đoán phần chúng ta
tôi nghĩ là nó sử dụng mật mã XOR.
đang cố gắng thực hiện unpack ngay
bây giờ, có sẽ là mã tạo ra file
helloworld.txt

Xong rồi,

Nếu bạn chuyển đổi vòng lặp này sang


mã lệnh C,
trông nó sẽ giống như thế này.

Source:http://hackerschool.org/DefconCTF/17/B300.html
Vậy câu trả lời có thể nằm ở
Ồ vãi thật... thanh ghi EBP,
nó chính là địa chỉ bắt đầu
của khóa giải mã đúng
không nhỉ?

Source:http://hackerschool.org/DefconCTF/17/B300.html
Hoàn toàn có thể.
Thử Follow in Dump xem !

Đó chính là 16 bytes của khóa giải mã!!!!!!!!!!!!

Source:http://hackerschool.org/DefconCTF/17/B300.html
Đúng rồi!!
Để tôi thử nó
xem sao.

Quá đỉnh!!!

Đệch...

Chuẩn cmnr anh em ơi!!

Lolz, giờ chúng ta đã trở lại


top 10 đội rồi.
Giờ chiến tiếp các challenges khác thôi!!

Source:http://hackerschool.org/DefconCTF/17/B300.html

You might also like