初识64位下的ret2libc
写在前面:这种类型的题其实不好归纳是ret2text还是ret2libc,我这里按照ctfwiki的分类方法,将存在完整可执行的system(bin/sh)后门函数的题型归纳为ret2text,将需要利用基本的ROP技术的题型归纳位ret2libc 我们知道,在32位系统下,参数是直接被放在栈上的,不需要寄存器,因此只需要简单的覆盖到后门函数地址即可,但是在64位系统下则不一样了 64位系统的函数调用约定linux下64位系统采用System V AMD64调用约定,这里我会在阅读完CSAPP第三章后做更加详细的解释,下面是一些简要解释 参数传递方式 参数编号 寄存器 第 1 个 RDI 第 2 个 RSI 第 3 个 RDX 第 4 个 RCX 第 5 个 R8 第 6 个 R9 函数的前六个参数从右往左先被存入寄存器,再通过call调用函数 foo(1, 2, 3, 4, 5, 6, 7); mov rdi, 1mov rsi, 2mov rdx, 3mov rcx, 4mov r8, 5mov r9, 6push 7 #...
pwn前置基础大合集(更新中)
这篇博客主要是记录一下pwn的底层知识,主要知识来来自CSAPP,维基百科,b站网课等 操作系统1.发展历史1969 UNIX系统 肯尼斯·蓝·汤普森&丹尼斯·麦卡利斯泰尔·里奇奠定了现代操作系统,“一切皆文件” 1984 ios mac 苹果操作系统1985 window1.01991 linux 开源免费 2.LINUX下计算机的控制流程用户——应用软件——操作系统——驱动程序——硬件,从左到右逐层调用,其中操作系统包括系统软件和系统内核,内核负责管理它负责直接管理系统的进程、内存、设备驱动程序、文件和网络系统 这里我还是觉得CSAPP讲的非常好,于是结合CSAPP讲一下 刚才讲了,计算机的控制是逐层调用的,所以可以把操作系统看作是是应用程序和硬件之间的一层软件,应用程序必须通过操作系统访问处理器,主存,I/O设备等硬件 因此,操作系统的两大功能是确保上层的应用软件既能控制,又不滥用下层的硬件 操作系统通过进程、虚拟内存和文件来实现两大功能 进程 虚拟内存 见CSAPP第二章 文件 权限的体现:可读可写可执行 可读可写不可执行 可读不可写不可执行
CSAPP第二章札记(更新中)
信息的存储二进制起源悠久,可以追溯到埃及,印度巴拉巴拉,莱布尼茨进行了系统的发展,后由乔治·布尔进一步完善 相比十进制更容易表示,存储和传输,比如高电压表示1,低电压表示0 编码无符号编码 大于等于零的数补码 带正负号的整数浮点数 信息存储和十六进制表示法程序将内存看成一个很大的字节数组,称为虚拟内存内存的每一个字节由唯一的数字来标识,称为它的地址所有地址的集合,称为虚拟内存空间 在C语言中,我们可以通过指针引用数组元素,指针的值即某个对象的位置 1个字节(byte)或者说块,由8个位(bit)组成,一个位由0或1两种可能,最大是全部为1,即11111111;最小是0,即00000000。那么如果用十进制表示,最大值为255 字节作为计算机可寻址的最小单位,而并不是位 0x开头表示16进制(hex),具体的转换可以查询表格 字数据大小字长字(word),是CPU一次能处理的数据宽度单位 字长(Word Length),是字所用单位的大小,是CPU一次能处理字节(或位)的长度,也通常是一个寄存器的宽度。比如,32位系统可以一次处理字长为32位,即字4个字节的数据,64位系统可...
初识ret2syscall
系统调用操作系统的进程空间可分为用户空间和内核空间,它们需要不同的执行权限。其中系统调用运行在内核空间 在电脑中,系统调用(英语:system call),指运行在用户空间的程序向操作系统内核请求需要更高权限运行的服务 我们要知道,系统调用和库函数调用是两回事,系统调用由操作系统内核提供,运行于内核核心态,而普通的库函数调用由函数库或用户自己提供,运行于用户态。 应用程序调用系统调用的过程是: 1.把系统调用的编号存入EAX2.把函数参数存入其它通用寄存器3.触发 0x80 号中断(int 0x80) 在这里我以32位系统为例,一个经典的系统调用如下 123456mov eax,0xbmov ebx,["/bin/sh"]mov ecx,0mov edx,0int 0x80 查找对应的函数调用表,我们知道0xb对应的是execve指令,然后将bin/sh字符串写入寄存器ebx中,剩下几个寄存器为空。当我们触发int 0x80软中断后,CPU会切换到内核态,会先从eax读到函数调用号0xb,然后读到参数bin/sh字符串,这一顿操作下来...
初识格式化字符串(下)
在上一篇文章中,我们了解了如何利用格式化字符串漏洞实现任意读,主要靠%d,%s等格式化占位符泄露内存。接下来介绍一下如何实现任意写,即覆盖内存 开挂的%n%n是一个很牛的格式化占位符,和%d,%s等占位符不一样,它不输出字符,而是把已经成功输出的字符个数写入对应的整型指针参数所指的变量 换句话说,它会将已打印的字符个数输出至格式化参数对应的地址中 printf(“包含%n的格式字符串”, …, &变量名); 比较特殊的是,%n对应的参数必须是一个指向整数的指针 12345678910#include <stdio.h>int main() { int count; printf("Hello, world!%n\n", &count); printf("上面那行输出了 %d 个字符。\n", count); return 0;} 输出结果是:Hello, world!上面那行输出了 13 个字符。 也就是说%n统计了前面字符串的字符数,并且让count=...
初识格式化字符串(上)
深入理解格式化字符串要想理解格式化字符串的原理,我们必须要知道的一个问题是,printf调用时,它的第一个参数是什么,比如printf("%d %f\n", x, y);,它的一参是x吗? 让我们来看看printf的声明,int printf(const char *format, ...),没错,printf的一参是”%d %f\n”,即格式化字符串,这一点是很多同学都没有意识到的 我们必须要深刻理解的第二个问题是,什么是格式化字符串 格式化字符串是一些程序设计语言的输入/输出库中能将字符串参数转换为另一种形式输出的函数,它通过用于把随后对应的0个或多个函数参数转换为相应的格式输出;格式化字符串中转换说明以外的其它字符原样输出。我补充一点,这里的转换说明即格式化占位符。 (ps:不要因为长就不读了,反而要读得更仔细,通过学习pwn我认识到,越涉及到一个概念的本质,描述的文字就会越详细) 通俗的说,它就是包含格式化占位符的字符串 格式化字符串的工作原理我们平时使用printf时,格式化占位符是必须和后面的参数一一对应的,有多少个格式化占位符,就必...
写源代码一定要crtl+s保存啊啊啊啊啊
今天想在css里加点东西,但是每次都是原来的样子,搞了一晚上都不行,一直是原来的样子,发现是自己改完后没有保存 看一下左下角的时间,如果是now那就证明保存了 另外,如果hexo d上传失败,可以按f12在网页里改一下,重新hexo d一下就可以了,实在不行,多等一小儿就可以了 最后,感谢我磊哥再一次救我
梦开始的地方
我的博客搭建终于好了! 从今天起,我会在我的博客上分享我的wp,以及一些CTF的日常,希望和大家一起多多交流!
初识32位下的ret2libc
从ret2libc开始,我们将不再局限于像ret2text那样的栈溢出了,而是要开始接触另一个技术————ROP技术。什么是ROP技术我此前详细写了博客,在此不再赘述。 ret2libc就是拿程序里已有的函数库做文章,可以ret到的plt表,或或者ret到函数实际放置的got表处 egctfshow pwn入门39&41这两个题思路是一样的,区别是39有bin/sh,41有sh 首先这个题是存在明显栈溢出的,而system和sh是有但是不在一起的 12345678910111213141516171819from pwn import *context.terminal = ['tmux', 'splitw', '-h']#io = remote('pwn.challenge.ctf.show',28119)io = process("./pwn43")gdb.attach(io,'''break *0x08048420 ...
初识ROP和ret2shellcode
如果遇到NX保护,即栈堆不可执行的情况,我们shellcode将不能作为机器码被执行,那么我们就需要新的方法————ROP技术。 何为ROP?ROP的全称为返回导向编程。听名字十分牛的样子。ROP的核心在返回,即ret上。ret等价于pop EIP/RIP,call所调用的函数结束后,ret会把返回地址弹出栈,程序会跳到ret指向的地址。 出自《深入理解计算机系统(CSAPP)》第三章,要注意的一个问题是,国内外的计算机教材对于栈的画法是相反的,国外的教材更倾向于把栈倒过来画,即栈顶sp在下,栈底bp在上,栈向下增长(向下画)。不过并不影响实际的理解。 接下来我们需要知道什么是gadget。gadget在英语里的翻译是小玩意,小装置的意思,在二进制领域,gadget就是一小段程序里已经有的,通常以ret结尾的汇编代码,注意这里的关键词,“一小段”,“已有的”,“以ret结尾的”,重点是后两个词,这就意味着我们可以通过一段又一段的gadget不断ret到程序内的不同地方。就算开了NX不让我们执行shellcode,但是程序里已经有的指令总不能不让我们执行吧,这就是gad...













