tricks
[TOC]
做题步骤
- 第一步先checksec(checksec至关重要,因为如果partial rello那么很可能会打got,然后no pie这种很可能最终就是栈溢出)和看libc版本,第二步查看有无直接后门,第三步看有无格式化字符串漏洞,第四步看有无整数溢出,第五步看看能否打syscall或者srop,最后一步再正常打看怎么打
栈溢出
- strcat会拼接字符串,他会在指针指向位置后的第一个\x00位置处继续写入,这里的方法是将canary末尾的\x00覆盖,然后strcat会从canary之后的\x00,也就是ebp处的位置开始写入,接这样实现了绕过canary去写入返回地址,然后strcpy重新写入canary末尾的\x00
- 不要放过任何细节,包括init函数,username,不要放过任何一个泄露函数
- 用environ环境变量泄露栈,由于远程的flag存放在栈中,所以可以加偏移循环爆破flag
- 有时候ida反汇编会是read(0, comment, 0x8CuLL);这样的,但是仔细看汇编代码是这样的,需要引起注意
- 无法泄露栈地址,同时下一条指令又是leave;ret 可以考虑partial overwrite rbp的值
- 静态链接的题一般都打ret2syscall,在bss读入/bin/sh\x00
- 对于每个写操作都要多留意,是否会有任意地址写(有时候写一个字节也很重要)
- 选择改close末位字节为syscall,利用read函数控制rax寄存器的值
格式化字符串
- 禁用了$,但是形如%c%c中的第二%c也是会匹配第二个参数的,这样叠加一下就可以控制任意地址写了
命令执行绕过
- \n,\t都是转移字符,read的时候不会当作两个字符,没有’',必须用转义字符\。同时注意与/区分,’/‘字符是存在的。
- echo ‘$(c"at" flag)‘命令会执行cat flag,因为括号中的内容会被当作命令进行执行。使用双引号和单引号,隔离拼接关键字来进行绕过。c’a’t flag,c"at" flag
- \符号,会将两字符串拼成一个字符串来使用。c\at flag,cat fl\ag
- 在bash环境中,有些的特殊变量都是为空的.可以夹着关键字中绕过,如fla$*g可以绕过对flag的过滤
- sprintf 会被 \x00 截断,可以用base64 去除 \x00用;作为一个分隔符,相当于执行echo “rop” | base64 -d > /tmp/result.txt
- \n 和 ; 在 system() 函数中都能够用来分隔多个命令,但它们之间存在一些区别:
- 表示方式不同: \n 是一个转义字符,表示换行符。 ; 是一个分隔符,用于在命令行中分隔多个命令。
- 作用范围不同: \n 可以在命令字符串中的任何位置使用,用于将命令字符串中的文本换行显示。 ; 用于分隔多个完整的命令,指示 shell 在一个命令执行完毕后立即执行下一个命令。
- 目录穿越,合理地运用../
- 通配符(星号):匹配零个或多个字符。例如,*.txt匹配所有以.txt结尾的文件名。cat fl*就可以读取flag
- 空格是默认用来分隔命令和参数的,如果禁用了空格,可以用\t代替。如果是普通字符串,可以不用引号;但如果有转义字符,特别是空格,必须用引号
- 双引号:解析变量值,单引号:不解析变量值,嵌套问题:看谁在最外面,反引号:解析命令 博客1 博客2
- 命令行参数中双引号和单引号都要对应闭合
在这个例子中,-u -p后面的’…‘都是对应的参数设置,所以"…“中的内容被解析为一个命令
在这个里面-u的参数为’’,也就是为空;第二个命令是cat\tfl*;最后一个命令单引号没有闭合我们也不用管了(这里报了格式错误),因为我们只要执行cat\tfl*就可以了。这就是利用单引号的绕过
堆
- 泄露stack打栈溢出,有时候libc2.35打IO真的很麻烦,能打栈溢出就打栈溢出
- 使用 scanf 获取内容时,如果 输入字符串比较长会调用 malloc 来分配内存。因此可以调用malloc consolidate函数实现合并fastchunks到unsorted bin进而泄露libc
- 打house系列时,断点可以打在_IO_wfile_seekoff _IO_switch_to_wget_mode,这种链中的函数中
- 堆题不要忘记了最基本的整数溢出,因为有时候根本不检查idx是否为负数
- go的堆题经常会莫名其妙在堆上申请空间,因此要注意一开始堆块的情况,以及像是protobuf这种msg的size为多少,实际上就会malloc(size),同时msg的值会在堆上
其他
- __libc_start_call_main+56可以重新返回main
- 关闭了标准输出和标准错误,已经拿到了shell,exec 1>&0,将标准输出重定向到标准输入来cat flag
- 关闭了标准输入和标准输出,执行system(“sh flag”),这样可以在标准错误拿到flag
- 最近打web pwn和llvm pass这种题发现整数溢出特别多,一般都是因为char型范围是-127~128,因此超过128就会从-127开始往上计数,造成负数溢出
- chmod rwx分别是4,2,1 但是mmap或者myprotect的有所不同,具体如下
PROT_NONE:0,表示无权限。
PROT_READ:1,表示可读权限。
PROT_WRITE:2,表示可写权限。
PROT_EXEC:4,表示可执行权限。
PROT_SEM:8,表示用于信号量的保护。
PROT_GROWSDOWN:0x01000000,表示内存段向下扩展的方向。
PROT_GROWSUP:0x02000000,表示内存段向上扩展的方向。
- 最近遇到许多可以让libc里面写值的题目。D3CTF有个题是通过/proc/self/mem往libc的可执行段写值控制流程;HNCTF是通过写libc的bss段的内容打stdout来泄露最后打rop