Please take a moment to read http://bit.ly/demandglobalchange, to help share the message and support the initiative to tell our leaders to focus on addressing the global world problems, instead of complaining about the effects of their lack of leadership. Be a leader yourself, and share this with as many people as possible. #demandglobalchange // https://www.facebook.com/demandglobalchange



Please consider donating: https://www.corelan.be/index.php/donate/


9,103 views

Hack Notes : ROP retn+offset and impact on stack setup

Yesterday, sickn3ss (one of the frequent visitors of the #corelan channel on freenode IRC) posted a really interesting question.

The question

While testing ROP gadgets, as part of the process of building a DEP bypass exploit for WM Downloader, he wanted to know if there is a way to predict the required padding needed to properly align/set up the stack, when a gadget is used that ends with RET + offset.

Apparently a lot of people assumed that the offset (offset to RET) needs be compensated immediately after the gadget pointer… but that’s not true.

Let’s visualize the issue & see if we can find a general rule.

Let’s say your ROP chain contains the following 3 (fake) gadgets :

  • 77C1E842 : PUSH EDI / POP EAX / POP EBP / RET
  • 77C1D7F5: ADD EAX,20 / POP EBP / RET
  • 71AA2526 : XOR EAX,EAX / INC ESI / RET

When setting up the stack with these pointers, the exploit developer has to compensate for any data that will be picked up (POP) or otherwise has to be put on the stack in order to make sure the RET (at the end of the gadget) will return to the next gadget pointer.

The example setup (using the pointers above) would look like this :

ESP 77C1E842 <- first gadget. PUSH EDI/POP EAX is followed by POP EBP.
ESP+4 DAC0FF33 <- will be popped into EBP by gadget above. These 4 bytes need to be on the stack to make sure RET will land at next pointer (at ESP+8)
ESP+8 77C1D7F5 <- second gadget. POP EBP in this gadget will pick up the next 4 bytes on the stack
ESP+C DAC0FF33 <- will be popped into EBP by gadget 77C1D7F5. RET will then land at next pointer (at ESP+10)
ESP+10 71AA2526 <- third gadget. No additional bytes are needed because nothing will be picked up from stack by this gadget
ESP+14 <- 4th gadget needs to be put here

Nothing really special here.

What happens if the gadgets end with RET + offset ? How does that impact the stack alignment / padding bytes you need to put in between 2 gadget pointers ?

The answer

Let’s say we have the following gadgets :

  • 77C1E842 : PUSH EDI / POP EAX / POP EBP / RETN + 4
  • 77C1D7F5: ADD EAX,20 / POP EBP / RETN + 8
  • 71AA2526 : XOR EAX,EAX / INC ESI / RET

The first gadget ends with RETN+4. The second gadget ends with RETN+8. How does this impact the stack layout ?

ESP 77C1E842 <- first gadget. PUSH EDI/POP EAX is followed by POP EBP and RETN + 4
ESP+4 DAC0FF33 <- will be popped into EBP by gadget above. These 4 bytes need to be on the stack to make sure RET will land at next pointer (at ESP+8)
ESP+8 77C1D7F5 <- second gadget. POP EBP will pick up next 4 bytes. This gadget ends with RETN + 8
ESP+C 41414141 <- these are the 4 bytes needed to compensate for RET+4 in the first gadget. As you can see, the 4 bytes compensation need to be placed after the next RET instruction (so after the next gadget).
ESP+10 DAC0FF33 <- will be popped into EBP by gadget 77C1D7F5. RET will then land at next pointer (at ESP+10)
ESP+14 71AA2526 <- third gadget. No additional bytes are needed because nothing will be picked up from stack by this gadget.
ESP+18 41414141 4 bytes of padding – compensate for the first 4 bytes in RET+8 (gadget 2)
ESP+1C 41414141 4 bytes of padding – compensate for the second 4 bytes in RET + 8 (gadget 2)
ESP+20 <- 4th gadget must be placed here

Conclusion : the offset to RET must be accounted for on the stack after the next gadget pointer, and not after the current gadget pointer.

Thanks sickn3ss for popping the question & working with me to documenting the behaviour !


Copyright secured by Digiprove 2011 Peter Van Eeckhoutte

2011, Corelan Team (corelanc0d3r). All rights reserved.

Related Posts:

One Response to Hack Notes : ROP retn+offset and impact on stack setup

  • f4i2u1 says:

    Hi Peter,

    Been struggling to understand the compensating bytes location myself for the past couple of days :-). If this is of any help to others, I found that the offset value after RETN (in case of RETN + offset) means the number of bytes the CPU will remove from the stack after fetching the next address (and increment ESP by ‘offset’ bytes as the result). In the above example, because there is a RETN + 4 in the first gadget, the CPU will remove 4 bytes from the stack after fetching the next gadget address i.e. 0x77C1D7F5 hence the need for 0x41414141 padding after it in order for next RETN to go to the second gadget address i.e. 0x71AA2526 (after a POP in that gadget). Hope this make sense, or I stand to be corrected if my understanding is wrong here.

Corelan Live training

Since 2011, Corelan GCV has been teaching live win32 exploit dev classes at various security cons and private companies & organizations.

You can read more about the training and schedules here

Demand Global Change

The world needs your help !

Please take a few moments to read the "Demand Global Change Call For Action" document at
http://bit.ly/demandglobalchange
Read the full document at
http://bit.ly/demandglobalchange_full and share the message with as many people as possible.

Like the Facebook page, and SHARE it with everyone you know.



Donate

Want to support the Corelan Team community ? Click here to go to our donations page.

Want to donate BTC to Corelan Team?



Your donation will help funding server hosting.

Protected by Copyscape Web Plagiarism Tool

Corelan Team Merchandise

You can support Corelan Team by donating or purchasing items from the official Corelan Team merchandising store.

Corelan on IRC

You can chat with us and our friends on #corelan (freenode IRC)

Categories