首页 > 其他分享 >newstart 部分题解和pwn相关的学习

newstart 部分题解和pwn相关的学习

时间:2024-04-08 20:58:19浏览次数:16  
标签:newstart 函数 libc 题解 canary leave 地址 ebp pwn

做newstart的pwnpieee题的pie的学习
首先:对于pieee这道题

很简单的栈溢出,除了NX其他的保护都开了,然后呢在左边也发现了后门函数
相对偏移为0x1264(对于这里我们只用关心后三位,因为pie不会随机化地址的低12位,通俗点说就是我们十六进制地址的后三位)而一般而言后三位的地址能够确定我们的函数的地址所以 直接栈溢出加上后三位的地址就可以返回到system(bin/sh)

对于pie的学习还在更新中,主要是第一次遇到pie的题目 还有一种基本解法就是用printf泄露出地址然后找到pie的基地址来做

ret2libc先了解一下基本知识吧
got表:globle offset table 全局偏移量表,位于数据段,是一个每个条目是8字节地址的数组,用来存储外部函数在内存的确切地址。我们的最终目标就是拿到system函数的got表地址,同时知道libc的基地址的话即可找到system函数的真实地址。
plt表:procedure link table 程序链接表,位于代码段,是一个每个条目是16字节内容的数组,使得代码能够方便的访问共享的函数或者变量。可以理解为函数的入口地址,通过劫持返回地址为puts函数的plt表地址,即可执行puts函数。
可执行的二进制文件里面保存的是PLT表的地址,对应 PLT 地址指向的是 GOT 的地址,GOT 表指向的就是 glibc 中的地址那我们可以发现,在这里面想要通过 plt 表获取函数的地址,首先要保证 got 表已经获取了正确的地址(即最靠右的两个箭头已经建立),但是在一开始(尚未发生函数调用时)就进行所有函数的重定位是比较麻烦的,为此,linux 引入了延迟绑定机制。
那么什么是延迟绑定机制:只有动态库libc中的函数在被调用时,才会进行地址解析和重定位工作,也就是说,只有函数发生调用之后,上图中最右侧的两个箭头才建立完成,我们才能够通过got表读取到libc中的函数。至于具体过程相对复杂,这里引用大佬博主的图片简要介绍,当程序第一次执行某个函数A时,发生的过程如下:
在可执行二进制程序调用函数A时,会先找到函数A对应的PLT表,PLT表中第一行指令则是找到函数A对应的GOT表。此时由于是程序第一次调用A,GOT表还未更新(就是图一中最右边俩箭头还没有建立),会先去公共PLT进行一番操作查找函数A的位置,找到A的位置后再更新A的GOT表,并调用函数A。当第二次执行函数A时,发生的流程就很简单了,如下图:

此时A的GOT表已经更新,可以直接在GOT表中找到其在内存中的位置并直接调用。
用通俗一点的话来说就是,第一次调用函数的时候,会首先在调用其plt表象的函数,然后由plt让got去找到这个函数,但是此时这个函数没有被调用过,所以got表里面没有存有这个函数,相当于没有找到这个函数,就会返回plt让自己去找,plt就找到了,存入got表里面,之后的调用,那么got表里面就会有了a函数的地址了,此时就可以直接到got表然后执行a函数了。

例题:newstartweek2-ret2libc 首先打开ida分析一下代码,
发现这里的read函数存在栈溢出
发现只开了NX 不能用shellcode,用shift+f12发现没有system和bin/sh 那么就可以用libc的攻击手法
这是很简单的libc的题目,exp在下
这道题没有给libc的动态连接库,所以有俩种方式可以获得libc的基地址,但是由于我的libsearcher库没有找到,所以只能用网上的libc-database,基本思路就是调用put函数泄露put函数的真实地址,然后去libc-database找到libc的偏移地址之后就能够获取到了libc的基地址了,然后就能够进行攻击了。
这里的libc.dump就是用libcsearch来做的

canary
Canary是一种针对栈溢出攻击的防护手段,其基本原理是从内存中某处(一般是 fs: 0x28 处)复制一个随机数 canary ,该随机数会在创建栈帧时紧跟着 rbp 入栈,如下图所示:
在函数退栈返回前,程序会比对栈上的 canary副本 和原始的 canary ,若二者不同,则说明发生了栈溢出,这时程序会直接崩溃。就相当于我们不能够直接进行栈溢出的操作。
canary的特点::Canary 所生成的随机数有一个非常重要的特点:随机数的第一个字节必然是 0x00 。如此设计的主要目的是实现字符串截断,以避免随机数被泄露。举个例子
如图,长度为 8字节 的字符串 str 就在随机数 canary 的正下方,某函数试图用 printf("%s", str) 输出字符串 str 。这时,若随机数 canary 的首字节不为 0x00 , printf 在输出了字符串 str 后,由于没有遇到 0x00 ,故会继续输出,进而使得 canary 被泄露。
canary绕过最常见的方法有两种:
1.逐字节爆破以获取随机数。(由于现在本人也不太会,所以不做涉及)
2.通过printf函数来泄露出canary的地址
例题:new start week2 canary:
首先checksec一下
然后用ida打开分析

