Gallopsled / pwntools

CTF framework and exploit development library
http://pwntools.com
Other
12.15k stars 1.72k forks source link

ROP should also use __setattr__ to automatically set register values with setRegisters #1636

Closed heapcrash closed 4 years ago

heapcrash commented 4 years ago

Currently, if you have a ROP gadget that has a pop eax; ret gadget, you can access ROP.eax and get the gadget information.

This should work in the other direction, so that setting e.g. rop.rax = 0xdeadbeef adds the correct data to the stack.

mariuszskon commented 4 years ago

Hi, I am interested in working on this. The only thing I am unsure of at the moment is how we would handle setting multiple registers "at once" i.e. with the minimum number of rop chains. I see that we are using _ delimited registers in __getattr__:

        #
        # Check for a '_'-delimited list of registers
        #
        x86_suffixes = ['ax', 'bx', 'cx', 'dx', 'bp', 'sp', 'di', 'si',
                        'r8', 'r9', '10', '11', '12', '13', '14', '15']

        if all(map(lambda x: x[-2:] in x86_suffixes, attr.split('_'))):
            return self.search(regs=attr.split('_'), order='regs')

But what should go on the right hand side of the assignment? A tuple? e.g.

rop.rax_rdi_rsi = (0xdead, 0xbeef, 0xcafe)

This looks a bit ugly to me, but I'm not sure what else we can do. Ideally something like this would work, but would require each __setattr__ call to check previous ones:

rop.rax = 0xdead
rop.rdi = 0xbeef
rop.rsi = 0xcafe
rop.chain()  # minimum rop chain for setting all of the above, not three separate chains (if possible)

Thanks, Mariusz

Arusekk commented 4 years ago

Yes, this is a good option, but I don't think this would be required. Most will actually use it with a single register name.

A pretty pretty option would be to allow something like this:

rop = ROP(context.binary)
rop(rax=0xdead, rdi=0xbeef, rsi=0xcafe)
mariuszskon commented 4 years ago

Indeed the __call__ interface @Arusekk proposes appears quite pleasant. Any other opinions?

zachriggle commented 4 years ago

I like the call interface, can we make it so that it takes kwargs or a dict? I know we can just do **dict but not everybody knows that.

On Sun, Sep 27, 2020 at 11:51 PM Mariusz Skoneczko notifications@github.com wrote:

Indeed the call interface @Arusekk https://github.com/Arusekk proposes appears quite pleasant. Any other opinions?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/Gallopsled/pwntools/issues/1636#issuecomment-699768035, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAA3IGEJ4YERBGGJSKW24V3SIAI6DANCNFSM4OWJKL2Q .

--

Zach Riggle

Arusekk commented 4 years ago

See #1681

mariuszskon commented 4 years ago

Please see my PR #1688