记一次命令执行的奇妙冒险

0x01

起源:朋友在做某项目但是一直没有突破,听闻百京的师傅整到一个RCE成功整下该项目的一个子域名,并扔出了一张打了马赛克的,奈何实在研究无果但又对马赛克后面的内容非常感兴趣(属实宅男天性),打算探究一番马赛克的图,找出这个RCE.

可以看到只能知道POST的路径和execSync,再根据返回包已经pwd命令返回的路径判断使用的Nodejs的Express框架,奈何本人对Nodejs没有任何了解,于是看了几篇相关的文章,觉得还是要看一下POST数据的参数情况,采用了各种方法测试Fuzz数据得到的仍然是

这点我想了很久根据这个业务判断应该有个入口提交数据到这个接口于是拜托朋友再去看了看,功夫不负有心人,朋友很快发来了一个使用该系统入口提交数据的地方使得我们能知道到底POST提交了那些数据

数据包的内容

1
2
POST /chat HTTP/1.1
data={"action":"getSocketServiceAddress","accessId":"71817ab0-237b-11e7-a165-910f06e6de4f","sid":"50358800-8607-11ea-b421-85952c69bc13"}

去掉了一些不相关的信息可以看到参数有data并且内容为json字符串,将该参数填入我们的目标进行测试

可以看到返回了一个Url,说明该参数正确,观察json 字符串中的action值为getSocketServiceAddress,怀疑该字符串作为了构造函数类似的东西去调用了,于是尝试使用Javascript中的eval函数尝试,测试发现accessld与sid并无多大作用所以去除测试。

使用eval函数发现出现undefined is not a function这个提示

当在浏览器控制台直接使用eval函数不传入任何参数时

值为undefined证实确实可以调用eval函数,于是采用nodejs命令执行的老办法child_process结合Dnslog平台判断,为啥要结合dnslog平台呢? 主要是因为执行后无回显无法判断只好采用Dnslog来测试

成功收到请求

但是无法用回显的方式就比较难受

如图这种情况下实际whoami命令成功执行但是无回显,尝试ls /xxx时发现报错,结合之前的经历,是否能通过报错将数据带出来呢?

在Linux中反引号是可以用来执行命令的,如图:

当执行

1
`ls`

ls执行后的结果作为命令再次执行而该结果并不是命令导致报错,于是我们可以使用反引号来报错带出数据,说干就干

可以看到成功带出执行结果,但是这种方式并不完美,比如执行cat /etc/passwd这个命令的时候只会带出文件的前一部分内容并不完整,回顾刚才我们看师傅的那张马赛克图片可以看到是在头部执行命令,并返回结果,猜想应该是使用了类似java反序列化回显的原理,利用上下文环境获取指定的HTTP头信息然后将执行结果写入到返回包中,可能有朋友会说为啥不弹个shell出来,确实是Ok的,只不过如果考虑不能出网的环境的话命令执行后的回显确实是我们要考虑的一个问题,奈何本人才疏学浅只能继续学习啦

0x02

在文章的最后感谢这位提供马赛克图片的师傅让我确确实实学到许多,同时也感谢朋友提供的这一个案例让我受益匪浅,文笔较浮躁,措辞可能不严谨希望师傅们指出让我加以改正,也希望师傅们带带我。