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

Fixes #538 - breakrva on symlink targets #539

Merged
merged 2 commits into from
Apr 21, 2019

Conversation

disconnect3d
Copy link
Member

@disconnect3d disconnect3d commented Oct 9, 2018

Fixes a bug with breakrva and brva commands reported in #538 and adds some more
explanation on how certain things works:

  • info auxv or to be more specific: AUXV's ET_EXECFN holds path to
    the executable, but if it is a symlink, it is not dereferenced
  • because of that we need to call readlink in get_exe_name in pie.py

Fixes a bug with `breakrva` and `brva` commands and adds some more
explanation on how certain things works:
* `info auxv` or to be more specific: AUXV's `ET_EXECFN` holds path to
the executable, but if it is a symlink, it is not dereferenced
* because of that we need to call `readlink` in `get_exe_name` in pie.py
@@ -245,7 +245,7 @@ def walk_stack2(offset=0):

return auxv

def get_execfn():
def _get_execfn():
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I renamed this as this function is internal to the file and should not be used outside.

# On the other hand, the vmmap, if taken from /proc/pid/maps will contain
# the absolute and real path of the binary (after symlinks).
# And so we have to read this path here.
real_path = pwndbg.file.readlink(path)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pwndbg.file.readlink should work on local, remote, qemu etc. See https://github.com/pwndbg/pwndbg/blob/dev/pwndbg/file.py#L68-L74

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might also just be able to read /proc/self/exe, versus using AT_EXECFN. I think the only reason we don't do that is for QEMU, since it can't emulate what we see.

Perhaps we should check for QEMU first, and just use /proc/self/exe otherwise?

@disconnect3d
Copy link
Member Author

TODO / FIXME for me:

  • check if breakrva/brva works on remote targets
  • check if breakrva/brva works on (remote) qemu targets

@rcx
Copy link
Contributor

rcx commented Oct 9, 2018

Just tested this locally on a symlinked binary, and it works for me.

$ ln -s ./target ./test
$ gdb ./test
> starti
> brva 0x8F6
> vmmap
pwndbg> vmmap
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
0x56630000 0x56631000 r-xp     1000 0      /root/target
pwndbg> info b
Num     Type           Disp Enb Address    What
3       breakpoint     keep y   0x566308f6 in main at target.c:17
> ^D
$ gdb ./target
> starti
> brva 0x8f6
0x565b9000 0x565ba000 r-xp     1000 0      /root/target
> info b
Num     Type           Disp Enb Address    What
1       breakpoint     keep y   0x565b98f6 in main at target.c:17

Ideally we should test this on QEMU and remote too, but assuming the readlink helper works then this LGTM.

# On the other hand, the vmmap, if taken from /proc/pid/maps will contain
# the absolute and real path of the binary (after symlinks).
# And so we have to read this path here.
real_path = pwndbg.file.readlink(path)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might also just be able to read /proc/self/exe, versus using AT_EXECFN. I think the only reason we don't do that is for QEMU, since it can't emulate what we see.

Perhaps we should check for QEMU first, and just use /proc/self/exe otherwise?

@disconnect3d
Copy link
Member Author

@zachriggle lol, a test on qemu launched with qemu-x86_64 -g 4444 ./a.out.

Without pwndbg:

✘ 130 ➜ gdb ./a.out 
Reading symbols from ./a.out...(no debugging symbols found)...done.
(gdb) target remote localhost:4444
Remote debugging using localhost:4444
warning: remote target does not support file transfer, attempting to access files from local filesystem.
Reading symbols from /lib64/ld-linux-x86-64.so.2...Reading symbols from /usr/lib/debug//lib/x86_64-linux-gnu/ld-2.27.so...done.
done.
0x0000004000a04090 in _start () from /lib64/ld-linux-x86-64.so.2
(gdb) b main
Breakpoint 1 at 0x64a
(gdb) c
Continuing.
warning: Probes-based dynamic linker interface failed.
Reverting to original interface.

[Inferior 1 (Remote target) exited normally]
(gdb) 

With pwndbg there is no memory page for the binary in _start eh...

@disconnect3d
Copy link
Member Author

@zachriggle any hint how to debug PIE binaries with qemu? :|

@rcx
Copy link
Contributor

rcx commented Oct 12, 2018

The horrible handling of PIE is one of my greatest frustrations with gdb as opposed to windows debuggers.
On GDB 8.1, this is remedied with the starti command. What we should do is keep track of all brva breakpoints, and upon (re)starting the binary, it clears all the relative breakpoints, executes starti, then re-sets the relative breakpoints. I don't know how to implement this, however.

@disconnect3d
Copy link
Member Author

disconnect3d commented Oct 16, 2018

@ecx86 That's probably a lot of work. It would be nice to research qemu more and see if we can do sth with rebasing in there. Maybe they rebase binary to the same address each time? [wishful thinking, heh]

@rcx
Copy link
Contributor

rcx commented Oct 16, 2018 via email

@disconnect3d
Copy link
Member Author

disconnect3d commented Oct 16, 2018

@ecx86 What do you mean by unrealistic address space? Why?

Oh, I meant, that we need to be able to find out the address the code will reside in.

@rcx
Copy link
Contributor

rcx commented Oct 16, 2018 via email

@disconnect3d
Copy link
Member Author

@ecx86 Oh I totally understand that point. Still, you usually test without ASLR and just make your exploit not assume this. However yeah, there might be situations where u need aslr/pie as you want to check out if your (partial) brute force works.

Anyway, I would rather accept a case where we disable ASLR to make things easier for pwndbg on qemu.. 🤕

I asked on qemu irc whether it is possible to find out the address that qemu will put the binary on.

@disconnect3d
Copy link
Member Author

Note to self or anyone who is willing to help: look through #168 - maybe we can get the image base address (after aslr randomization) from there?

@disconnect3d disconnect3d merged commit 33350ab into pwndbg:dev Apr 21, 2019
@disconnect3d
Copy link
Member Author

Merged as it stayed here for so long. Not sure if things could be done better, we may find it out in the future if this or similar things pops out.

@disconnect3d disconnect3d deleted the fix-breakrva-on-symlink-targets branch April 21, 2019 13:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

3 participants