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

Overhaul ROP.setRegisters to support more complex cases needed by AMD64 #1044

Merged
merged 13 commits into from
Oct 11, 2017

Conversation

zachriggle
Copy link
Member

Additionally, have a separate cache for ROPs composed of multiple ELF files

The old version would only work if there was a dumb pop reg register for every register we need.

This version will find the best combination of gadgets to cover any set of registers.

Given a simple AMD64 ELF:

>>> context.arch = 'amd64'
>>> asm = 'pop rdx; pop rdi; pop rsi; add rsp, 0x20; ret; target: ret'
>>> e = ELF.from_assembly(asm)

The most simple case is to just get to a give naddress. This uses the ROP.call mechanism underneath.

>>> r = ROP(e)
>>> r.target()
>>> print r.dump()
0x0000:       0x10000008 target()

When we make a single-argument call, Pwntools knows it needs to populate RDI. Previously, this would only work when a pop rdi gadget was present.

>>> r = ROP(e)
>>> r.target(1)
>>> print r.dump()
0x0000:       0x10000001 pop rdi; pop rsi; add rsp, 0x20; ret
0x0008:              0x1 [arg0] rdi = 1
0x0010:       'eaaafaaa' <pad rsi>
0x0018:       'gaaahaaa' <pad 0x20>
0x0020:       'iaaajaaa' <pad 0x18>
0x0028:       'kaaalaaa' <pad 0x10>
0x0030:       'maaanaaa' <pad 0x8>
0x0038:       0x10000008 target

We can also populate multiple registers. Everything works out correctly.

>>> r = ROP(e)
>>> r.target(1,2,3)
>>> print r.dump()
0x0000:       0x10000000 pop rdx; pop rdi; pop rsi; add rsp, 0x20; ret
0x0008:              0x3 [arg2] rdx = 3
0x0010:              0x1 [arg0] rdi = 1
0x0018:              0x2 [arg1] rsi = 2
0x0020:       'iaaajaaa' <pad 0x20>
0x0028:       'kaaalaaa' <pad 0x18>
0x0030:       'maaanaaa' <pad 0x10>
0x0038:       'oaaapaaa' <pad 0x8>
0x0040:       0x10000008 target

There is no perceptible delay at runtime. Loading a random libc.so.6 from Ubuntu, we can make up-to-4-argument calls (it can't find pop r8 or pop r9 anywhere in any gadgets).

This fixes #1019

Additionally, have a separate cache for ROPs composed of multiple ELF files
@zachriggle zachriggle merged commit 1577263 into Gallopsled:dev Oct 11, 2017
@zachriggle zachriggle added this to the 3.11.0 milestone Oct 12, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ROP setRegisters
1 participant