🚩
Practical CTF
BlogContact
  • 🚩Home - Practical CTF
  • 🌐Web
    • Enumeration
      • Finding Hosts & Domains
      • Masscan
      • Nmap
      • OSINT
    • Client-Side
      • Cross-Site Scripting (XSS)
        • HTML Injection
        • Content-Security-Policy (CSP)
      • CSS Injection
      • Cross-Site Request Forgery (CSRF)
      • XS-Leaks
      • Window Popup Tricks
      • CRLF / Header Injection
      • WebSockets
      • Caching
    • Server-Side
      • SQL Injection
      • NoSQL Injection
      • GraphQL
      • XML External Entities (XXE)
      • HTTP Request Smuggling
      • Local File Disclosure
      • Arbitrary File Write
      • Reverse Proxies
    • Frameworks
      • Flask
      • Ruby on Rails
      • NodeJS
      • Bun
      • WordPress
      • Angular
    • Chrome Remote DevTools
    • ImageMagick
  • 🔣Cryptography
    • Encodings
    • Ciphers
    • Custom Ciphers
      • Z3 Solver
    • XOR
    • Asymmetric Encryption
      • RSA
      • Diffie-Hellman
      • PGP / GPG
    • AES
    • Hashing
      • Cracking Hashes
      • Cracking Signatures
    • Pseudo-Random Number Generators (PRNG)
    • Timing Attacks
    • Blockchain
      • Smart Contracts
      • Bitcoin addresses
  • 🔎Forensics
    • Wireshark
    • File Formats
    • Archives
    • Memory Dumps (Volatility)
    • VBA Macros
    • Grep
    • Git
    • File Recovery
  • ⚙️Reverse Engineering
    • Ghidra
    • Angr Solver
    • Reversing C# - .NET / Unity
    • PowerShell
  • 📟Binary Exploitation
    • ir0nstone's Binary Exploitation Notes
    • Reverse Engineering for Pwn
    • PwnTools
    • ret2win
    • ret2libc
    • Shellcode
    • Stack Canaries
    • Return-Oriented Programming (ROP)
      • SigReturn-Oriented Programming (SROP)
      • ret2dlresolve
    • Sandboxes (chroot, seccomp & namespaces)
    • Race Conditions
  • 📲Mobile
    • Setup
    • Reversing APKs
    • Patching APKs
    • HTTP(S) Proxy for Android
    • Android Backup
    • Compiling C for Android
    • iOS
  • 🌎Languages
    • PHP
    • Python
    • JavaScript
      • Prototype Pollution
      • postMessage Exploitation
    • Java
    • C#
    • Assembly
    • Markdown
    • LaTeX
    • JSON
    • YAML
    • CodeQL
    • NASL (Nessus Plugins)
    • Regular Expressions (RegEx)
  • 🤖Networking
    • Modbus - TCP/502
    • Redis/Valkey - TCP/6379
  • 🐧Linux
    • Shells
    • Bash
    • Linux Privilege Escalation
      • Enumeration
      • Networking
      • Command Triggers
      • Command Exploitation
      • Outdated Versions
      • Network File Sharing (NFS)
      • Docker
      • Filesystem Permissions
    • Analyzing Processes
  • 🪟Windows
    • The Hacker Recipes - AD
    • Scanning/Spraying
    • Exploitation
    • Local Enumeration
    • Local Privilege Escalation
    • Windows Authentication
      • Kerberos
      • NTLM
    • Lateral Movement
    • Active Directory Privilege Escalation
    • Persistence
    • Antivirus Evasion
    • Metasploit
    • Alternate Data Streams (ADS)
  • ☁️Cloud
    • Kubernetes
    • Microsoft Azure
  • ❔Other
    • Business Logic Errors
    • Password Managers
    • ANSI Escape Codes
    • WSL Tips
Powered by GitBook
On this page
  1. Binary Exploitation

ret2win

Jump to a predefined function in the binary, even with arguments

When you have found a buffer overflow, you can set the Instruction Pointer to any value by overwriting it. In some simple cases, there is a predefined function in the binary that may not even be used but can be jumped to. This is always an easy win, so check if this is the case in your binary. You can use objdump -d ./binary to view the disassembly of all known functions, or you can look at a decompiler of your choice to find these functions.

To exploit it, you can use the simple PwnTools ROP functionality to find any required ROP gadgets automatically and resolve function names for you.

elf = ELF("./binary")
rop = ROP(elf)
rop.win()

payload = flat({
    OFFSET: rop.chain()
})

The example above will call a function named win() in your binary, and then use the flat() function to add the required amount of padding before the return address (rop.chain). If you have the correct offset, it will now jump to and run your function.

In some cases, the stack might be misaligned causing segmentation faults even when doing it correctly like this. In such a case, you can simply realign the stack by inserting a single ret instruction before actually jumping to the desired function.

rop = ROP(elf)
rop.call(rop.ret)
rop.win()

Adding arguments

With some more PwnTools magic adding arguments to a function call can also be really easy:

rop = ROP(elf)
rop.win(42, 1337)

But sometimes you need a string, which is a little harder. Strings are stored as pointers (addresses) to the string. This means the string itself is not actually stored on the stack we are overflowing, only the address is. We can only set the address, so we need to find some address where the string is stored.

If you can leak addresses like the stack pointer, you can simply calculate and point it to the address of your own payload, where you completely control the value as it is your input.

If you can only leak an address like libc, you can search in that binary to find the string you need. For example:

libc = ELF("./libc.so.6")
bin_sh = next(libc.search(b"/bin/sh"))  # 0x7fcdf0446698

rop.system(bin_sh)  # Call with string argument

This way you can still call functions with specific string arguments, to get a shell in this case.

PreviousPwnToolsNextret2libc

Last updated 2 months ago

📟