PWN入门-格式化字符串
参考漏洞挖掘基础之格式化字符串-CSDN博客 格式化字符串函数介绍格式化字符串函数将第一个参数作为格式化字符串,根据其来解析之后的参数。一般来说格式化字符串在利用的时候主要分三个部分 格式化字符串函数 格式化字符串 后续参数格式化字符串函数输入函数:scanf输出函数: 格式化字符串基本格式如下%[parameter] [flag] [field width] [.precision] [length] type中括号中的属性是可选的,不需要一定都写上,比如%08x,他就只用到了其中的一部分。下面举几个比较重要的属性讲一下:parameter n$,获取格式化字符串中的指定参数flagfield width,输出的最小宽度precision,输出的最大长度length,输出的长度 hh,输出一个字节 h,输出一个双字节type d/i,有符号整数 u,无符号整数 x/X,16 进制 unsigned int 。x 使用小写字母;X 使用大写字母。如果指定了精度,则输出的数字不足时在左侧补 0。默认精度为 1。精度为 0 且值为 0,则输出为空。 o,8 进制 unsig...
PWN入门-基本ROP
基本ROP前言在了解栈溢出后,我们再从原理和方法两方面深入理解基本ROP 什么是ROPROP的全称为Return-oriented programming(返回导向编程),这是一种高级的内存攻击技术可以用来绕过现代操作系统的各种通用防御(比如内存不可执行和代码签名等)。通过上一篇文章栈溢出漏洞原理详解与利用,我们可以发现栈溢出的控制点是ret处,那么ROP的核心思想就是利用以ret结尾的指令序列把栈中的应该返回EIP的地址更改成我们需要的值,从而控制程序的执行流程。 为什么要ROP探究原因之前,我们先看一下什么是NX(DEP),NX即No-execute(不可执行)的意思,NX(DEP)的基本原理是将数据所在内存页标识为不可执行,当程序溢出成功转入shellcode时,程序会尝试在数据页面上执行指令,此时CPU就会抛出异常,而不是去执行恶意指令。随着NX保护的开启,以往直接向栈或者堆上直接注入代码的方式难以继续发挥效果。所以就有了各种绕过办法,rop就是一种。 ROP(Return Oriented Programming),其主要思想是在栈缓冲区溢出的基础上,利用程序中已有的小...
PWN基础-动态链接
什么动态链接(Dynamic linking)动态链接 是指在程序装载时通过 动态链接器 将程序所需的所有 动态链接库(Dynamic linking library) 装载至进程空间中( 程序按照模块拆分成各个相对独立的部分),当程序运行时才将他们链接在一起形成一个完整程序的过程。它诞生的最主要的原因是 静态链接 太过于浪费内存和磁盘的空间,并且现在的软件开发都是模块化开发,不同的模块都是由不同的厂家开发,在 静态链接 的情况下,一旦其中某一模块发生改变就会导致整个软件都需要重新编译,而通过 动态链接 的方式就推迟这个链接过程到了程序运行时进行。 优点1、节省内存、磁盘空间 例如磁盘中有两个程序,p1、p2,且他们两个都包含 lib.o 这个模块,在 静态链接 的情况下他们在链接输出可执行文件时都会包含 lib.o 这个模块,这就造成了磁盘空间的浪费。当这两个程序运行时,内存中同样也就包含了这两个相同的模块,这也就使得内存空间被浪费。当系统中包含大量类似 lib.o 这种被多个程序共享的模块时,也就会造成很大空间的浪费。在 动态链接 的情况下,运行 p1 ,当系统发现需要...
PWN基础-something_about_操作系统
操作系统signal机制signal 机制是类 unix 系统中进程之间相互传递信息的一种方法。一般,我们也称其为软中断信号,或者软中断。比如说,进程之间可以通过系统调用 kill 来发送软中断信号。一般分为三大步: kill并不是字面意思——杀死进程KILL功能描述:用于向任何进程组或进程发送信号 内核向某个进程发送signal机制,该进程会被暂时挂起,进入内核态 内核会为该进程保存相应的上下文,跳转到之前注册好的signal handler中处理signal signal返回 内核为进程恢复之前保留的上下文,恢复进程的执行内核在保存进程相应上下文阶段主要是将所有寄存器压入栈中,以及压入 signal 信息,以及指向 sigreturn 的系统调用地址。此时栈的结构如下图所示,我们称 ucontext 以及 siginfo 这一段为 Signal Frame。需要注意的是,这一部分是在用户进程的地址空间的。之后会跳转到注册过的 signal handler 中处理相应的 signal。因此,当 signal handler 执行完之后,就会执行 sigreturn 代码。对...
PWN基础-bss段、data段、text段、堆(heap)和栈(stack)
概念bss段bss段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域。bss段属于静态内存分配。 data段数据段(data segment)通常是指用来存放程序中已初始化的全局变量的一块内存区域。数据段属于静态内存分配。 text段代码段(code segment/text segment)通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读(某些架构也允许代码段为可写,即允许修改程序)。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。 堆(heap)堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)。 栈(stack)栈又称堆栈,是用户存放程序临时创建的局部变量,也就是说我们函数括弧“{}”中定义的变量(但不包括static声明的变量,static意味着在数据段中存放变量)。除此以外,在函数被调用时...
工具篇·ROPgadgets_and_One-gadget_RCE
ROPgadget是一种基于代码复用技术的攻击工具,它可以帮助攻击者在二进制文件中找到可利用的代码片段(即ROP链中的gadgets),从而构建出有效的攻击载荷。以下是ROPgadget的基本使用方法: 查找gadgets使用ROPgadget的基本命令格式是:ROPgadget --binary <文件名> --only <gadgets类型> 其中,<文件名>是你想要分析的二进制文件的路径,是你想要查找的gadgets的类型,比如“pop|ret”表示查找所有包含pop和ret指令的gadgets。 常用ROPgadget --binary example --string "/bin/sh"ROPgadget --binary example --only "int"例如,如果你想在名为example的二进制文件中查找所有的pop和ret gadgets,你可以使用以下命令:ROPgadget --binary example --only "pop|ret"jmp和retRO...
PWN基础-栈帧、C语言函数调用
在x86的计算机系统中,内存空间中的栈主要用于保存函数的参数,返回值,返回地址,本地变量等。一切的函数调用都要将不同的数据、地址压入或者弹出栈。因此,为了更好地理解函数的调用,我们需要先来看看栈是怎么工作的。 栈栈是一种计算机系统中的数据结构,它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。栈的操作常用操作: 进栈(PUSH):将一个数据放入栈里叫进栈(PUSH) 出栈(POP):将一个数据从栈里取出叫出栈(POP) 栈顶:常用寄存器ESP,ESP是栈指针寄存器,其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的栈顶。 栈底:常用寄存器EBP,EBP是基址指针寄存器,其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的底部。 上面例子中栈的生长方向是从高地址到低地址的,这是因为在下文讲的栈帧中,栈就是向下生长的,因此这里也用这种形式的栈。pop操作后,栈中的数据并没有被清空,只是该数据我们无法直接访问。 有了这些栈的基本知识,我们现在可以来看看在x86-32bit系统下,...
ELF文件保护机制
Linux ELF文件的保护主要有四种:Canary、NX、PIE、RELRO 1.CanaryStackCanary表示栈的报警保护。在函数返回值之前添加的一串随机数(不超过机器字长)(也叫做cookie),末位为/x00(提供了覆盖最后一字节输出泄露Canary的可能),如果出现缓冲区溢出攻击,覆盖内容覆盖到Canary处,就会改变原本该处的数值,当程序执行到此处时,会检查Canary值是否跟开始的值一样,如果不一样,程序会崩溃,从而达到保护返回地址的目的。 //GCC用法gcc -o test test.c // 默认情况下,不开启Canary保护gcc -fno-stack-protector -o test test.c //禁用栈保护gcc -fstack-protector -o test test.c //启用堆栈保护,不过只为局部变量中含有 char 数组的函数插入保护代码gcc -fstack-protector-all -o test test.c //启用堆栈保护,为所有函数插入保护代码-fno-stack-protector /-fstack-prote...
PWN基础-something_about_linux
文件权限rwxp分别指Linux虚拟内存权限的不同部分,具体含义如下 r:读权限(Read),表示可以读取内存区域的内容。 w:写权限(Write),表示可以修改内存区域的内容。 x:执行权限(Execute),表示可以执行内存区域中的代码。 p:私有权限(Private),表示该内存区域的内容在进程间是私有的,其他进程无法访问。系统调用号在Linux中,每个系统调用被赋予一个系统调用号。这样,通过独一无二的号就可以关联系统调用。当用户空间的进程执行一个系统调用的时候,这个系统调用号就用来指明到底是要执行哪个系统调用;进程不会提及系统调用的名称。 系统调用号相当重要,一旦分配就不能再又任何变更,否则编译好的应用程序就会崩溃。此外,如果一个系统调用被删除,它所占用的系统调用号也不允许被回收利用,否则,以前编译过的代码会调用这个系统调用,但事实上却调用的是另外一个系统调用。 Linux有一个“未实现”系统调用sys_ni_syscall(),它除了返回-ENOSYS外不做任何其他工作,这个错误号就是专门针对无效的系统调用而设的。虽然很罕见,但如果一个系统调用...
工具篇·objdump
objdump 命令是 GNU Binutils 二进制工具集的一员,用于查看目标文件或可执行文件的组成信息,以可读的形式打印二进制文件的内容。objdump [options] obj_file #[]表示可选,obj_file表示目标文件 常用objdump -T libc.so.6 |grep system objdump参数-a, --archive-headers 显示档案头信息,展示档案每一个成员的文件格式。效果等同于命令 ar -tv-b, --target=BFDNAME 指定目标码格式。这不是必须的,objdump 能自动识别许多格式,比如 objdump -b oasys -m vax -h fu.o 显示 fu.o 的头部摘要信息,明确指出该文件是 Vax 系统下用 Oasys 编译器生成的目标文件。objdump -i 将给出这里可以指定的目标码格式列表-C, --demangle[=STYLE] 目标文件中的符号解码成用户级名称。比如移除符号修饰时在变量与函数名前添加的下划线等。-d, --disassemble 反汇编目标文件,将机器指令反汇编成汇编代...
