DEFCON 31 LiveCTF - shop
0x00. Introduction
Structures
Goal
unsigned __int64
There’s a hidden function hidden_1C83() that gets called when selecting option 7 from the menu after login. Here, if the first byte of login_info, i.e., the value of is_admin, is not 0, it spawns a shell.
0x01. Vulnerability
unsigned __int64
unsigned __int64
In add_item_1357(), when an item is added, a heap chunk is allocated to item_ptr. When deleting an item in remove_item_14B6(), it reallocates by only reducing the chunk size, and when the size becomes 0, realloc() returns NULL.
However, the value of shelf_ptr->item_ptr is not initialized and remains as is, and since the freed area can be accessed when calling add_item_1357() again after deletion, there is a UAF vulnerability.
0x02. Exploit
unsigned __int64
Looking at open_account_1932(), it creates an account and immediately sets is_admin to 0.
Therefore, I structured the exploit to add and then remove an item in account A, so that account B’s credential struct points to the freed area by .
- open_account A
- add_item 1
- remove_item 0
- logout
- open_account B
By writing the payload in this order, I can make A’s item_ptr and B’s credential located in the same area, and
- login as A
- add_item 2
I thought of a scenario where after logging in as A again and adding an item, is_admin gets overwritten during the process of copying item->number, but…
# Credential of B - BEFORE
# Credential of B - AFTER
The shell dropped, so when I checked if the value was properly overwritten, it was overwritten with a meta data of freed chunk instead of item->number.
Thinking carefully, there were the following issues:
- In
remove_item_14B6(),realloc()returnsNULL, so not only isitem_ptrnot initialized, but thecountvalue also doesn’t decrease - In the process of doing
add_item_1357()again, since thecountvalue is still 1, it requestsrealloc()for 0x40 - Not only does the size not match, but since the area where B’s
credentialexists has never beenfreed again, a completely different area gets allocated
As a result, meta data gets written during the realloc process, overwriting is_admin, and fortunately the exploit succeeds. Looks like I accidentally solved it with an unintended solution… lol
0x03. Payload
=
=
= 0x0000555555554000
=
= f
=
=
return
=
=
=
=
# open_account of A
# add_item 1
# remove_item 0
# logout
# open_account of B
# logout
# login as A
# add_item 2
# logout
# login as B
# hidden