All Projects → david942j → One_gadget

david942j / One_gadget

Licence: mit
The best tool for finding one gadget RCE in libc.so.6

Programming Languages

ruby
36898 projects - #4 most used programming language
shell
77523 projects

Projects that are alternatives of or similar to One gadget

Gef
GEF (GDB Enhanced Features) - a modern experience for GDB with advanced debugging features for exploit developers & reverse engineers ☢
Stars: ✭ 4,197 (+221.36%)
Mutual labels:  exploit, ctf, pwn
Hyperpwn
A hyper plugin to provide a flexible GDB GUI with the help of GEF, pwndbg or peda
Stars: ✭ 387 (-70.37%)
Mutual labels:  exploit, ctf, pwn
Ctf All In One
CTF竞赛权威指南
Stars: ✭ 2,807 (+114.93%)
Mutual labels:  exploit, ctf, pwn
exploiting
Exploiting challenges in Linux and Windows
Stars: ✭ 122 (-90.66%)
Mutual labels:  exploit, pwn, ctf
Libc Database
Build a database of libc offsets to simplify exploitation
Stars: ✭ 1,122 (-14.09%)
Mutual labels:  libc, ctf, pwn
pwnscripts
Very simple script(s) to hasten binary exploit creation
Stars: ✭ 66 (-94.95%)
Mutual labels:  exploit, pwn, ctf
Search Libc
Web wrapper of niklasb/libc-database
Stars: ✭ 124 (-90.51%)
Mutual labels:  libc, exploit, ctf
libc-db
libc database (file in packages, hash, package files, symbols). Raw binary libc available on https://github.com/BestPig/libc-bin)
Stars: ✭ 21 (-98.39%)
Mutual labels:  libc, pwn, ctf
Write Ups
📚 VoidHack CTF write-ups
Stars: ✭ 45 (-96.55%)
Mutual labels:  exploit, ctf, pwn
FastPwn
CTF中Pwn的快速利用模板(包含awd pwn)
Stars: ✭ 18 (-98.62%)
Mutual labels:  exploit, pwn, ctf
Shellen
🌸 Interactive shellcoding environment to easily craft shellcodes
Stars: ✭ 799 (-38.82%)
Mutual labels:  exploit, ctf, pwn
soma
Cross-platform CTF problem container manager
Stars: ✭ 23 (-98.24%)
Mutual labels:  pwn, ctf
Welpwn
💖CTF pwn framework.
Stars: ✭ 284 (-78.25%)
Mutual labels:  ctf, pwn
Pwn2exploit
all mine papers, pwn & exploit
Stars: ✭ 289 (-77.87%)
Mutual labels:  exploit, pwn
Exploits
Real world and CTFs exploiting web/binary POCs.
Stars: ✭ 69 (-94.72%)
Mutual labels:  exploit, pwn
Armpwn
Repository to train/learn memory corruption on the ARM platform.
Stars: ✭ 320 (-75.5%)
Mutual labels:  exploit, ctf
Pwn Sandbox
A sandbox to protect your pwn challenges being pwned in CTF AWD.
Stars: ✭ 81 (-93.8%)
Mutual labels:  ctf, pwn
how-to-exploit-a-double-free
How to exploit a double free vulnerability in 2021. Use After Free for Dummies
Stars: ✭ 1,165 (-10.8%)
Mutual labels:  pwn, ctf
Pwndra
A collection of pwn/CTF related utilities for Ghidra
Stars: ✭ 417 (-68.07%)
Mutual labels:  ctf, pwn
Ctf Wiki
Come and join us, we need you!
Stars: ✭ 5,305 (+306.2%)
Mutual labels:  ctf, pwn

Gem Version Build Status Downloads Code Climate Issue Count Test Coverage Inline docs Yard Docs MIT License

OneGadget

When playing ctf pwn challenges we usually need the one-gadget RCE (remote code execution), which leads to call execve('/bin/sh', NULL, NULL).

This gem provides such gadgets finder, no need to use objdump or IDA-pro every time like a fool 😉

To use this tool, type one_gadget /path/to/libc in command line and enjoy the magic 😆

Installation

Available on RubyGems.org!

$ gem install one_gadget

Note: requires ruby version >= 2.1.0, you can use ruby --version to check.

Supported Architectures

  • [x] i386
  • [x] amd64 (x86-64)
  • [x] aarch64 (ARMv8)

Implementation

OneGadget uses symbolic execution to find the constraints of gadgets to be successful.

The article introducing how I develop this tool can be found on my blog.

Usage

Command Line Interface

