由一道题引发的对无字母数字WebShell的思考

前言

跟随 PHITHON 师傅 的笔记 , 研究了一下 无字母数字 的 WebShell~


一道题目

写这篇 Blog 的本因是看到了这段代码

题目的要求很明确 , 就是构造一个WebShell , 执行 getFlag() 函数 来拿到 Flag . 但是题目要求真的非常有意思

  1. 整个代码的长度不能超过35个字符
  2. 在代码中不能出现任何字母 , 数字 , $_

这就很奇怪了 , 不使用任何字母和数字 , 那么怎么能构造WebShell呢 ? 网上对这类问题有这差不多的解决方案 , 主要从三个方面入手 , 这里来总结学习一下


三大思路


异或运算得到对应字符

在PHP中 , 两个字符串执行异或操作之后 , 得到的还是一个字符串 . 利用PHP这个特性 , 如果想要得到a-zA-Z0-9中的某个字符 , 那么就可以去找两个非字母 , 非数字的字符 , 它们的异或结果是要的字符就可以了

那么现在问题的关键点就转移到 : 如何找到这两个非字母 , 非数字的字符

为了解决这个问题 , 可以先列举出常用的特殊字符 , 对它们进行异或运算 , 看看它们两两异或能得到什么字符

输出结果 , 可以发现能通过它们得到想要的字母 ,而且不同的字符异或后可以得到相同的字母~

png

得到了这些字符 , 就可以构造我们所需的 getFlag()


取反运算得到对应字符

该方法与使用异或运算有异曲同工之妙 , 不过它利用的是 UTF-8 编码中的某个汉子 , 将其中的某个字符提取出来 , 进行取反后得到对应字符

这里网上都是直接给一张图 , 但是好像没有人讲为什么这么做 . 在手动寻找特殊字符上面 , 我建议使用逆推的方式

