ret2dlresolve及例题
ret2dlresolveret2dlresolve主要是利用函数进行plt表进行动态链接的时候,通过一系列的跳转才能找到got表,就是利用的这个过程进行漏洞攻击
_dl_runtime_resolve函数调用参考:[原创]ROP高级用法之ret2_dl_runtime_resolve-二进制漏洞-看雪-安全社区|安全招聘|kanxue.com
首先用link_map访问.dynamic,分别取出.dynstr、 .dynsym、 .rel.plt的地址
.dynamic的地址加0x44的位置是.dynstr.dynamic的地址加0x4c的位置是.dynsym.dynamic的地址加0x84的位置是.rel.plt
.rel.plt + 参数reloc_index,求出当前函数的重定位表项Elf32_Rel的指针,记作rel
rel->r_info >> 8作为.dynsym的下标,求出当前函数的符号表项Elf32_Sym的指针,记作sym
.dynstr + sym->st_name得出符号名字符串指针
在动态链接库查找这个函数的地址,并且把地址赋值给* ...
pwn漏洞修复
pwn patch栈read 32
在push 18h处右击 点击Assemble 将18h改成正常的无溢出的长度就好了
read 6464位的也是同理
找到溢出的函数将长度改合理
格式化字符串32法一 :若有puts的plt把printf改成puts即可
法二:需要改一个函数无用的函数改成write函数
12345678910.text:080485C0 win proc near.text:080485C0 ; __unwind {.text:080485C0 push 20h ; ' ' ; n.text:080485C2 push eax ; buf.text:080485C3 push 1 ; fd.text:080485C5 call _write.text:080485CA ...
reverse-壳与脱壳
壳壳分为两类
压缩壳:
UPX ASPack PECompact RLPack NSPack
保护壳、
ASProtect Armadillo EXECryptor Themida
手动脱壳参考这篇【BUUCTF】 reverse 新年快乐_buuctf 文件加壳和脱壳-CSDN博客
格式化字符串
格式化字符串原理
在printf函数后面,若是存在%s %x %n$x类似的函数
就会读取栈上内存上的内容进行转化
利用 %x 来获取对应栈的内存,但建议使用 %p,可以不用考虑位数的区别
利用 %s 来获取变量所对应地址的内容,只不过有零截断
利用 %n$x 来获取指定参数的值,利用 %n$s 来获取指定参数对应地址的内容
原理:在做题时会进行对多个’[标记]%p’类似的是为了确定在栈上读取到相应位置的值
非栈上的格式化字符串
当我们的输入函数是把输入的放在bss段或者堆上面,就无法直接通过覆盖ebp进行溢出改变值了,这个时候我们就有其他的做题方法了
现在通过一道题目来解释这个方法
SWPUCTF_2019_login
像这样的这样 无法通过直接写道栈上
来到printf函数这里进行动态调试
因为格式化字符串改值需要利用上图中第一个红框和第二个红框这样的类似的链式结构来改写栈上面的地址
12345678910111213#泄漏libcpay = b'%15$p'io.sendlineafter("Please input your pa ...
LitCTF 2024 pwn ATM
先查看文件
托入ida进行查看
没有什么东西
可以看到首先有个死循环,就是不断的循环,让你选择不同函数作用
在图6可以读取到read这里有个明显的漏洞
接着我们要调节nbytes上面的参数
在图5上面的是把nptr的地址化为(unsigned int)接着下面的函数(第二个框)就把nbytes改变了
可以跑程序看一下
在3函数随便改变输入就可以造成nptr值的改变
接下来找一下偏移
可以看到偏移是0x160
接下来就可以编写脚本了
123456789101112131415161718192021222324252627282930313233343536373839from pwn import *from LibcSearcher import *context.log_level='debug'p=process('./app ...
SROP及例题
SROP使用条件
有时候函数没有输出函数,无法使用ret2libc(或者直接没有got表)
条件1.存在
123mov eax,0fhretn
这样的指令(系统调用号15)sigreturn
2.还有较长的读取空间
3.有syscall_ret
4.有/bin/sh(若没有则需要自己写入)
可以通过栈溢出来控制栈的内容需要知道相应的地址“/bin/sh”Signal Framesyscallsigreturn需要有够大的空间来塞下整个 sigal frame
基本原理
ctf-wiki上面有
总结一下就是调用了sigreturn后面程序会进入一个挂起的状态
然后将此时的状态压入栈中
然后在sigreturn中填写指令
最后程序会返回原来的状态
例题现在以一道例题来说明这个知识点
buu上面的ciscn_2019_s_3
先检查函数,64位,没有canary
再打开ida查看函数
发现有个gadgets
点进去看看
发现可以系统调用号15 可以使用SROP取得这一个题目的权限
先看函数
会打印出一串东西
动态调试看看
看到 ...
堆概述及其例题
堆概念
在stdlib的头文件中存在malloc函数和free函数
两个系统调用brk()
brk()是通过增加break location 来获取内存的,开始heap区域的起点start_brk和终点brk是指向同一个位置的,
ASLR关闭时,这两者都会指向data/bss 段的末端,就是下面的end_data
ASLR开启时,这两者会在data/bss段的末端加上一段随机的的brk偏移
溢出方式:堆是向上面溢出的
怎么一出到下面的空间:在32位的程序中通过整数溢出,超过这段空间时会从下面进行溢出
怎么增大空间的:第一次申请空间的时候就是把brk结束的标识符往上面进行移动
当brk方式增大的空间超过了一定的地方就变成了mmap()溢出了
mmap()用于创建私有的匿名映射段,主要是为了分配一块新的内存,并且这块内存只用调用mmap()的进程才可以使用,所以时私有的。与之相反的操作时munmap(),删除一段内存区域上面的映射
malloc 会使用 mmap()来创建独立的匿名映射段。匿名映射的目的主要是可以申请以 0 填充的内存,并且这块内存仅被调用 ...
bjdctf_2020_babyrop2题解
这题有canary保护
在ida中打开看看
这里的
1__isoc99_scanf("%6s", format);
有个格式化字符串漏洞
这里的read函数有个栈溢出
所以要想办法通过格式化字符串找到canary
又因为这里什么都没有,需要自己构造rop
进行ret2libc
开始找canary
找到了偏移量为6
找到了canary
因为canary一般以00结尾
然后根据栈溢出构造ret2libc就行了
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758from pwn import *from LibcSearcher import *context(log_level='debug')p=remote('node5.buuoj.cn',25455)#p=process('./bjdctf_2020_babyrop2' ...
整数溢出
上界溢出
上界溢出有两种情况,一种是 0x7fff + 1, 另一种是 0xffff + 1
下界溢出
第一种是 sub 0x0000, 1 == 0xffff,对于有符号来说 0 - 1 == -1 没问题,但是对于无符号来说就成了 0 - 1 == 65535。
第二种是 sub 0x8000, 1 == 0x7fff,对于无符号来说是 32768 - 1 == 32767 是正确的,但是对于有符号来说就变成了 -32768 - 1 = 32767。
[OGeek2019]babyrop
先看开了什么保护
可以看到没有canary保护
主函数在fd>0时会读取数据
1v2 = sub_804871F(buf);
来到这个函数里面
发现
12if ( strncmp(buf, s, v1) ) exit(0);
这里有个判断,如果s和buf的长度不一样会退出程序
在开头加上**/x00**进行绕过
1sub_80487D0(v2);
函数会根据buf这个char型数组的buf[7]进行传参
这个函数read的大小更巨buf[7]
所以buf[7]的字符串的值越大越好 取’/xff’
栈溢出这部分完成后就可以用libc构造ROP完成提权
完整exp
1234567891011121314151617181920212223242526272829303132from pwn import *from LibcSearcher import *context(log_level='debug')libc=ELF('./libc-2.23.so')#p=process('./pwn ...