BeanShell RCE 排坑
最近在测试过程中遇到了NC BeanShell RCE漏洞,网络上大部分都是用BeanShell自带的
exec
函数执行反弹shell命令,但无法直接执行反弹shell。
寻根溯源
exec
函数在BeanShell中定义如下
参数是一个 String
类型,并且根据下面的描述是调用了 Runtime.getRuntime().exec()
。
搞过Java命令执行的都知道,Java如果要执行命令不能向python之类的直接通过字符串执行命令,需要将命令转化为 String[]
类型
所以网络上大部分的poc/exp都是只能执行部分命令,无法执行带有各种管道、参数的命令。
由于在cmd与bash中各种命令的实现不同,比如在Linux中id
是一个elf程序,而echo
则更像是一种宏。且beanshell中原本exec定义是传入字符串,但具体的实现方法Runtime.getRuntime.exec允许传入字符串数组重载。所以我们只需要将exec重新实现一遍即可
解决方法
解决方法也非常简单,既然这里可以使用beanshell script进行命令执行,那我们直接自己用Runtime exec构造命令执行代码就完事了
1 | String[] cmd = new String[] {"sh", "-c", "whoami"} |
用了这个payload发现命令可以执行了,但是网站没有回显,写成脚本也没有办法直接获取一些命令的结果,就还得通过生成文件再查看结果,太丑陋了!!
就想到如果我知道 exec
方法的实现过程,我再根据这个实现过程去实现刚才的payload就可以完成结果回显。
直接去找beanshell项目,查找 exec
方法
1 | /** |
Exp
1 | exec( String[] arg ) |