发现有canary保护,不能够简单的栈溢出了 有nx也不能用shellcode relro也在我们不能修改got表,然后发现有栈溢出的漏洞还有格式化字符串漏洞,此时我们就可以用格式化字符串漏洞来泄露出canary的地址来进行我们的攻击。那么我们该怎么泄露出canary的地址呢?
我们先随意输入几个%p 发现在第六个位置会有我们输入进去的aaaa,在下面的栈区也发现了canary距离我们输入进去的地方的偏移为5,所以距离print的偏移就为11,canary的地址就存放在这里
ok找到了canary的地址,也有后门函数,直接进行攻击第一次payload泄露出canary的地址,然后payload2的构成是40的溢出数据然后是canary的地址,记住,64位的需要进行一次空转,栈对齐,然后就是backdoor的地址,就可以获取shell了。解释一下为什么要空转:因为ubuntu18及以上在调用system函数的时候会先进行一个检测,如果此时的栈没有16字节对齐的话,就会强行把程序crash掉,所以需要栈对齐。
栈迁移
我们为什么要使用栈迁移这样的攻击方式?就是因为可溢出的长度不够用,也就是说我们要么是没办法溢出到返回地址只能溢出覆盖ebp,要么是刚好溢出覆盖了返回地址但是受payload长度限制,没办法把参数给写到返回地址后面。总之呢,就是能够溢出的长度不够,没办法写我们的攻击脚本,所以我们才需要换一个地方写我们的攻击脚本。
那么下面我们理解一下栈迁移的核心,就在于两次的leave;ret指令上面,然后我们在理解一下leave和ret的指令
leave:就是mov esp ebp;pop 解释一下第一条指令就是先将ebp赋给esp,此时esp与ebp位于了一个地址,你可以现在把它们指向的那个地址,即当成栈顶又可以当成是栈底。然后pop ebp,将栈顶的内容弹入ebp(此时栈顶的内容也就是ebp的内容,也就是说现在把ebp的内容赋给了ebp)。因为esp要时刻指向栈顶,既然栈顶的内容都弹走了,那么esp自然要往下挪一个内存单元(注意栈的地址,此时向下地址是减小的)。
ret就是​pop eip,这个指令就是把栈顶的内容弹进了eip(就是下一条指令执行的地址)
我们来分析一下简单的main上的栈迁移的攻击方式:
首先利用溢出把ebp的内容给修改掉(修改成我们要迁移的那个地址),并且把返回地址填充成leave;ret指令的地址(因为我们需要两次leave;ret)此时main函数准备结束,开始执行第一个leave,此时mov esp ebp让两个指针处于同一位置,现在还是正常运行,接着执行pop ebp就出现了异常,因为此时ebp的内容被修改成了要迁移的地址,因此执行了pop ebp,ebp并没有弹到它本应该去的地方(正常情况下,ebp里装的内容,就是它接下来执行pop ebp要去的地方),而是弹到了我们修改的那个迁移后的地址,接着执行了pop eip,eip里放的又是leave的地址(因为此时是把返回地址弹给eip,这个返回地址,我们先给覆盖成leave;ret的地址。你可能会问,如果这个返回地址不放成leave;ret的地址,行不行?很明显是不行的,因为我们想要实现栈迁移,就必须执行两个leave;ret,main函数正常结束,只有一个level;ret,因此我们在这里必须要它的返回地址写成leave;ret地址,以来进行第二次leave;ret),结果又执行了leave(现在执行第二个leave),此时才是到了栈迁移的核心部分,mov esp ebp,ebp赋给了esp,此时esp挪到了ebp的位置,可你别忘了,现在的ebp已经被修改到了我们迁移后的地址,因此现在esp也到了迁移后的地址,接着pop ebp,把这个栈顶的内容弹给ebp,esp指向了下一个内存单元,这就完成了我们的栈迁移了,然后就可以构造我们的payload了。
例题:newstart week2 stackmigration:
首先也是checksec加ida分析源码

没开什么保护,然后就是分析有俩个read读入的地方,然后第一个地方只能读入8个数据,所以我们不能进行栈溢出,然后就是第二个read函数的时候,溢出数据是0x10,很小,不能够构造出我们的payload,所以这里可以进行栈迁移。但是在shift+f12中并没有发现system和bin/sh的字符,所以这道题还需要我们用libc泄露来做。ok大致思路就是这样,exp如下:

