首页
社区
课程
招聘
[求助]单字节溢出原理
发表于: 2013-8-1 15:29 3558

[求助]单字节溢出原理

2013-8-1 15:29
3558
apache mod_rewrite 单字节溢出漏洞,下面是存在漏洞函数
static char *escape_absolute_uri(ap_pool *p, char *uri,
unsigned scheme)
2700 {
2701 char *cp;
2733 if (!strncasecmp(uri, "ldap", 4)) {
2734 char *token[5];
2735 int c = 0;
2736
2737 token[0] = cp = ap_pstrdup(p, cp);
2738 while (*cp && c < 5) {
2739 if (*cp == '?') {
2740 token[++c] = cp + 1;
2741 *cp = '\0';
2742 }
2743 ++cp;
2744 }
token[5]时候溢出,token[5]覆盖了ebp最后一个字节。我想问下,漏洞的利用原理是什么样的。网上的技术帖子总是在关键地方含糊不清,实在看不懂。

覆盖了ebp的一个字节,函数执行完时候,
mov esp,ebp
pop ebp        //弹出了我们覆盖的地址给ebp,  
ret                //pop eip  

不太明白这里是怎么样跳到shellcode的?知道的告诉下,就是单字节溢出的的控制流程。谢谢了

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
免费 0
支持
分享
最新回复 (13)
雪    币: 116
活跃值: (70)
能力值: ( LV10,RANK:170 )
在线值:
发帖
回帖
粉丝
2
ebp被修改了,mov esp,ebp后esp的值跟正常执行不一样,ret当然会改变执行流程,lz可以动态调试一下,注意栈区中数据的变化
2013-8-1 15:51
0
雪    币: 565
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
http://bbs.pediy.com/showthread.php?t=56445&viewgoodnees=1&prefixid=
你的问题,在这个入门介绍里都有解答
2013-8-1 15:55
0
雪    币: 86
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
构造 one - by - one  ebp  让esp  弹出处,进入eip 的 指针为  执行处,或者跳板处...回来执行 shellcode...
2013-8-1 16:01
0
雪    币: 31
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
详细说下,谢谢
2013-8-2 13:30
0
雪    币: 46
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
ebp被控制之后,将ebp mov到esp,也就是esp也被控制,之后ret会将esp弹出给eip,导致控制程序流程。个人拙见,请指教。
2013-8-2 17:47
0
雪    币: 124
活跃值: (429)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
7
在这个函数中ebp是不变的,但是在上一个函数中ebp改变了。上一个函数中再执行mov esp,ebp不就控制了esp
2013-8-3 10:24
0
雪    币: 31
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
我又看了下上面提到的教程,讲的还是可以直接填充缓冲区,直到覆盖eip,没有说单字节时候是什么情况。
函数调用结束的时候,要退出当前的栈帧
先,mov esp,ebp  //使esp,ebp指向同一个地方,就是前一栈帧的ebp,  到这里还是正常的啊

pop ebp               //弹出了我们覆盖的地址给ebp,  这时候,ebp的值变成我们覆盖的,这时候堆栈应该不正常了。
ret                       //相应的这里pop eip也出问题了,就是不明白这里到底怎么弹出的。。怎么弹出跳转地址,或shellcode的地址。。
2013-8-3 15:45
0
雪    币: 31
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
函数调用结束的时候,要退出当前的栈帧
先,mov esp,ebp  //使esp,ebp指向同一个地方,就是前一栈帧的ebp,  到这里还是正常的啊

pop ebp               //弹出了我们覆盖的地址给ebp,  这时候,ebp的值变成我们覆盖的,这时候堆栈应该不正常了。
ret                       //相应的这里pop eip也出问题了,就是不明白这里到底怎么弹出的。。怎么弹出跳转地址,或shellcode的地址。。
2013-8-3 15:48
0
雪    币: 124
活跃值: (429)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
10
esp在结束之前是不变的,在当前函数会正常返回,堆栈有问题也是调用它的函数
2013-8-3 16:14
0
雪    币: 124
活跃值: (429)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
11
调试一下,看看堆栈就明白了
2013-8-3 16:15
0
雪    币: 31
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
确实是在前一函数中,函数结束时,把覆盖的ebp,赋值给esp,感谢提醒。
现在又遇到个问题,

00401238   add         esp,24Ch
0040123E   cmp         ebp,esp
00401240   call        __chkesp (00401320)//在这里这个函数会把堆栈恢复,并弹出错误
00401245   mov         esp,ebp            //ebp被我们覆盖
00401247   pop         ebp
00401248   ret

这样我就没法继续了,,有没有什么办法能把这函数去掉么?
2013-8-6 16:54
0
雪    币: 124
活跃值: (429)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
13
这个水平有限,这种加gs保护,并且没办法引起异常的,好像没办法用。你看一下有没有可能利用这个,执行其他操作,,比如有没有可能覆盖虚指针,不一定是非得覆盖函数返回地址,具体的反汇编结果不知道,只能帮你到这了
2013-8-7 11:15
0
雪    币: 31
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
对于调试版本,VC++编译器在“直接调用地址”时会增加检查esp的代码,例如:

    ta = (TAdd)add; // TAdd定义:typedef int (__cdecl *TAdd)(int a, int b);
    c = ta(a, b);

产生以下汇编代码:

    mov [ebp-10h],0040100a
    mov esi,esp
    mov ecx,dword ptr [ebp-8]
    push ecx
    mov edx,dword ptr [ebp-4]
    push edx
    call dword ptr [ebp-10h]
    add esp,8
    cmp esi,esp
    call __chkesp (004011e0)
    mov dword ptr [ebp-0Ch],eax

__chkesp 代码如下。如果esp不等于函数调用前保存的值,就会转到错误处理代码。

    004011E0 jne __chkesp+3 (004011e3)
    004011E2 ret
    004011E3 ;错误处理代码

__chkesp的错误处理会弹出对话框,报告函数调用造成esp值不正确。 Release版本的汇编代码要简洁得多。也不会增加 __chkesp。如果发生esp错误,程序会继续运行,直到“遇到问题需要关闭
2013-8-7 14:59
0
游客
登录 | 注册 方可回帖
返回
//