Skip to content

publicqi/one_fmt

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

25 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

one_fmt

The goal of this tool is to build payload for format string vulnerability, as fmt_str module from pwntools on 64-bits machines is shitty.

  • Supports only python2 for now, as python3 for pwning is awful
  • Supports only 64-bits for now, as I personally rarely encounter 32-bits scenarios nowadays

Feel free to add supports and pull requests are welcomed.

Some code of this module is from Inndy/formatstring-exploit. It's better than pwntools, but still it used a a lot of paddings to generalize payloads therefore sometimes not so pleasing.

The payload has 3 levels: %n %hn %hhn. In version 1.1.0(2974bc4), I added an optimize() function to further reduce payload size. This should be the final version of functions for a while. Enjoy!

Installation

pip install one_fmt

Or

git clone https://github.com/publicqi/one_fmt.git
cd one_fmt
python2 setup.py install

Usage

from one_fmt import *
fmt = Fmt(offset=24, written=8)
fmt[0x601040] = "DEADBEEF"
fmt[0x601050] = 0x1337babe

# Add custom index
fmt.index(0x601040, 10)

payload_level_hhn = fmt.build(0)
payload_level_hn = fmt.build(1)
payload_level_n = fmt.build(2)

The payload has 3 levels: %n %hn %hhn. For some cases when dealing with a CTF challenge which limits your input length, you'd better to use a higher level with shorter payload but may takes longer time.

Custom index is for cases that input string is not on the stack or you cannot locate it. In this case, offset is meaning less and there's no "arbitrary" read/write. But you still can write to some addresses on the stack, which needs your manual operation. And you don't need to enter an exactly correct address in the first stage of _setitem_().

Test case

You can find a test program in test folder and test1.py. The challenge is written by @lockshaw. There're a few cases that the address contains \x0a therefore SIGSEV. And the challenge doesn't really need arbitrary write as lots addresses are there on the stack. It's just for demoing.

Another test program test2 is for me to test cases as well.

optimize_test folder is for me to test optimize function, and it worked on my machine XD

customize_index_test folder is to test custom index. I hand-crafted a payload with length 54 and the program did 64 bytes. So I think it's good enough.

Changelog

1.0.0: First version

1.0.1: Update Pypi project url

1.0.2: Fix typo in setup.py

1.0.3: Fix endianness; Fix %n index bug

1.1.0: Add optimization function; Fix bug

1.2.0: Add customized index

TODO

  • Add a level of automatically generate an shorter payload on low levels
    • For example, if you use level 0 to generatefmt[0x601050] = p64(0x4142), the payload will write to 8 addresses. However, this can be trimmed by write a %n to 0x601054 and a %hn to 0x601052.
  • Supports Python3 and 32 bits? Will do when I have the need.
  • ADD COMMENTS TO THE ULGY CODE
  • Add customized %N$n