首页
社区
课程
招聘
[求助]:《shellcoder's handbook 》第19页测试 shellcode 的程序编译后运行出错!
发表于: 2008-7-2 16:24 5850

[求助]:《shellcoder's handbook 》第19页测试 shellcode 的程序编译后运行出错!

2008-7-2 16:24
5850
就是那个测试 shellcode 的程序:
char shellcode[] =
"\xeb\x1a\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08\x89\x46"
"\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe1"
"\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68";
int main()
{
int *ret;
ret = (int *)&ret + 2;
(*ret) = (int)shellcode;
}

我编译顺利,但是执行会报段错误!
[root@localhost asm]# ./sc
Segmentation fault (core dumped)

系统环境为 redhat as4,
[root@localhost asm]# uname -a
Linux localhost.localdomain 2.6.9-5.EL #1 Wed Jan 5 19:22:18 EST 2005 i686 i686 i386 GNU/Linux

我觉得这段代码我看懂了,用gdb调试过程和所想的也完全一样,改写的是ebx下面的 ret 返回地址,但是就是不能像书中写的那样顺利执行成功获得sh!出错发生在main执行完毕 leave 后到 ret 的那一步!请高手解答!

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

收藏
免费 0
支持
分享
最新回复 (9)
雪    币: 2108
活跃值: (208)
能力值: (RANK:1260 )
在线值:
发帖
回帖
粉丝
2
没有这样的环境。
据猜测,最大的可能是因为内核版本不同。
2008-7-2 16:30
0
雪    币: 2110
活跃值: (21)
能力值: (RANK:260 )
在线值:
发帖
回帖
粉丝
3
Segmentation fault为Unix下的SIG(信号),大致相当于Windows下的内存访问异常

你读的这本书我还没机会读到,不过其中的代码,是32位平台的吗?为什么调整指针是2,不是4?

你在GDB中看一下,ret = (int *)&ret + 2;这句是按照预计的把返回地址存储到ret变量中了吗?

在ret指令之间,检查一下堆栈,看看返回地址是不是shellcode的地址。

我的感觉那里应该是 ret = (int *) ( (void *) (&ret) + 4),不过也不确定,因为C语言标准当中,对局部变量的堆栈使用是决定于编译器的,不能保证堆栈的布局中局部变量ret紧挨着返回地址。

用调试器调试一下就知道在你的平台上,指针应该调整多少了,自己试试吧。
2008-7-2 16:41
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
我自己手动调试过的,ebp和esp显示应该正是 ret 之上时 保存的ebp 再之上是自动变量,
调整指针是2,刚好追到ebp下面的那个位置,也就是ret的位置,从书上讲的和我自己亲手调的,都应该没错才对,但是实际运行中确实是内存访问异常了。
我用stepi指令逐汇编指令调试,我注意到leave指令之后,(即ebp恢复之后),将要执行ret之前,再调试输出ret的值,输出的就是恢复之后的ebp下面那一格的值了,刚好是0,我怀疑是此处引起了内存访问异常错误,但是即便在leave指令之后,esp指向的位置也正是所修改的  &ret+2 的位置啊,就是说在执行 ret 之前, shellcode[]的内容确实是在栈顶esp处的,但是一执行ret指令就出错了。十分不解,谢谢关注,期待进一步的帮助解答~

(btw: shellcoder's handbook 那本书网上有中文版,好像论坛里就有,你找找看吧)
2008-7-3 00:30
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
嗯,谢谢提示,我再到redhat 9 下面去试一下。
但是我觉得即使内核版本不同,栈空间里面的顺序应该也不会乱掉啊,并且即使我不直接用main做实验,我用main()调用func(),在func()里面再调用那几个语句也一样会报内存异常错误,
就是说应该并不是main()函数体外面的环境引起的,不管怎样,我先去搭一个redhat9的虚拟机吧:)
2008-7-3 00:35
0
雪    币: 4583
活跃值: (3567)
能力值: ( LV12,RANK:230 )
在线值:
发帖
回帖
粉丝
6
你的内核启用了数据区不可执行的保护吧。我在没启用这个保护的系统上执行成功。

用gdb停在最后的ret那里,

在另一个shell里查看

cat /proc/<your pid>/maps

应该是这个原因。你要折腾这种东西,还是装个Debian好了,不然很可能面临新内核加上来的一堆保护特性。再就是要用gcc-2.95编译,不要用gcc-4.x什么的,因为那些书的作者写文章的时候用的是老版本的gcc。这个区别也很大,gcc-4.x会改变内存布局的。
2008-7-3 10:26
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
谢谢scz的解答,的确应该就是scz所说的这个原因了。
在arhat的提示下我到rh9上做了测试,我在rh9下执行那段代码是可以正常运行的,并且按照scz的指导去查看/proc/p-pid/maps 下面各加载页面的执行属性,无法正常执行的系统的栈页属性确实没有x,肯定就是DEP的原因了。

以前刚开始学习shellcode栈溢出的内容时模模糊糊的感觉是有点不对劲的,只是没有把这个概念显化,记得看操作系统的教科书上说,操作系统可以对内存页面设置是否可执行属性的,好像说可执行文件格式之所以分成.data,.text等段的意义正在于此。依照这样看来,shellcode岂不是根本没有多大的用武之地吗?

搜了一下关于DEP的资料,大都是关于WindowsXP新加DEP 补丁的一些设置说明,其中搜到北邮一个高手flyingkisser一篇逆向DEP的文章,里面说绕过DEP还是得用return-to-lib的经典方式返回到VirtualProtect()来改变当前栈的属性。

怎么这些在那些shellcode的书里面都不提到呢,感觉对shellcode的效能大小也有些信心动摇了,呵呵


关于linux下的DEP,好像相关文章很少,没有搜到。不知道scz你是怎样启用linux kernel的DEP的呢?能不能帮忙推荐几篇这方面的文章?
另外就是,怎么kernel对于这种出错有没有在什么地方记录DEP违规?我在/var/log/message里面没看到哦
您建议我装个Debian好了,不知道debian在这方面和rh 有什么区别?


对于DEP(数据段执行保护)这个概念今天第一次有了明确概念,再次感谢scz,感谢大家的关注和帮助。
2008-7-4 17:43
0
雪    币: 4583
活跃值: (3567)
能力值: ( LV12,RANK:230 )
在线值:
发帖
回帖
粉丝
8
> 怎么这些在那些shellcode的书里面都不提到呢,感觉对shellcode的效能大小也有些信心动摇了

你没好好看这本书。有些时候,真正看完了,走过了,再回头来一遍,会发现自己的那些结论下得是多么的早。

要不,你还是看上两整遍,再来自己回答这些问题?
2008-7-5 22:10
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
谢谢,继续学习。:)
2008-7-5 22:44
0
雪    币: 2108
活跃值: (208)
能力值: (RANK:1260 )
在线值:
发帖
回帖
粉丝
10
我的偶像也来了,:)

一本书不可能面面俱到,一定会有它的局限性。
而且这本书里还提到“这是一本讲解黑客技术的书,不要指望我们把什么都讲得很清楚“,原文记不清了,大概就是这个意思。

忘了说了,这本书的第二版里,已经专门拿出一章来讨论内核保护的话题,你可以下载英文版看看。
2008-7-6 23:16
0
游客
登录 | 注册 方可回帖
返回
//