比如我们想要得到字符 " e " , 你可以按照以下步骤寻找特殊字符

  1. 找到 " e " 对应的ASCII编码
    e 对应的十六进制编码为65 , 十进制编码为101 , 这里需要用到 65 这个数字

  2. 在前面添加两个十六进制数 . 这个数是任意的 . 然后将它取反 .
    比如这里在前面添加 7B , 然后进行取反

    png

  3. 将取反后的数字写成 NCR 格式( &#x ... ) , 并且将它转换为中文字符

    png

    你不用管它是什么字 , 只要是个UTF-8中文字符就可以 . 如果发现无法转换成中文字符 , 那么回到第二步 , 多找两次十六进制字符肯定就可以了

  4. 带入代码测试 , 取第二个字符( 第一个字符是你任意添加的 ) , 即可得到需要的字符

    png

    成功得到需要的字符 !

按照上面的方法 , 你可以通过UTF-8汉字来得到每个你需要的字符

当然你可能有疑问 : 在上面代码中 , 我们需要通过 {1} , {2} 来取值 , 但这样不是违背题目要求了吗

对 , 所以这里我们我们需要用到PHP另外一个特性 : PHP弱类型比较 . 请看下面代码

png

1 或者 2 可以通过上面这种弱类型比较来得到


递增运算得到对应字符

上面两种骚操作都是通过位运算来实现的 , 那么如果不使用位运算 , 能不能搞定这题呢?

PHP有这么个特性 :

在处理字符变量的算数运算时 , PHP沿袭了Perl的习惯 , 而非C的

举个例子 :
$a = 'a' , $b = ++$a , 那么$b = 'b'

也就是说 , 'a'++ = 'b' , 'b'++ = 'c' , 只要我们能拿到一个字符 , 就可以将所有的字符全部推出来了

那么怎么获得一个字符呢 ? 正好 , 数组( Array ) 中既包含了大写字母A , 也包含了小写字母a . 通过变换 , 我们就能得到所有的字母了!

png

同样 , 这里可以通过PHP弱类型比较来得到数字

png

03 也可以使用PHP弱类型比较来得到


难点 --- PHP5 的局限性

到此为止 , 我们已经可以得到任何我们想要的字符了 . 一般的题目也就到这里为止了 .

但是这题却很难 , 因为它不仅禁用数字和字母 , 还禁用 $_

如果目标主机用的是 PHP7+ , 那么执行代码根本就不是问题 . 因为在 PHP7+ 中 , 可以以 (函数名)() 这样的格式去动态执行函数 . 利用这个特性就完成Payload . 这里拿 phpinfo() 作为例子

  1. 先通过异或的方法拿到组成 phpinfo() 的特殊字符
    phpinfo = "\(\@@&/" ^ ",@,).@@"

  2. 因为代码是通过url获取参数的 . 为了避免特殊符号的影响 , 将 phpinfo(); 进行URL编码

    png

  3. 带入URL中 , 即可利用成功

    png

但是根据网上流传的题目 , 当时这道题所处的PHP环境是PHP5 , 而在PHP5中 , 好像没有不使用 $ , _ 就可以动态执行函数的方法


破局

该方法我还存在一些疑问 , 等彻底搞明白后再来写

看了一下网上各个大佬的骚操作 , 发现主流了是一种 php5 + shell 的解决方案 , 这种思路我还是第一次见到 , 长姿势了~

其实在之前我就走入了一个误区 , 那就是 : 我要去执行那个getFlag() 函数来拿到Flag

在Linux下一切都是文件 , 那么我们可以构造一个 读文件或者执行命令 的操作 , 直接读取flag的内容

原题我们可以构造一个文件上传的数据包 , 通过文件上传可以在服务器的/tmp目录下生成一个PHP的临时文件 . 文件的内容为要执行的命令 , 这个临时文件的生命周期就是在PHP代码执行的期间 , PHP代码执行结束就会自动删除

但是这里毕竟只是分析题目 , 所以实验环境就拿本地环境来做

在这里需要用到多个知识点


进阶分析


PHP 上传文件副本命名特性

PHP在上传文件的时候 , 会在临时目录下生成一个文件副本 . 直到脚本结束这个文件副本才会被删除

可以写一个demo来证实一下

png

当用户上传一个文件后 , 会生成一个临时的文件副本

png

值得一提的是 , 这个文件副本的名称是固定的 , 格式为 : /tmp/php + 6个字母或者数字


Linux glob 通配符匹配特性

成功上传了文件 , 那么该如何找到这个文件呢 ? 要知道我们无法使用任何字母或者数字

Linux中可以使用 glob 通配符匹配任意文件名 , ? 可以匹配任意一个字符 , [] 里面可以通过ASCII编码指定匹配字符的范围 , 下面来举个例子

比如匹配 /???/????????? , 会发现存在太多匹配项

png

但是一想这个临时文件的名称存在大写字母 , 那么就假设最后一位为大写字母 . 在ASCII编码中 , A为65 , Z为90 , 那么这里取第64位 @ 和第91位[ , 刚好它们都是可用的字符

png

这时已经可以比较精确的匹配那个临时文件了 . 既然生成的临时文件名是随机的 , 那么假设倒数第二位也为大写字母吧

png

成功 ! 通过/???/???????[@-[][@-[] 唯一匹配了可能出现PHP临时文件


Linux " . " 符号执行文件特性

Linux中可以使用 . 去执行任意文件 , 即使这个文件没有 x 执行权限

png

PHP5 短标签特性

php短标签 <?= .. > 相当于 <?php echo ... ; ?> 的作用

png


极限利用

在掌握上面四个知识点后 , 你就可以完成本题了 !!!

  1. 先构造一个上传文件的请求 , 可以使用之前写的demo发送的数据包

    png

  2. 当然这里题目中可没有什么 submit 按钮 , 我们需要删除这部分内容 . 把这个数据包丢到 repeater 模块中 , 改造数据包

    构造数据包时 , 需要构造 Payload 来闭合前面的内容 , 执行自己构造的<?= ... ?>语句 . 所以需要构造 ?code=?><?= ... ?> 这部分的内容了 , 把之前写的那个demo放进去就可以了 , 完整的 Payload 为 ?code=?><?=. /???/???????[@-[][@-[]?>

    将这个 Payload 进行URL编码后 , 防止特殊字符带来的影响

    png

    最终 , 修改后的数据包如下所示

    png

    这个 a.txt 中的内容即为你想要执行的命令 , 这里选择使用 id 命令

  3. 点击 GO , 多执行几次 . 当生成的PHP临时文件的最后两位均为大写字母时 , 该 Payload 利用成功 ! HTTP响应了对应命令的执行结果

    png

命令执行成功 ! 对于本题来说 , 只不过是将 id 命令改成查看flag的命令就可以了


总结

现在你可以完成该题了 ! 这也是现在互联网上最常见的解法 . 但是大多数的教程都没有具体的讲这种解法的原因

我在上面详细的阐述了解题的具体过程 , 同时自己也学到了很多 , 希望这篇文章能让你眼前一亮~

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