Skip to content

Instantly share code, notes, and snippets.

@Charo-IT
Last active August 28, 2016 01:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Charo-IT/61903c3ad41928a99705bc6b6222796d to your computer and use it in GitHub Desktop.
Save Charo-IT/61903c3ad41928a99705bc6b6222796d to your computer and use it in GitHub Desktop.
katagaitai勉強会 #5 関西med - [hack you 2014] Crypto200 hashme writeup
$ ruby hashme.rb
[*] connected
[*] crack key
key = 28c1150dac6704583d6c1125a72d3c87241e7f5497e9b80c78f4ce2b08dcab2b0df20be0abde0b17512a935bc765607cf5e5
[*] generate base cert
auth_str = login=charo&role=anonymous
hash = c98ae88d1a3e2429b754781923423e54
[*] try length extension attack
................FLAG{2016_is_5th_aniversary_of_katagaitai} ☆(ゝω・)v
[*] connection closed
#coding:ascii-8bit
require "pwnlib"
require "base64"
remote = true
if remote
host, port = ["(*´ω`*)", 1337]
else
host, port = ["localhost", 54321]
end
class PwnTube
def recv_until_prompt
2.times{recv_until("======================\n")}
end
end
def gen_cert(username)
@tube.recv_until_prompt
@tube.sendline("0")
@tube.recv_until("Your login: ")
@tube.sendline(username)
@tube.recv_capture(/Your auth certificate:\n(.*?)\n/)[0]
end
def auth(cert)
@tube.recv_until_prompt
@tube.sendline("1")
@tube.recv_until("Provide your certificate:\n")
@tube.sendline(cert)
end
def xor(a, b)
a.bytes.zip(b.bytes * 100).map{|a, b| (a ^ b).chr}.join
end
def hashme(s, status = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0])
def f(x, y, z)
((~x & z) | (~x & z)) & 0xffffffff
end
def g(x, y, z)
((x & z) | (~z & y)) & 0xffffffff
end
def h(x, y, z)
(x ^ y ^ y) & 0xffffffff
end
def i(x, y, z)
(y ^ (~z | x)) & 0xffffffff
end
def rol(x, y)
(x << y | x >> (32 - y)) & 0xffffffff
end
a, b, c, d, l = status.tap{|a| a[4] &= 0x1f}
x = (0...256).map{|i| (0xffffffff * Math.sin(i)).to_i & 0xffffffff}
for k in s.bytes
a = (b + rol(a + f(b, c, d) + x[k], l)) & 0xffffffff
b = (c + rol(b + g(c, d, a) + x[k], l)) & 0xffffffff
c = (d + rol(c + h(d, a, b) + x[k], l)) & 0xffffffff
d = (a + rol(d + i(a, b, c) + x[k], l)) & 0xffffffff
l = (l + 1) & 0x1f
end
return [b, a, d, c].map{|a| "%08x" % a}.join
end
def crack_key(length = 32)
username = "A" * length
status = "login=#{username}&role=anonymous"
key = xor(Base64.decode64(gen_cert(username)), status)[0...-32]
for i in 1...status.length / 2
if key[0...i] == key[i...i * 2]
return key[0...i]
end
end
crack_key(length * 2)
end
PwnTube.open(host, port){|tube|
@tube = tube
puts "[*] crack key"
key = crack_key
puts "key = #{key.unpack("H*")[0]}"
puts "[*] generate base cert"
auth_str, hash = gen_cert("charo").tap{|cert|
cert = xor(Base64.decode64(cert), key)
break [cert[0...-32], cert[-32..-1]]
}
puts "auth_str = #{auth_str}"
puts "hash = #{hash}"
puts "[*] try length extension attack"
b, a, d, c = hash.scan(/.{8}/).map{|a| a.to_i(16)}
for i in 0...0x20
print "."
new_hash = hashme("&role=administrator", [a, b, c, d, i])
auth(Base64.encode64(xor(auth_str + "&role=administrator" + new_hash, key)).gsub(/\s/, ""))
result = tube.recv_until("\n")
if result.include?("Welcome")
puts tube.recv_until("\n")
break
end
end
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment