专栏首页信安之路【作者投稿】奇葩webshell技巧

【作者投稿】奇葩webshell技巧

前段时间看XDCTF的一道web题,发现了一种很奇特的构造webshell的方法。

Base64一句话木马


题目的大概意思就是允许包含,但限制了使用的字符,仅允许使用'acgtACGT'这8个字符。

emmm,就像我第一次看到一样,感觉这根本不能构造webshell嘛,这要能弄出来,我直播吃……冰激凌。

不废话了,原理如下:

先大致讲一下,任何由 {A-Z|a-z|0-9|+|/} 组合的字符串(如果不够4的倍数可以用'='补全),如果长度为4的倍数,则都可以作为base64解码的材料,而在base64decode的时候,会产生原字符串包含字符集以外的字符,举个例子:

字符串aaaa进行base64解码:

结果为i��,有一部分为乱码,不过不要紧,因为至少产生了一个额外的、可以被利用的字符i

如果是md5那样的哈希编码,多一位字母,编码后的整个字符串就完全不一样了,但是base64不一样。

base64编码是一种基于64个可打印字符来表示二进制数据的表示方法。由于2的6次方等于64,所以每6个比特为一个单元,对应某个可打印字符。三个字节有24个比特,对应于4个Base64单元,即3个字节可表示4个可打印字符。也就是说3个字节进行base64编码之后是4个字节。四个字节解码后为三个字节。

因此base64有一个特性,就是以四位为一个单位,多个单位组合起来,进行多次解密,得到的结果和组合的顺序相同。再举一个例子:

abcABC123的编码结果为YWJjQUJDMTIz,我们把加密后的字符串四个为一组拆开YWJj(abc)、QUJD(ABC)、MTIz(123),组合为MTIzYWJjQUJD

123abcABC的顺序反过来了。

base64还有一个特性,就是会自动抛弃不符合要求的字符,如果要进行解密的base64字符串包括有不合法的字符,也就是不在集合 {A-Z|a-z|0-9|+|/} 里,同时也不是末尾的等号的字符。会被自动抛弃,又一个例子:

PS:注意py版本为2.7

aaaa的解密结果为i��

