第一届百度杯线上初赛 try to pwn
题目涉及:
伪造文件流(FILE Stream)
调整栈帧(stack pivot)
源码分析题目给的是一个32位静态编译的程序,保护开启情况如图:
程序的大概业务流程是打开名为输入名称+随机数文件的随机内容的文件,然后可以读取并输出这个文件的内容。
在 welcome 函数读入用户名时,没有限制输入长度,存在缓冲区溢出。
变量 x 位于 bss 段,文件指针 dword_80EFA00 也位于 bss 段,与 x 位置关系如图:
存储控制 x 输入内容,可以覆写文件指针 dword_80EFA00。程序最后调用了 fclose ,所以可以更改虚表指针来劫持控制流。
根据FILE结构,在 bss 段伪造出一个类似的结构,然后控制FILE里面的函数指针,执行任意代码。例如:执行fclose(fileexample)相当于调用 fileexample 这个文件(file)结构体虚表结构的 close 函数指针。
成功劫持文件流后,有一次调用机会(顺序执行一遍代码)。题目开启了 NX 保护,不能执行栈上 shellcode 。采取的解决办法是:先调整栈帧、扩充栈空间,使用 m ...
GOT和PLT | GOT and PLT for pwning
重定向二进制文件有两种类型:静态链接和动态链接。静态链接二进制文件包含运行需要的全部代码,不要加载外部库。动态链接没有包含全部代码,需要加载系统库来运行。
假设动态链接二进制文件加载(调用)系统库使用硬编码地址(绝对地址),那么系统库发生变化,二进制文件内的硬编码地址很可能全部改变。所以提出了一个重定向机制。
.got、.plt、.got.plt、链接器等是重定向的组成成分。
重定位表(relocations).got全局偏移表。用于记录在 ELF (二进制)文件中所用到的共享库中函数(或字符串)的绝对地址。
在程序刚开始运行时,GOT 表为空的,当函数第一次被调用时会动态解析符号的绝对地址然后转去执行,并将被解析符号的绝对地址记录在 GOT 中;第二次调用同一函数时,由于 GOT 中已经记录了其绝对地址,直接转去执行即可(不用重新解析)。(结合 .got.plt 理解)
.got.pltgot 表中的一部分。用于重定向请求到 .got 上的对应偏移或者返回 .plt 中激活链接器寻找函数在 系统库 中的地址。
开始运行是 .got.plt 不为空。当 got 表中没有函数的记录值时, ...
ASLR与PIE学习笔记
对于 ASLR 和 PIE 一直没有系统归纳,部分概念时常混淆,做个笔记记录一下。
ASLR 是什么?ASLR 是 Linux操作系统的功能选项,作用于程序(ELF)装入内存运行时。是一种针对缓冲区溢出的安全保护技术,通过对加载地址的随机化,防止攻击者直接定位攻击代码位置,到达阻止溢出攻击的一种技术。
开启、关闭ASLR查看当前系统ASLR的打开情况:
1sudo cat /proc/sys/kernel/randomize_va_space
ASLR 有三个安全等级:
0: ASLR 关闭
1:随机化栈基地址(stack)、共享库(.so\libraries)、mmap 基地址
2:在1基础上,增加随机化堆基地址(chunk)
PIE 是什么?PIE 是 gcc 编译器的功能选项,作用于程序(ELF)编译过程中。是一个针对代码段( .text )、数据段( .data )、未初始化全局变量段( .bss )等固定地址的一个防护技术,如果程序开启了PIE保护的话,在每次加载程序时都变换加载地址,从而不能通过 ROPgadget 等一些工具来帮助解题。
开启 PIE在使用 gcc ...
Canary学习笔记
Canary是什么由于栈溢出(stack overflow)而引发的攻击非常普遍也非常古老, 相应地一种叫做canary就出现在gcc/glibc里, 直到现在也作为系统安全的第一道防线存在。
canary 实现和设计思想都比较简单, 就是插入一个值, 在stack overflow发生的高危区域的栈空间尾部, 当函数返回之时检测canary的值是否经过了改变, 以此来判断stack/buffer overflow是否发生。
Canary与windows下的GS保护都是防止栈溢出的有效手段,几乎并不消耗系统资源,所以现在成了linux下保护机制的标配。
在GCC中使用Canary在GCC中使用以下参数设置Canary:
12345-fstack-protector 启用保护,不过只为局部变量中含有数组的函数插入保护-fstack-protector-all 启用保护,为所有函数插入保护-fstack-protector-strong-fstack-protector-explicit 只对有明确stack_protect attribute的函数开启保护-fno-stack-prote ...
Canary&PIE绕过 - bugku
题目涉及绕过canary、PIE保护,未了解两者知识,可到ctf wiki学习。
分析64位保护全开的程序
IDA打开,main 函数里面调用 vul 后,直接 return 0 退出。
vul 函数业务流程:读入 fpath 地址,输出 fpath 指向的内容,输入note。分析发现 thinking_note 写入时,大于定义的大小,存在栈溢出可能(程序开了canary保护),溢出点请看图。
write_note 部分(after line 33)处理逻辑有点奇怪:当第一次输入的 note 长度不是624时,要求重新输入一次长度最长为 0x270 的 note。这里可用来读取栈上canary值,而绕过canary保护。
leak canary第一次 note 栈溢出覆写 canary 最低位的\00,让 puts 顺利打印出 canary 的值。第二次 note 复原被破坏的 canary 值,并覆写 rip 完成 rop。这里第一次栈溢出不会破坏后面几个函数栈中的canary,因为栈是向低地址增长,后面函数栈在 vul栈 的前面(低地址),而栈溢出是向高地址覆写。
首先需 ...
GDB中x的使用语法
简介x用于在 gdb 中查看内存的内容
格式: x /nuf <addr>
说明
x 是 examine 的缩写
n 表示要显示的内存单元的个数
u 表示一个地址单元的长度:
b 表示单字节
h 表示双字节
w 表示四字节
g 表示八字节
f 表示显示方式, 可取如下值:
x 按十六进制格式显示变量
d 按十进制格式显示变量
u 按十进制格式显示无符号整型
o 按八进制格式显示变量
t 按二进制格式显示变量
a 按十六进制格式显示变量
i 指令地址格式
c 按字符格式显示变量
f 按浮点数格式显示变量
举例x /20gx buf:表示从内存地址buf读取内容,g 表示八字节,20 表示 20 个单位,x 按十六进制格式显示变量
x /3hu buf:表示从内存地址buf读取内容,h 表示以双字节为一个单位,3 表示三个单位,u 表示十进制格式显示无符号整型
广东外语外贸大学第三届网络安全大赛Writeup
官方WP:https://github.com/gwht/2019GWCTF/tree/master/
MISCmath是男人就下150层嘛,也就是答对150次计算题就返回 flag 嘛。这道题与 pwnable.kr 的一道题很像。题目有作答时间限制,所以用脚本跑吧。可能是人品问题,跑了很多次,最好的就是回答到 147 之后就链接断了(垃圾校园网?)。
最终EXP:
1234567891011121314from pwn import *context.log_level = 'debug'p = remote("183.129.189.60",10034)n = 0while n<150: p.recvuntil("Math problem: ") math = p.recvuntil("=")[:-2] p.sendline(str(eval(math))) sleep(1) n += 1else: p.sendl ...
第三届红帽杯线上赛Writeup
PWNthreeIDA打开之后,函数名都是sub_xxx,然后通过nc官方部署的程序(或本地在程序所在目录创建flag文件后),获得程序中会出现的字符串定位到了重要函数,我用的是字符串Maybe is good。
贴出来一下重要函数对应的内存地址:
函数名(已重命名)
内存地址
main
0x08048CA8
load_flag
0x080488C5
Maybe_is_good
0x0804897E
main_method
0x08048B5C
四者结构如图:
load_flag里面需要加载flag文件,如果没有就exit,也就是一开始无法本地打开原因。
Maybe_is_good 里面没有特别的,关键在main_method,先贴出完整代码(以重名部分函数&注释)
gdb调试:’very much’ 后输入 ‘aaa’,’tell me’ 后输入 ‘bbbbbbbbbbb······’。可以看到eax被写入了’aaa’,ecx被写入了’bbbbbbbbbbbbbbbbbbb····’
然后就是第22行代码,看不懂就查汇编,对应的汇编是cal ...
i春秋CTF答题赛(第三季)WriteUp
Re幸运数字分析 main 函数得出,只要输入的值经过加密转换之后等于H5wg_2g_MCif_T1ou_v7v7v,就会返回真正 flag 。加密算法只针对字符串中的英文字符。
分析中间加密部分可知,如果密文是大写字母,那么明文也是大写字母;小写字母同理。如果想检验的下面给出加密部分的 c 源码,自己加一个循环上去,看看就知道了。
1234567891011121314151617181920212223242526#include <stdio.h>#include <cstring>int main(){ char a_list[]= "N5cm_2m_SIol_Z1ua_b7b7b"; unsigned int v5=strlen(a_list)+1; int i; char v8; char v9; for(i=0;i<=v5-2;++i) { v8 = a_list[i]; if(v8>'Z'| ...
一步一步学ROP之Linux篇 - 学习笔记
课本地址:https://segmentfault.com/a/1190000005888964
笔记中所用到的程序&脚本下载地址:https://github.com/zhengmin1989/ROP_STEP_BY_STEP(原作者github仓库)
蒸米ROP学习笔记基础介绍ROP 的全称为 Return-oriented programming (返回导向编程)。是一种高级的内存攻击技术可以用来绕过现代操作系统的各种通用防御(比如内存不可执行和代码签名等)
x86篇level 1 - 栈上执行shellcode常见的程序流劫持就是栈溢出,格式化字符串攻击和堆溢出。最常见的防御方法有DEP(堆栈不可执行),ASLR(内存地址随机化),Stack Protector(栈保护)等。下面看看这题,程序流劫持。
初学阶段,先关闭Linux系统的ASLR保护:
123sudo -Secho 0 > /proc/sys/kernel/randomize_va_spaceexit
下载level1题目,放入到IDA分析,在vulnerable_function()中存在着栈 ...