Kỹ thuật đảo ngược x64 cho người mới bắt đầu - Windows

1734
15-06-2018
Kỹ thuật đảo ngược x64 cho người mới bắt đầu - Windows

Trong bài viết này, Bizfly Cloud sẽ hướng dẫn bạn cách thực hiện các bước đầu tiên trong quá trình đảo ngược một phần mềm x64 trên hệ điều hành Windows.

Mở đầu

Trong blog trước ở đây, Bizfly Cloud đã dịch ngược thiết kế một nhị phân đơn giản chứa mật khẩu plaintext trong Linux với sự trợ giúp của trình gỡ lỗi GNU (GDB). Tuy nhiên, trong blog này, chúng tôi sẽ sử dụng cùng một mã nguồn của tệp nhị phân nhưng biên dịch và gỡ lỗi nó trong Windows. Các công cụ kỹ thuật dịch ngược trong Windows rất khác so với Linux, nhưng ở cấp độ lắp ráp, nó sẽ có phần nào giống nhau. Sự khác biệt duy nhất bạn sẽ tìm thấy là các cuộc gọi cấp nhân và các tệp DLL sẽ là của Windows thay vì các thư viện của Linux.

Trong bài này, tôi sẽ sử dụng x64dbg vì tôi không thể tìm thấy phiên bản trình gỡ lỗi x64 Immunity hoặc trình gỡ lỗi Olly để dịch ngược nhị phân. Tuy nhiên, dưới đây là các lựa chọn thay thế cùng với các link download mà bạn có thể lựa chọn. Nếu bạn có thể tìm thấy các trình gỡ lỗi x64 khác cho window, hãy bổ sung vào phần comment bên dưới và tôi sẽ đề cập đến chúng tại đây .:

    1. Immunity Debugger

    2. Olly Debugger

    3. IDA Pro

    4. WinDBG

    5. X64dbg

Immunity Debugger là một công cụ tuyệt vời nếu bạn đang gỡ lỗi nhị phân x86. Tuy nhiên, vì chúng tôi chỉ tập trung vào x64, chúng tôi sẽ phải sử dụng x64dbg hỗ trợ cả tháo gỡ x86 và x64.

Một khi bạn đã tải về trình gỡ lỗi được yêu cầu, bạn có thể biên dịch mã nguồn được tải lên trên Git repo của tôi tại đây. Bạn có thể biên dịch nhị phân trong Windows bằng lệnh dưới đây:

$ g crack_me.cpp -o crack_mex64.exe -static -m64

Hãy chắc chắn rằng bạn sử dụng phiên bản 64 bit của trình biên dịch g nếu không nó sẽ vẫn biên dịch nhưng sẽ không hoạt động tiếp sau đó. Bạn cũng có thể tải xuống tệp nhị phân từ repo của tôi được đề cập ở trên. Tôi thích sử dụng trình biên dịch Mingw-x64, nhưng đôi lúc cũng sử dụng clang x64. Chung quy là tất cả đều phụ thuộc vào sở thích của riêng bạn.

Tháo gỡ

Khi bạn đã biên dịch tệp nhị phân, hãy tải nó lên trong x64dbg. Hãy nhớ rằng, nhị phân của chúng tôi chấp nhận một đối số là mật khẩu của chúng tôi. Vì vậy, không giống như GDB, nơi chúng tôi có thể cung cấp đối số bên trong GDB; trong Windows, chúng tôi sẽ phải cấp nó trong quá trình tải nhị phân thông qua dòng lệnh.

Để tải nhị phân vào x64dbg, dưới đây là dòng lệnh bạn có thể sử dụng:

. \x64dbg.exe crack_mex64.exe pass123

Một khi, các nhị phân được tải, bạn sẽ thấy sáu cửa sổ theo mặc định. Hãy để tôi giải thích nhanh những cửa sổ này là gì:

Kỹ thuật dịch ngược x64 cho người mới bắt đầu - Windows - Ảnh 1.

Cửa sổ trên cùng bên trái hiển thị mã đã tháo gỡ. Nó cũng giống như disassemble main trong GDB. Nó sẽ hướng dẫn bạn qua toàn bộ mã assembly của nhị phân. Cửa sổ trên cùng bên phải chứa các giá trị của thanh ghi. Vì chúng tôi đang gỡ lỗi nhị phân x64, các giá trị của thanh ghi x86 chẳng hạn như EAX hoặc ECX sẽ nằm bên trong RAX hoặc RCX.

