WIN下
获
取kernel基址的shellcode
探讨
gz1X
[
gz1x
(at)
tom
(
dot
)
com
]
2006.6.30
[
什么是shellcode
]
———————————
Shellcode是一个攻击程
序
(Exploit)的
核心代
码,能够在溢出后改
变
系统的正常
流
程,取得系统的
控
制
权
,是一
些汇
编
代
码抽取成的
16进
制码;
[
经典
溢出攻击
流
程
]
———————————
1.
查找Kernel32.dll基地址;
2.
查找GetProcAddress
()
函
数地址;
3.
查找
其
它API
函
数地址;
4.
CreateProcess
()
;
5.
远程
连
接。
我们都知
道WINDOWS
的系统功能不像UNIX的系统调
用
那
样
实现,
由
于WINDOWS版本的不断更
新
,使得系统调
用
对SHELLCODE几
乎起
不到作
用
。
但是WINDOWS是
靠DLL
动态链接库
来
实现,这
就
是说,如果能从KERNEL32.DLL中
获
取LoadLibrary
()
和GetProcAddress
()
函
数的地址,我们
就可
以调
用WINDOWS
下的所有
函
数了。
所以我们需要对KERNEL32.DLL
进
行地址定位,这也是本文的目的。
[
获
取KERNEL地址的方法
]
———————————
1.
通过PEB
获
取;
2.
通过TOPSTACK
-
TEB
获
取;
3.
通过SEH
获
取;
[
第三方工具
获
取基址
]
———————————
为了方便
审核和
对比结果,我们
用MASM提
供的dumpbin分析本地kernel32.dll的加
载
地址。如下:
C:
\WINDOWS\system32
>
dumpbin
/
headers kernel32.dll
//
...此
处
省略
看OPTIONAL HEADER VALUES
里
的
7C800000
image base,
其
中
7C800000即
为本地kernel32.dll的加
载
地址。
注意是本地的加
载
地址,在远程目标
机
器
上
,我们需要额外的技巧
来
实现kernel32.dll地址的查找,
即PEB
,
SEH等方法。
当然,为了简单,你也
可
以
直
接
用Windbg
加
载
一个类似noteapad的
可
执行程
序
,ModLoad
里
很清晰地给出了kernel32.dll的地址。
[
PEB
]
———————————
获
取KERNEL地址最有效的方法
就
是通过PEB实现,
即
:PEB kernel base location。
下
面
是一个比较常见的
利用PEB获
取kernel32.dll地址的shellcode
,
31
字
节
。
————————————————
/*
程
序1
*/
004045F4
>
6A 30
PUSH
30
004045F6 59
POP
ECX
004045F7 64
:
8B09
MOV
ECX
,DWORD PTR
FS
:[
ECX
]
004045FA 85C9
TEST
ECX
,
ECX
004045FC 78 0C
JS SHORT
OllyTest.0040460A
004045FE 8B49 0C
MOV
ECX
,DWORD PTR
DS
:[
ECX
+C]
00404601 8B71 1C
MOV
ESI
,DWORD PTR
DS
:[
ECX
+
1C
]
00404604
AD
LODS DWORD PTR
DS
:[
ESI
]
00404605 8B48 08
MOV
ECX
,DWORD PTR
DS
:[
EAX
+
8
]
00404608
EB
09
JMP SHORT
OllyTest.00404613
0040460A 8B49 34
MOV
ECX
,DWORD PTR
DS
:[
ECX
+
34
]
0040460D 8B49 7C
MOV
ECX
,DWORD PTR
DS
:[
ECX
+
7C
]
00404610 8B49 3C
MOV
ECX
,DWORD PTR
DS
:[
ECX
+
3C
]
————————————————
现在
来
分析下,PEB方法查找
流
程如下:
(
1
)
FS
寄
存
器
->
TEB结构;
(
2
)
TEB
+
0x30
->
PEB结构;
(
3
)
PEB
+
0x0c
->
PEB_LDR_DATA;
(
4
)
PEB_LDR_DATA
+
0x1c
->
Ntdll.dll;
(
5
)
Ntdll.dll
+
0x08
->
Kernel32.dll。
在
2000
以后的系统中,实际
上
实现的方法只要很短的几行:
mov
eax
,
fs
:[
30h
]
mov
eax
,[
eax
+
0ch
]
mov
esi
,[
eax
+
1ch
]
lodsd
mov
ebx
,[
eax
+
08h
]
而在程
序1
中涉
及
了
9X
系统,所以还有相
关
的
判
断
跳
转。
首
先,我们
来
看看TEB
和PEB
的结构,
利用WINDBG
,调试如下:
0
:
000
> dt
ntdll!_TEB
+
0x000
NtTib
:
_NT_TIB
+
0x01c
EnvironmentPointer
:
Ptr32 Void
+
0x020
ClientId
:
_CLIENT_ID
+
0x028
ActiveRpcHandle
:
Ptr32 Void
+
0x02c
ThreadLocalStoragePointer
:
Ptr32 Void
+
0x030
ProcessEnvironmentBlock
:
Ptr32 _PEB
+
0x034
LastErrorValue
:
Uint4B
+
0x038
CountOfOwnedCriticalSections
:
Uint4B
+
0x03c
CsrClientThread
:
Ptr32 Void
+
0x040
Win32ThreadInfo
:
Ptr32 Void
...
//
此
处
省略
+
0xfac
CurrentTransactionHandle
:
Ptr32 Void
+
0xfb0
ActiveFrame
:
Ptr32 _TEB_ACTIVE_FRAME
+
0xfb4
SafeThunkCall
:
UChar
+
0xfb5
BooleanSpare
: [
3
]
UChar
0
:
000
> dt -
v
-
r ntdll!_PEB
struct
_PEB
,
65
elements
,
0x210
bytes
+
0x000
InheritedAddressSpace
:
UChar
+
0x001
ReadImageFileEx