$ one_gadget
# Usage: one_gadget <FILE|-b BuildID> [options]
#     -b, --build-id BuildID           BuildID[sha1] of libc.
#     -f, --[no-]force-file            Force search gadgets in file instead of build id first.
#     -l, --level OUTPUT_LEVEL         The output level.
#                                      OneGadget automatically selects gadgets with higher successful probability.
#                                      Increase this level to ask OneGadget show more gadgets it found.
#                                      Default: 0
#     -n, --near FUNCTIONS/FILE        Order gadgets by their distance to the given functions or to the GOT functions of the given file.
#     -r, --[no-]raw                   Output gadgets offset only, split with one space.
#     -s, --script exploit-script      Run exploit script with all possible gadgets.
#                                      The script will be run as 'exploit-script $offset'.
#         --info BuildID               Show version information given BuildID.
#         --base BASE_ADDRESS          The base address of libc.
#                                      Default: 0
#         --version                    Current gem version.

$ one_gadget /lib/x86_64-linux-gnu/libc.so.6
# 0x4f2c5 execve("/bin/sh", rsp+0x40, environ)
# constraints:
#   rsp & 0xf == 0
#   rcx == NULL
#
# 0x4f322 execve("/bin/sh", rsp+0x40, environ)
# constraints:
#   [rsp+0x40] == NULL
#
# 0x10a38c execve("/bin/sh", rsp+0x70, environ)
# constraints:
#   [rsp+0x70] == NULL

x86_64

Given BuildID

$ one_gadget -b aad7dbe330f23ea00ca63daf793b766b51aceb5d
# 0x45526 execve("/bin/sh", rsp+0x30, environ)
# constraints:
#   rax == NULL
#
# 0x4557a execve("/bin/sh", rsp+0x30, environ)
# constraints:
#   [rsp+0x30] == NULL
#
# 0xf1651 execve("/bin/sh", rsp+0x40, environ)
# constraints:
#   [rsp+0x40] == NULL
#
# 0xf24cb execve("/bin/sh", rsp+0x60, environ)
# constraints:
#   [rsp+0x60] == NULL

build id

Gadgets Near Functions

Why

Consider this scenario when exploiting:

  1. Able to write on GOT (Global Offset Table)
  2. Base address of libc is unknown

In this scenario you can choose to write two low-byte on a GOT entry with one-gadget's two low-byte. If the function offset on GOT is close enough with the one-gadget, you will have at least 1/16 chance of success.

Usage

Reorder gadgets according to the distance of given functions.

$ one_gadget /lib/x86_64-linux-gnu/libc.so.6 --near exit,mkdir
# [OneGadget] Gadgets near exit(0x43120):
# 0x4f2c5 execve("/bin/sh", rsp+0x40, environ)
# constraints:
#   rsp & 0xf == 0
#   rcx == NULL
#
# 0x4f322 execve("/bin/sh", rsp+0x40, environ)
# constraints:
#   [rsp+0x40] == NULL
#
# 0x10a38c execve("/bin/sh", rsp+0x70, environ)
# constraints:
#   [rsp+0x70] == NULL
#
# [OneGadget] Gadgets near mkdir(0x10fbb0):
# 0x10a38c execve("/bin/sh", rsp+0x70, environ)
# constraints:
#   [rsp+0x70] == NULL
#
# 0x4f322 execve("/bin/sh", rsp+0x40, environ)
# constraints:
#   [rsp+0x40] == NULL
#
# 0x4f2c5 execve("/bin/sh", rsp+0x40, environ)
# constraints:
#   rsp & 0xf == 0
#   rcx == NULL
#

near

Regular expression is acceptable.

$ one_gadget /lib/x86_64-linux-gnu/libc.so.6 --near 'write.*' --raw
# [OneGadget] Gadgets near writev(0x1166a0):
# 1090444 324386 324293
#
# [OneGadget] Gadgets near write(0x110140):
# 1090444 324386 324293
#

Pass an ELF file as the argument, OneGadget will take all GOT functions for processing.

$ one_gadget /lib/x86_64-linux-gnu/libc.so.6 --near spec/data/test_near_file.elf --raw
# [OneGadget] Gadgets near exit(0x43120):
# 324293 324386 1090444
#
# [OneGadget] Gadgets near puts(0x809c0):
# 324386 324293 1090444
#
# [OneGadget] Gadgets near printf(0x64e80):
# 324386 324293 1090444
#
# [OneGadget] Gadgets near strlen(0x9dc70):
# 324386 324293 1090444
#
# [OneGadget] Gadgets near __cxa_finalize(0x43520):
# 324293 324386 1090444
#
# [OneGadget] Gadgets near __libc_start_main(0x21ab0):
# 324293 324386 1090444
#

Show All Gadgets

Sometimes one_gadget finds too many gadgets to show them in one screen, by default gadgets would be filtered automatically according to the difficulty of constraints.

Use option --level 1 to show all gadgets found instead of only those with higher probabilities.

