ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

c-跳到argv吗?

2019-12-10 03:50:40  阅读:318  来源: 互联网

标签:buffer-overflow assembly gdb c-3 linux


我正在尝试shellcode,偶然发现了nop-slide技术.我写了一个小工具,将buffer-size作为参数并像这样构造一个缓冲区:[NOP | SC | RET],NOP占用缓冲区的一半,然后是shellcode,其余的则填充(猜测的)返回地址.它与他的著名论文中描述的工具aleph1非常相似.

我脆弱的测试应用程序与他的论文相同:

int main(int argc, char **argv) {
char little_array[512];
if(argc>1)
    strcpy(little_array,argv[1]);   
return 0;
}

我测试了一下,效果很好:

jth@insecure:~/no_nx_no_aslr$./victim $(./exploit 604 0)
$exit

但老实说,我不知道为什么.好的,保存的eip已按预期被覆盖,但我认为它没有跳到缓冲区中,而是跳到了argv中.

gdb在调用strcpy()之前显示了以下地址:

(gdb) i f  
Stack level 0, frame at 0xbffff1f0:  
 eip = 0x80483ed in main (victim.c:7); saved eip 0x154b56  
 source language c.  
 Arglist at 0xbffff1e8, args: argc=2, argv=0xbffff294  
 Locals at 0xbffff1e8, Previous frame's sp is 0xbffff1f0  
 Saved registers:  
  ebp at 0xbffff1e8, eip at 0xbffff1ec  

little_array的地址:

(gdb) print &little_array[0]
 $1 = 0xbfffefe8 "\020"

在strcpy()之后:

(gdb) i f
Stack level 0, frame at 0xbffff1f0:
 eip = 0x804840d in main (victim.c:10); saved eip 0xbffff458
 source language c.
 Arglist at 0xbffff1e8, args: argc=-1073744808, argv=0xbffff458
 Locals at 0xbffff1e8, Previous frame's sp is 0xbffff1f0
 Saved registers:
  ebp at 0xbffff1e8, eip at 0xbffff1ec

那么,这里发生了什么?我使用了604字节的缓冲区来溢出little_array,因此他当然重写了保存的ebp,保存的eip和argc以及带有猜测地址0xbffff458的argv.

然后,返回后,EIP指向0xbffff458.但是little_buffer位于0xbfffefe8,相差1136个字节,因此他当然没有执行little_array.我使用stepi命令跟踪执行,然后从0xbffff458开始,他执行NOP并到达Shellcode.

我不太确定为什么会这样.首先,我是否正确说他在argv中而不是little_array中执行我的shellcode? loader(?)将argv放在哪里?我以为它紧随argc之后,但是在argc和0xbffff458之间,有620个字节的间隙.他怎么可能成功地“降落”在地址为0xbffff458的NOP面板中,该地址比保存的eip高于0xbffff1ec的地址高?

有人可以澄清吗?我实际上不知道为什么这样做.我的测试机器是没有ASLR的Ubuntu 9.10 32位机器.受害者有一个可执行栈,用execstack -s设置.

提前致谢.

解决方法:

首先,绘制堆栈图.

0xBFFFF4F9 |          |
            ----------
          ...   
0xBFFFF29E |    NOP   |
0xBFFFF29D |    NOP   | argv[1]   * guestimate
            ----------
0xBFFFF29C |   '\0'   |
          ...
0xBFFFF295 |    '/'   |
0xBFFFF294 |    '.'   | argv[0] "./victim"
            ----------
          ... 
            ----------
0xBFFFF1F8 |   NULL   |
0xBFFFF1F8 | &argv[1] |
0xBFFFF1F4 | &argv[0] | argv
            ---------- 
0xBFFFF1F0 | 0x000002 | argc
            ---------- 
          ...
0xBFFFEFE9 |          |
0xBFFFEFE8 |          | little_array
            ----------

(注意:在图中,某些框每行保留1个字节,其他框为4或8,这取决于存储在其中的类型)

And where does the loader(?) place argv onto the stack?

在调用strcpy表明它们可能在little_array之上之后,argc和argv被覆盖.我将它们放置在0xBFFFF1F0处,因为那是堆栈在上一帧结束的地方,而且main的帧中似乎没有空间,即使GDB表示arglist位于0xBFFFF1E8.它依赖于我的系统-argc和argv低于little_array.尝试使用p& argv和p& argc来确定它们的放置位置.

由于0xBFFFF458位于argv [1]中,因此argv [1]中的shellcode确实是要执行的内容,而不是little_array中的内容.由于有两个shell代码副本(一个在little_array中,另一个在argv [1]中),根据您猜测的返回地址,可以执行其中一个.

I thought [argv] follows immediately after argc, but between argc and 0xbffff458, there is a gap of 620 bytes.

0xBFFFF458是漏洞利用后存储在argv中的值(请注意,argc与(带符号的)0xBFFFF458 == -1073744808相同).之前,argv持有0xbffff294.在这两种情况下,argv本身都存储在其他位置.

标签:buffer-overflow,assembly,gdb,c-3,linux
来源: https://codeday.me/bug/20191210/2099165.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有