解释一下:在第一个read我们可以泄露出我们的buf的地址,在第二个printf的函数这里会给出我们buf的地址,然后v2又在buf的上面8个字节,所以这里我们需要在我们泄露出来的buf上加上8.还有一个值得注意的就是为什么我们的每个payload最前都需要加上8个字节,因为这里是64位,然后执行了俩次leave ret是 esp会往上-8个字节。
因为我们其余思路就和ret2libc一样了,但是需要注意,第二次时v2的地址和第一次不一样了 所以需要我们再次泄露出来!
感想:真的理解到了很多东西,这个newstart的题目出的挺好的,但是我需要学的还有很多,还应该好好把这个栈的内容巩固之后再去学习堆,压力一下子就来了,新手的第一次博客,写的不好还请指出!

标签:newstart,函数,libc,题解,canary,leave,地址,ebp,pwn
From: https://www.cnblogs.com/qu1st/p/18111125

相关文章

  • 【题解】洛谷马的遍历
    马的遍历方法:广度优先搜索源代码如下#include<iostream>#include<queue>#include<cstdio>#include<cstring>usingnamespacestd;structcoord{//结构体定义x,y坐标intx,y;};queue<coord>Q;intans[500][500];//-1代表未访问intwalk[8......
  • Leetcode 第 390 场周赛题解
    Leetcode第390场周赛题解Leetcode第390场周赛题解题目1:3090.每个字符最多出现两次的最长子字符串思路代码复杂度分析题目2:3091.执行操作使数据元素之和大于等于K思路代码复杂度分析题目3:3092.最高频率的ID思路代码复杂度分析题目4:3093.最长公共后缀查询思......
  • CF1361E James and the Chase 题解
    Description给定一个有\(n\)个点\(m\)条边的有向强连通图。称一个点是好的当且仅当它到其他点都有且只有一条简单路径。如果好的点至少有\(20\%\)则输出所有好的点,否则输出-1。单个测试点内有多组数据。\(1\leqT\leq2\times10^3,1\leqn\leq10^5,1\leqm\leq2\time......
  • 任务处理【华为OD机试】(JAVA&Python&C++&JS题解)
    一.题目-任务处理在某个项目中有多个任务(用tasks数组表示)需要您进行处理,其中tasks[i]=[si,ei],你可以在si<=day<=ei中的任意一天处理该任务。请返回你可以处理的最大任务数。注:一天可以完成一个任务的处理。输入描述:第一行为任务数量n,1<=n<=100000。后......
  • 跳马【华为OD机试】(JAVA&Python&C++&JS题解)
    一.题目马是象棋(包括中国象棋和国际象棋)中的棋子,走法是每步直一格再斜一格,即先横着或直着走一格,然后再斜着走一个对角线,可进可退,可越过河界,俗称“马走‘日’字。给顶m行n列的棋盘(网格图),棋盘上只有有棋子象棋中的棋子“马”,并且每个棋子有等级之分,等级为k的马可以跳1~k......
  • AT_abc348_e 的题解
    (一)感觉D>E。考虑换根DP,把节点\(1\)当作一开始的根节点。先搜一遍,把\(f(1)\)算出。当将计算的节点从父结点往子节点转移时,每个节点到计算的节点的距离要么\(-1\)要么\(+1\),取决于是否在子节点的子树内。可以提前处理字数内\(C\)的值的和,来计算\(f\)的变化量。(二)......
  • CF1292B 题解
    Aroma'sSeatch题意简述题目链接。一个二维平面内有无限个点,从\(0\)开始编号,编号为\(0\)的点的坐标为\((x_{0},y_{0})\)。对于一个编号为\(i(i>0)\)的点,它的坐标为\((a_{x}\cdotx_{i-1}+b_{x},a_y\cdoty_{i-1}+b_{y})\)。Aroma最开始在点\((x_s,y_s)\)处,她每......
  • CF1744F MEX vs MED 题解
    题目传送门题目大意给定一个数列,求满足\(\operatorname{mex}(a_l\sima_r)>\operatorname{med}(a_l\sima_r)\)的区间\([l,r]\)的个数。解题思路记\(p_i\)为\(i\)出现的位置。我们可以枚举\(d\),先确定\(\operatorname{mex}(a_l\sima_r)>d\)的区间。由于数列是\(......
  • CF1951E No Palindromes 题解
    题目大意给出一个字符串sss,要求将sss分为若干个非回文子串,输出......
  • 谢启鸿高等代数第四版习题7.7部分习题解析part2.以及部分第7章复习题
    7.7部分定理:以为特征值的K阶若当块个数为11.设n阶矩阵A的特征值全为1,求证:对任意的正整数K,与A相似。证明:=(易证故此处不再证明)而且的特征值全为1。的特征值为1的k阶若当块的个数为接下来只需证明相似于即可;即证明两者有相同的约当标准型.由书上7.8节的数学归纳可以知道......