Hai cửa sổ ở giữa, cửa sổ bên trái hiển thị cho bạn phần .text của assembly code, và bên phải hiển thị các fastcalls trong x64 assembly. Fastcalls là các quy ước gọi x64 được thực hiện chỉ giữa 4 thanh ghi. Tôi khuyên bạn nên bỏ qua điều này nếu bạn là người mới bắt đầu. Tuy nhiên đối với những "con mèo" tò mò, thông tin thêm có thể được tìm thấy ở đây.

Cửa sổ phía dưới bên trái hiển thị kết xuất bộ nhớ của tệp nhị phân và cửa sổ dưới bên phải hiển thị stack. Bất cứ khi nào các biến được chuyển sang hàm khác, bạn sẽ thấy chúng ở đây.

Ngay khi màn hình phía trên được tải, đầu tiên chúng tôi sẽ tìm kiếm các chuỗi trong tệp nhị phân của chúng tôi. Chúng tôi có biết một vài chuỗi khi chúng tôi thực thi nhị phân chẳng hạn "Incorrect Password" hoặc "Correct Password" hoặc "help". Hiện tại, mục tiêu chính của chúng tôi là tìm mật khẩu thực và mục đích thứ hai là sửa đổi thanh ghi RAX thành Zero, để hiển thị 'Correct Password' vì hàm check_pass () của chúng tôi trả về 0 hay 1 tùy thuộc vào việc mật khẩu là đúng hay sai.

Để tìm kiếm chuỗi, nhấp chuột phải vào bất kỳ đâu trong mã đã tháo rời -> Search for -> All modules -> String References

Kỹ thuật dịch ngược x64 cho người mới bắt đầu - Windows - Ảnh 2.

Thao tác này sẽ đưa bạn đến màn hình dưới đây, nơi nó hiển thị cho bạn chuỗi Mật khẩu sai. Vì chúng tôi biết sẽ có sự so sánh giữa mật khẩu nhập và mật khẩu ban đầu trước khi in cho dù mật khẩu có chính xác hay không, chúng tôi cần tìm mã tương tự từ mã đã tháo rời để quan sát thanh ghi vàstack để tìm kiếm mật khẩu cleartext. Bây giờ, nhấp chuột phải vào khu vực 'Incorrect Password' và chọn Follow in Disassembler. Điều này sẽ hiển thị màn hình dưới đây trong khu vực tháo gỡ:

Kỹ thuật dịch ngược x64 cho người mới bắt đầu - Windows - Ảnh 3.

Những gì tôi đã làm như ở trong hình trên, đó là tôi đã thêm một điểm ngắt tại 00000000004015F6. Lý do chính cho điều đó là bởi vì tôi có thể thấy một câu lệnh jmp và một lệnh call ngay phía trên nó. Điều này có nghĩa là một hàm được gọi trước khi chạm đến điểm này và hàm cuối cùng được thực thi trước khi in 'Correct/Incorrect password' là hàm check_pass(). Vì vậy, đây là điểm mà các hàm thú vị của chúng tôi bắt đầu khởi động. Chỉ cần nhấn vào nút chạy cho đến khi nó đạt đến việc thực thi điểm ngắt.

Ngay khi bạn đã đạt đến điểm ngắt này, nhấn stepi (F7) cho đến khi bạn chạm đến địa chỉ mov RCX, RAX hoặc 0000000000401601. Khi đó, bạn có thể thấy mật khẩu của chúng tôi pass123 được nạp vào thanh ghi RCX từ thanh ghi RAX. Không có gì khác ngoài việc đối số của chúng ta được nạp vào hàm check_pass(). Bây giờ, tiếp tục bước vào thanh ghi tiếp theo cho đến khi bạn đạt đến địa chỉ 0000000000401584, đó là nơi mật khẩu plaintext của chúng tôi được tải vào thanh ghi RAX.

Kỹ thuật dịch ngược x64 cho người mới bắt đầu - Windows - Ảnh 4.