$ one_gadget /lib/x86_64-linux-gnu/libc.so.6 --level 1
# 0x4f2c5 execve("/bin/sh", rsp+0x40, environ)
# constraints:
#   rsp & 0xf == 0
#   rcx == NULL
#
# 0x4f322 execve("/bin/sh", rsp+0x40, environ)
# constraints:
#   [rsp+0x40] == NULL
#
# 0xe569f execve("/bin/sh", r14, r12)
# constraints:
#   [r14] == NULL || r14 == NULL
#   [r12] == NULL || r12 == NULL
#
# 0xe5858 execve("/bin/sh", [rbp-0x88], [rbp-0x70])
# constraints:
#   [[rbp-0x88]] == NULL || [rbp-0x88] == NULL
#   [[rbp-0x70]] == NULL || [rbp-0x70] == NULL
#
# 0xe585f execve("/bin/sh", r10, [rbp-0x70])
# constraints:
#   [r10] == NULL || r10 == NULL
#   [[rbp-0x70]] == NULL || [rbp-0x70] == NULL
#
# 0xe5863 execve("/bin/sh", r10, rdx)
# constraints:
#   [r10] == NULL || r10 == NULL
#   [rdx] == NULL || rdx == NULL
#
# 0x10a38c execve("/bin/sh", rsp+0x70, environ)
# constraints:
#   [rsp+0x70] == NULL
#
# 0x10a398 execve("/bin/sh", rsi, [rax])
# constraints:
#   [rsi] == NULL || rsi == NULL
#   [[rax]] == NULL || [rax] == NULL

Other Architectures

i386
$ one_gadget /lib32/libc.so.6
# 0x3cbea execve("/bin/sh", esp+0x34, environ)
# constraints:
#   esi is the GOT address of libc
#   [esp+0x34] == NULL
#
# 0x3cbec execve("/bin/sh", esp+0x38, environ)
# constraints:
#   esi is the GOT address of libc
#   [esp+0x38] == NULL
#
# 0x3cbf0 execve("/bin/sh", esp+0x3c, environ)
# constraints:
#   esi is the GOT address of libc
#   [esp+0x3c] == NULL
#
# 0x3cbf7 execve("/bin/sh", esp+0x40, environ)
# constraints:
#   esi is the GOT address of libc
#   [esp+0x40] == NULL
#
# 0x6729f execl("/bin/sh", eax)
# constraints:
#   esi is the GOT address of libc
#   eax == NULL
#
# 0x672a0 execl("/bin/sh", [esp])
# constraints:
#   esi is the GOT address of libc
#   [esp] == NULL
#
# 0x13573e execl("/bin/sh", eax)
# constraints:
#   ebx is the GOT address of libc
#   eax == NULL
#
# 0x13573f execl("/bin/sh", [esp])
# constraints:
#   ebx is the GOT address of libc
#   [esp] == NULL

i386

AArch64
$ one_gadget spec/data/aarch64-libc-2.27.so
# 0x3f160 execve("/bin/sh", sp+0x70, environ)
# constraints:
#   address x20+0x338 is writable
#   x3 == NULL
#
# 0x3f184 execve("/bin/sh", sp+0x70, environ)
# constraints:
#   addresses x19+0x4, x20+0x338 are writable
#   [sp+0x70] == NULL
#
# 0x3f1a8 execve("/bin/sh", x21, environ)
# constraints:
#   addresses x19+0x4, x20+0x338 are writable
#   [x21] == NULL || x21 == NULL
#
# 0x63e90 execl("/bin/sh", x1)
# constraints:
#   x1 == NULL

aarch64

Combine with Script

Pass your exploit script as one_gadget's arguments, it can try all gadgets one by one, so you don't need to try every possible gadgets manually.

$ one_gadget ./spec/data/libc-2.19.so -s 'echo "offset ->"'

--script

In Ruby Scripts

require 'one_gadget'
OneGadget.gadgets(file: '/lib/x86_64-linux-gnu/libc.so.6')
#=> [324293, 324386, 1090444]

# or in shorter way
one_gadget('/lib/x86_64-linux-gnu/libc.so.6', level: 1)
#=> [324293, 324386, 939679, 940120, 940127, 940131, 1090444, 1090456]

# from build id
one_gadget('b417c0ba7cc5cf06d1d1bed6652cedb9253c60d0')
#=> [324293, 324386, 1090444]

To Python Lovers

import subprocess
def one_gadget(filename):
  return [int(i) for i in subprocess.check_output(['one_gadget', '--raw', filename]).decode().split(' ')]

one_gadget('/lib/x86_64-linux-gnu/libc.so.6')
#=> [324293, 324386, 1090444]

Make OneGadget Better

Any suggestion or feature request is welcome! Feel free to send a pull request.

Please let me know if you find any libc that make OneGadget fail to find gadgets. And, if you like this work, I'll be happy to be starred 😬

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].