Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

doc: add example case for tuple (host, port pair) in gdb.attach #2504

Merged
merged 6 commits into from
Feb 17, 2025

Conversation

RocketMaDev
Copy link
Contributor

In gdb.attach, target can be host, port pair, but this is not documented below. Recently I ran into a case where I need to debug the remote binary while I still would like to utilize local gdb.

I started xinetd on port A to deliver gdbserver which listens on port B. To debug the target binary, I first connected to port A with remote and started gdb to attach to port B, then I could interact with the target while I was able to set breakpoints.

I realize this is a perfect example case to demonstrate how could pwntools debug remote apps with local gdb.

屏幕截图_20241211_022844

@peace-maker
Copy link
Member

Is the example added in #2291 lacking? Or how does your setup differ here? Is bash and gdbserver running on a different host?

@RocketMaDev
Copy link
Contributor Author

In my setup, both gdbserver and the target program are on the "remote" machine (I use 127.0.0.1 as an example), while #2291 launches local gdbserver.

As the old doc launches gdbserver locally, that confuses me a bit as I had to make debugging remotely instead of locally.

Maybe that part of doc could be deleted? Because gdb.debug does that job, and my case can't be done with gdb.debug.

@Arusekk
Copy link
Member

Arusekk commented Dec 18, 2024

Can you add a socat listener somewhere? So that the tests really test.

@RocketMaDev
Copy link
Contributor Author

Can you add a socat listener somewhere? So that the tests really test.

OK, I could do that. But what about the similar doc in #2291? How can I modify my doc?

@peace-maker
Copy link
Member

I think it's enough to change the documentation showing you can use gdb.attach((IP, port)) tuples to not say it has to be a local gdb stub. The test is a manual local gdbserver because I can't start a remote gdbserver from the doctests :D We can improve the docs there to explicitly say that the gdbserver can be running anywhere. But I don't know if your example of starting gdbserver when connecting to a socket using xinetd or socat isn't too specific. That seems better suited in a tutorial?

pwntools/pwnlib/gdb.py

Lines 1041 to 1062 in fb2ee19

Attach to a gdbserver / gdbstub running on the local machine
by specifying the host and port tuple it is listening on.
(gdbserver always listens on 0.0.0.0)
>>> gdbserver = process(['gdbserver', '1.2.3.4:12345', '/bin/bash'])
>>> gdbserver.recvline_contains(b'Listening on port', timeout=10)
b'Listening on port 12345'
>>> pid = gdb.attach(('0.0.0.0', 12345), gdbscript='''
... tbreak main
... commands
... call puts("Hello from gdbserver debugger!")
... continue
... end
... ''')
>>> gdbserver.recvline(timeout=10) # doctest: +ELLIPSIS
b'Remote debugging from host 127.0.0.1, ...\n'
>>> gdbserver.recvline(timeout=10)
b'Hello from gdbserver debugger!\n'
>>> gdbserver.sendline(b'echo Hello from bash && exit')
>>> gdbserver.recvline(timeout=10)
b'Hello from bash\n'
>>> gdbserver.close()

@peace-maker
Copy link
Member

If you have ssh access you can use gdb.ssh_gdb to start a gdbserver on the remote and use the local gdb to connect to it through ssh port forwarding. That might be what you were looking for in the first place. I just noticed it only has an example script and no doc comment which causes it to not show in in the docs. That's not optimal 😅

@RocketMaDev
Copy link
Contributor Author

Well, I come up with this idea when I'm reproducing CVE-2024-2961. Though ssh forwarding is suitable for a real machine or virtual machine, it's too heavy for container. As the cve has been fixed already, and the lib with bug is loaded dynamically, it's hard to reproduce the bug just with patchelf. As a result, I start a ubuntu:noble-20240423 in which the bug still exists, and place my poc on it.

In this case, if I start a ssh, obviously it will cost too much. So I start a xinted to deliver gdbserver.

@peace-maker
Copy link
Member

I see the benefit of having access to the stdio of the target process this way too instead of only debugging it remotely. I think we can wrap this more nicely and redirect the tty on remote when connecting to a running gdbserver, but that requires some additional thought.

You can attach to a remote process through a pipe in gdb too which we might want to support.

target remote | sudo docker exec -i your-container gdbserver - --attach 42

For this PR the tests could be actually run though by starting the socat process and closing it after gdb disconnects. The docs above the example are clear enough that the socat command should be run on a different host.

@RocketMaDev
Copy link
Contributor Author

Ahh, doctest failed...

I think we can wrap this more nicely

In my opinion, it might not be suitable to launch docker every time as it's a bit too "heavy". As for integration, I think we can add a positional argument gdbserver_port in remote, so when user gdb.attach to remote, we can retrieve address and port from remote object.

@peace-maker peace-maker merged commit 447ac94 into Gallopsled:dev Feb 17, 2025
13 of 14 checks passed
@RocketMaDev RocketMaDev deleted the doc branch February 19, 2025 02:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants