ret2syscall
ret2syscall一、checksec
32位程序,开启了NX(栈不可执行)保护。
二、ida查看C代码123456789101112131415161718#include <stdio.h>#include <stdlib.h>char *shell = "/bin/sh";int main(void){ setvbuf(stdout, 0LL, 2, 0LL); setvbuf(stdin, 0LL, 1, 0LL); char buf[100]; printf("This time, no system() and NO SHELLCODE!!!\n"); printf("What do you plan to do?\n"); gets(buf); return 0;}
存在gets函数栈溢出漏洞
三、溢出思路因为开启了栈不可执行保护,所以不可以将自己写的shellcode部署到内存中。由于C代码中也没有系统函数,也 ...
unsortedbin的unlink
unsortedbin的unlink参考资料123https://blog.csdn.net/qq_41202237/article/details/108481889holk大佬的文章写的非常nice,对初学unlink的很友好,本文很多都是参考的holk大佬的思路的https://www.yuque.com/cyberangel/rg9gdm/yki7ng
UnlinkUnlink是什么简单翻译一下就是断开链接
先简单提出两个点:
unlink是什么
什么时候执行了unlink
这两个问题在你初识unlink的时候估计也会想到,翻看libc源码,在2.23版本中在malloc.c中找到了unlink。unlink其实是libc中定义的一个宏,定义如下:
12345678910111213141516171819202122232425262728293031#define unlink(AV, P, BK, FD) { FD = P->fd; ...
堆-UAF(Use After Free)
堆-UAF(Use After Free)参考资料12https://www.yuque.com/cyberangel/rfg9gdm/lhsz9z#79UVlhttps://blog.csdn.net/qq_41696518/article/details/125878437
原理我们将Use After Free翻译过来就是释放后使用:当一个指针所指向的指针块被释放掉后可以被再次使用,但是这是有要求的,不妨将所有情况列举出来:
chunk被释放之后,其对应的指针未被设置成NULL,如果再次使用它,程序就会崩溃。
chunk被释放之后,其对应的的指针未被设置为NULL,但是它在下一次使用之前没有代码对这块内存进行修改,那么再次使用这个指针时程序很有可能正常运转。
chunk被释放之后,其对应的指针没有被设置为NULL,但是在它下一次使用之前,有代码对这块内存呢进行了修改,那么当程序再次使用这块内存时,就很有可能会出现奇怪的问题。
在堆中User After Free一般指的是后两种漏洞,我们一般称为被释放后没有被设置为NULl的内存指针为dangling pointer(悬空指 ...
堆中的off-by-one
堆中的off-by-one参考资料
123https://hollk.blog.csdn.net/article/details/108116618https://www.yuque.com/cyberangel/rg9gdm/gg4bw4#pry13https://blog.csdn.net/song_lee/article/details/103565826
简介及定义off-by-one这项技术不仅适合用于堆,而且适用于栈。但是在CTF中最常见的还是在堆中的应用。严格来说off-by-one是一种特殊的溢出漏洞,当程序在缓冲区写入并溢出的时候,写入的字节数超过了这个缓冲区本身所申请的字节数并且只越界了一个字节。
漏洞原理off-by-one这种漏洞的形成和整数溢出很相似,往往都是由于对边界的检查不够严谨,当然也不排除和写入的size正好就多了一个字节的情况,边界验证不严谨通常有两种情况:
使用循环语句向堆块写入数据时,循环的次数设置错误,导致多写了一个字节,这篇文章讲的就是这个漏洞
堆字符串长度判断有误
举例讲解原理1、循环边界不严谨:
123456789101112131 ...
堆入门概述
堆入门概述12345参考资料;https://www.yuque.com/cyberangel/rg9gdm/uhdudzhttps://www.anquanke.com/post/id/163971#h3-9https://zhuanlan.zhihu.com/p/374431199《CTF竞赛权威指南pwn篇》
什么是堆?堆和栈不同,堆是(由操作系统内核或者堆管理器)动态分配的,是程序虚拟内存中由低地址到高地址增长的线性区域。一般只有当用户向操作系统申请内存时,这片区域才会被内核分配出来,并且出于效率和页对齐的考虑。通常会分配相当大的连续内存。程序再次申请时便会从这片内存中分配,直到堆空间不能满足时才会再次增长。
先看看堆在虚拟内存中的位置
堆的属性是可读可写的,大小通过brk()或sbrk()函数进行控制。如上图所示,在堆未初始化时,Program break指向BSS段的末尾,通过调用brk()和sbrk()来移动program_break使得堆增长。在堆初始化时,如果开启了ASLR,则堆的起始地址start_brk会在BSS段之后的随机位移处,反之则start_brk ...
整数溢出(stack)
整数溢出(stack)整数溢出的介绍首先回顾一下C语言中的整形的数据分类。
按数据类型分类主要分三类:短整形(short)、整形(int)、长整形(long)
按符号分类:有符号,无符号
并且每种数据类型都有自己的大小范围:
类型
字节
范围
short int
2byte(word)
032767(00x7fff)-32768-1(0x80000xffff)
unsigned short int
2byte(word)
065535(00xffff)
int
4byte(dword)
02147483647(00x7fffffff)-2147483648-1(0x800000000xffffffff)
unsigned int
4byte(dword)
04294967295(00xffffffff)
long int
8byte(qword)
正:00x7fffffffffffffff负:0x80000000000000000xffffffffffffffff
unsigned long int
8byte(qword)
0~0xffffffff ...
栈溢出-Stack smash
栈溢出-Stack smash原理Stack-smash简单来说就是绕过Canary保护机制的技术。当程序开启了Canary保护后,会在缓冲区中加入一个Canary值,如果这个Canary值在程序运行中被改变了,会触发__stack_chk_fail函数。这个技术的关键就在于
这个函数会打印信息,我们可以通过这个函数打印我们想要的信息。打印的是argv[0]指针所指向的字符串。正常情况下指向程序名。
__stack_chk_fail函数介绍1234567891011void __attribute__ ((noreturn)) __stack_chk_fail (void){ __fortify_fail ("stack smashing detected");}void __attribute__ ((noreturn)) internal_function __fortify_fail (const char *msg){ /* The loop is added only to keep gcc happy. */ whi ...
栈溢出技巧-Stack pivoting(栈翻转/jmp esp跳板)
栈溢出技巧-Stack pivoting(栈翻转/jmp esp跳板)12参考资料:https://www.yuque.com/cyberangel/rg9gdm/rg6g4g
1、介绍首先介绍一下Stack pivoting的含义:
该技巧就是劫持栈指针指向攻击者所能控制的内存处,然后再在相应的位置进行ROP。一般来说,我们可能在以下情况需要使用 stack pivoting:
可以控制的栈溢出字节数较少,难以构造较长的ROP链
开启了PIE保护,栈地址未知,我们可以将栈劫持到已知的区域。
其它漏洞难以利用,我们需要进行转换,比如说将栈劫持到堆空间,从而在堆上写ROP及进行堆漏洞利用。
此外,利用stack pivoting有以下几个要求:
可以控制程序执行流
可以控制sp指针。一般来说,控制栈指针会使用ROP,常见的控制栈指针的gadgets一般是
1pop rsp/esp
还有一些其它的姿势。比如说libc_csu_init中的gadgets,我们通过偏移就可以得到控制rsp指针。
此外,还有更加高级的fake frame。
存在可以控制内容的内存, ...
栈迁移
栈迁移一、前言在只能够控制ebp的情况下,我们怎么才能控制eip去拿到我们的shell呢
以32位程序为例子,在使用call这个指令时,进入函数的时候,会进行一系列栈操作:
123push eip+4; //保存返回地址push ebp; //保存前栈帧的栈底指针mov ebp,esp;
保护现场,避免执行完函数后堆栈不平衡以及找不到之前的入口。
在函数的结尾会进行一系列操作来还原现场leave;ret;
leave就相当于进入函数栈操作的逆过程。
12leave == mov esp,ebp;pop ebp;ret == pop eip //弹出栈顶数据给eip寄存器
二、什么是栈迁移所以栈迁移这种技术,可以通过控制ebp的值,借助leave指令,间接控制esp的值。
核心思想:将栈的esp和ebp转移到一个输入不受长度限制且可控制的地址处,通常是bss段地址!(在栈中也可以)
最后ret的时候,如果我们能控制得了栈顶esp的指向,就相当于控制了程序执行流。
简单一句话就是控制esp指针的指向。
举个例子:
第一步:首先确定缓冲区变量溢出时,至少 ...
格式化字符串漏洞
格式化字符串漏洞一、X86二、格式化字符串漏洞原理 格式化串漏洞和普通的栈溢出有相似之处,但是还是有所不用。都是利用程序中存在的漏洞劫持程序流程的。
a、什么是格式化字符串? 像printf()、fprintf()等一系列的函数可以按照一定的格式将数据进行输出,举个例子:
1printf("Hello %s","World");
执行完这个函数会返回字符串:Hello World
这个printf函数的第一个参数就是格式化字符串,它用来告诉程序将数据以什么格式输出。
printf()函数的一般形式为:printf(“format”,输出列表),关注点在format上,它的结构是:
%[ 标志 ] [ 输出最小宽度] [.精度] [长度] 类型,其中跟格式化字符串漏洞有关系的主要有下列几点:
1、输出最小宽度:用十进制整数来表示输出的最少位数。若实际位数多余定义的宽度,则按实际位数输出,若实际位数少于定义的宽度则补空格或0.
比如:
12printf("%2d",123); //结果为123pr ...