Bạn có thể thấy trên cửa sổ trên cùng bên phải mật khẩu 'pass123' và mật khẩu ban đầu 'PASSWORD1' của chúng tôi được tải lên thanh ghi RCXRAX để làm nhiệm vụ so sánh. Hoàn thành động cơ chính của chúng tôi là nhận được mật khẩu plaintext. Vì mật khẩu của chúng tôi khác nhau nên nó sẽ in ra 'Incorrect password'. Bây giờ chúng tôi cần phải sửa đổi giá trị trả về từ 1 đến 0, được trả về bởi hàm check_pass(). Nếu bạn nhìn thấy hình ảnh trên, 3 dòng bên dưới mã của chúng tôi, nơi mật khẩu được tải lên thanh ghi, bạn sẽ thấy test EAX, EAX tại địa chỉ 0000000000401590. Và chúng tôi thấy hai câu lệnh nhảy sau chúng. Vì vậy, nếu giá trị thử nghiệm trả về mà bằng nhau, nó sẽ nhảy (je = nhảy nếu bằng nhau) đến crack_m3x64.40159B là nơi nó sẽ chuyển 0 đến thanh ghi EAX. Nhưng vì mật khẩu chúng tôi nhập sai, nó sẽ không nhảy ở đó mà tiếp tục đi đến đoạn mã tiếp theo, nơi nó sẽ di chuyển 1 đến EAX tức là tại địa chỉ 0000000000401594. Vì vậy, chúng tôi chỉ thiết lập điểm ngắt trên địa chỉ này bằng cách nhấp chuột phải và breakpoint- > toggle vì chúng tôi cần sửa đổi giá trị thanh ghi tại điểm đó và tiếp tục chạy tệp nhị phân cho đến khi nó đạt đến điểm ngắt đó:

Kỹ thuật dịch ngược x64 cho người mới bắt đầu - Windows - Ảnh 5.

Ngay khi điểm ngắt này đạt được, bạn sẽ đặt giá trị 1 vào thanh ghi RAX ở phía bên tay phải. EAX là thanh ghi 32 bit, là 32 bit cuối cùng của thanh ghi RAX. Tóm lại,

RAX = 32 bit EAX

EAX = 16 bit AX

AX = AH (8 bit) AL (8 bit)

và cứ thế.

Do đó, khi 1 được nạp vào EAX, theo mặc định, nó sẽ được chuyển vào thanh ghi RAX. Cuối cùng, chúng ta chỉ có thể chọn thanh ghi RAX ở phía bên phải, nhấn chuột phải và giảm nó về Zero.

Kỹ thuật dịch ngược x64 cho người mới bắt đầu - Windows - Ảnh 6.

Lời kết

Và sau đó bạn sẽ thấy RAX được đổi thành Zero. Bây giờ tiếp tục chạy nhị phân cho đến khi nó đạt đến điểm mà nó kiểm tra giá trị trả về của nhị phân là Zero hay One, có tại địa chỉ 000000000040160C. Bạn có thể thấy trong hình dưới đây đã nó sử dụng cmp để kiểm tra xem giá trị có khớp với 1 hay không.

Kỹ thuật dịch ngược x64 cho người mới bắt đầu - Windows - Ảnh 7.

RAX sử dụng điều kiện jne (nhảy nếu không bằng nhau), có nghĩa là nó sẽ nhảy tới crack_mex64.401636 nếu giá trị của nó không bằng One. Và crack_mex64.401636 sẽ in 'Correct Password' tại địa chỉ 0000000000401636. Bạn cũng có thể thấy trong thanh ghi mật khẩu của chúng tôi vẫn là pass123 mặc dù đã in là mật khẩu đúng.

Điều này sẽ dành cho các phiên crack của window cho blog này. Trong blog tiếp theo, chúng ta sẽ xem xét các ví dụ phức tạp hơn là việc chỉ tìm mật khẩu plaintext từ các tệp nhị phân.

Cảm ơn các bạn đã theo dõi! @@

link gốc: http://niiconsulting.com/checkmate/2018/04/reverse-engineering-x64-for-beginners-windows/

                                                                                      Theo Bizfly Cloud chia sẻ

>> Có thể bạn quan tâm: Kỹ thuật dịch ngược x64 cho người mới bắt đầu - Mã hóa XOR - Windows x64

SHARE