iiii的解密结果为�(�

如果我们把aaaa的解密结果重复四遍,再进行解密

结果和iiii的解密结果是一样的

从以上两个例子能Get到什么猥琐的技巧呢?

三个背景知识:

① 编码和解码不是唯一对应,就是说字母a可能通过不同的,其它字符的组合进行base64解码解出来。(组合种类远多于base64的合法字符种类)

② 被解码的字符,以四位为一个单位,多个单位组合起来,进行多次解密,得到的结果和组合的顺序相同。

③ 我们的一句话<?php @eval($_POST[a]);?>,可以通过解密另一个字符串,我们假设为字符串一号获得,而字符串一号可以通过解密字符串二号获得,并且这种序列不是唯一的。我们有可能找到仅仅由acgtACGT这8个字符组合起来的一串字符,这串字符在经过n次解密后的结果为我们的一句话木马。当然,在这个过程中,要保证四位一组,否则会乱序。

然后附上王一航大佬的Python脚本:

https://gist.github.com/WangYihang/a49c663237e68822dd4816e99534ca72)

我加入了很多的注解,然后我们来一步一步地,从主函数开始分析:

首先输出了base64_chars,这是在之前的 base64_chars = string.letters + string.digits + "+/" 中定义好的。base64除了‘=’以外可能会用到的字符串。然后tables = enmu_tables(set(chars))将可以使用的8个字符带入了enmu_tables()函数。

我们跟进enmu_tables()函数,它将我们可以使用的8个字符带入enmu_table()函数,四位为一组进行组合,然后进行base64解码,生成了一个list,这个list的key值为所有acgtACGT组合能够生成的合法数字(再带两个注定要被遗弃的非法数字),value值为生成这个合法数字的‘acgtACGT’四位字符组合。

还记得之前提到的一个栗子吗?

aaaa解码生成了i��,那么在第一次生成时,list的key值为i,value值为‘aaaa’

经过所有的组合之后

我们拿到了26个字符,而这二十六个字符能重新组成的四位字符串为四的26次方~

循环上一步步骤,我们拿到了57个

再循环一次

我们拿到了64个,已经是全部的base64合法字符了

这时,我们手中有三个表,分别是一层一层地一位key(伴随着两个注定要被扔掉的垃圾字符)对应四位value。这时,我们可以把一句话密码中的字符分隔开,挨个去最后一个表(64个key)中寻找由第二次循环生成的57个字符组成的4位字符串。找到之后,再去第二个表中,将目前的这些字符,用第一次循环得到的26位字符串的4位组合替换掉,然后再去第一个表中,找到用最初始的8位字符组成的四位字符串替换;

总共替换了3次,又因为在把一句话进行输入的时候额外进行了一次base64encode,所以最后的payload为:

include(php://filter/convert.base64-decode/resource=php://filter/convert.base64-decode/resource=php://filter/convert.base64-decode/resource=php://filter/convert.base64-decode/resource= 【我们的acgtACGT组合】);

生成的payload,储存在了名字为'acgtACGT'的文件中,长得是这个样子:

特别长,我就不贴出来了

那个脚本中还要注意的一点为:

其中,如果长度不是4的倍数,会根据base64编码原理默认用等号补齐,凑够长度为4的倍数。

本文分享自微信公众号 - 信安之路(xazlsec),作者:ph0rse

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2017-10-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 实战|记一次授权的渗透测试

    前段时间收到小伙伴的求助,说是有一个站搞不了,让我看看能不能帮忙弄一下;刚好最近应急完了在看日志,看的有点烦,于是便接下了这个任务,增加点乐趣。

    信安之路
  • 2017-NSCTF-PWN

    这次比赛值得吐槽的地方很多,但是我要忍住,先讲正经的。 这次总结比赛的两道pwn,都是栈溢出类型的,比较简单。先放上题目链接:http://pan.baidu....

    信安之路
  • 重大福利!2018年白帽黑客最新干货资料,限时免费分享

    嗨 ~~各位未来的白帽们,今天为大家推荐一套体系化的安全课程,感谢大家长时间对我的支持现在作为福利赠送给大家。

    信安之路
  • Golang面向对象编程之构造函数【struct&new】

    构造函数是一种特殊的方法,主要用来在创建对象时初始化对象,即为对象成员变量赋初始值。特别的一个类可以有多个构造函数 ,可根据其参数个数的不同或参数类型的不同来区...

    Allen.Wu
  • SAP Hybris Enterprise Commerce的一些有用链接 - 保证持续更新

    Jerry Wang
  • iOS 仿微信相册选择照片imagePicker(Swift) 序号 预览缩略图

    ZYImagePickerAndBrower 是一个模仿微信相册多选照片的一个控件。注意了微信相册的一些细节,比如序号,最大选择之后照片变灰,浏览缩略图等等。

    ZY_FlyWay
  • 2017 NIPS 哪家强?我们统计了大会发文数量,谷歌和CMU稳居老大

    大数据文摘
  • 管理|管理就是管理别人,就是我指挥,你来干?

    黄小怪
  • “大数据+技术管理”:机器管理码农的时代来了!

    最近,我在各大技术沙龙和论坛上,积极倡导的一个理念:“大数据驱动的技术管理”,我相信这是技术管理的未来,犹如我在《技术管理之巅》一书中阐述的那样:通过汇集“软件...

    博文视点Broadview
  • 使用jsTree树形控件【1】入门

    部署环境使用压缩版的jsTree.min.js,如果是开发环境可以使用jsTree.js

    用户2936342

扫码关注云+社区

领取腾讯云代金券