# nullptr - ALLES CTF 2020

tl;dr

• Overwrite mmap_threshold with null and trim top chunk size.
• Null out last 2 bytes of stdin’s _IO_buf_base and brute force to get allocation on stdin.
• Overwrite one of the jump tables with win function to get shell.

Challenge Points: 453
Solves: 4

We had a really great time this weekend with this year’s edition of Alles CTF. I spent most of my time working on the challenge nullptr and in this post , I’ll be discussing the intended solution for the challenge.

PS: We could not solve this during the CTF but the exploit idea is worth sharing.

## Challenge description

To begin with , we’d been provided with a pretty simple c source code which has 2 functionalities.

1. The view function prints the content of an address passed , hence we can be assured of all leaks ;).
2. The nuke function nulls out the content of an address passed.

Looks pretty simple doesn’t it?

## Getting necessary leaks

Getting all required leaks is nothing but a trivial task.

Initially, we can directly get stack leak by passing any non-numeric value to scanf. Let’s script it a bit.

## Idea of exploitation

After carefully analyzing scanf’s source code, sherl0ck came up with the idea of calling malloc again by nulling out IO_buf_base.

In the depths of scanf ,there resides a function called IO_doallocbuf.

The code is actually of the caller function of _IO_doallocbuf which is _IO_new_file_underflow.

It calls malloc with a fixed size of blk_sizet which is by default 0x1000 bytes.

From this point on , we were stuck , we tried nulling out the last 2 bytes of buf base in the hope of getting allocation at tcache structure , from there on we faked a 0x400 size arbitrary chunk in tcache and found another way to call malloc with size of 0x400 from stdout structure.

Well , getting allocation with stdout doesn’t actually give us arbitrary write.

## The intended solution

Well , the intended solution is actually leveraging an mmap call from malloc. Let’s see how this can be done.

• Nulling out mmap_threshold with triggers a different code path in malloc.
• Also , trimming top size by writing null misaligned finally calls mmap when malloc is invoked.

Now , all that we have to do is , brute force until an mmap happens near our stdin file structure and from there on , its a game over.

Let’s take our script forward.

Once there’s a hit , all that’s left is to partially overwrite IO_buf_base and get allocation on stdin. Here , after getting allocation on stdin , we intend to overwrite malloc hook to get shell.

### An alternative approach

We could be all lazy and let brute force do the work. A simpler yet time consuming approach would be to overwrite the last 3 bytes of stdin’s IO_buf_base and wait for the magic to happen. Eventually , in one of the runs , it would match with binary bss and you get a direct write to GOT table.

## Conclusion

The challenge had really intersting concepts involved and we learnt quite alot. Kudos to the author Mrmaxmeier for the awesome challenge.

Here’s the original script of the author - Link