codezen.fr code hacking, zen coding

19Feb/13Off

GiTS 2013 CTF – Pwnables 250 Question 10 – Back2skool Write-up

Posted by aXs

back2skool-3fbcd46db37c50ad52675294f566790c777b9d1f: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, stripped

This is the binary for MathServ, "The one-stop shop for all your arithmetic needs".

$ nc localhost 31337
    __  ___      __  __   _____
   /  |/  /___ _/ /_/ /_ / ___/___  ______   __ v0.01
  / /|_/ / __ `/ __/ __ \\__ \/ _ \/ ___/ | / /
 / /  / / /_/ / /_/ / / /__/ /  __/ /   | |/ /
/_/  /_/\__,_/\__/_/ /_/____/\___/_/    |___/
===============================================
Welcome to MathServ! The one-stop shop for all your arithmetic needs.
This program was written by a team of fresh CS graduates using only the most
agile of spiraling waterfall development methods, so rest assured there are
no bugs here!

Your current workspace is comprised of a 10-element table initialized as:
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }

Commands:
  read  Read value from given index in table
  write Write value to given index in table
  func1 Change operation to addition
  func2 Change operation to multiplication
  math  Perform math operation on table
  exit  Quit and disconnect
read
Input position to read from:
1
Value at position 1: 1
write
Input position to write to:
1
Input numeric value to write:
10
Value at position 1: 10
func1
Setting mode to ADDITION
math
Result of math: 54
exit
Exiting program!

You can read and write numbers to an array and perform addition or multiplication of all the entries of the array.

Lets check how the "read" function works:

sendString(sockfd, (int)"Input position to read from:\n");
readUntil(sockfd, (int)&nptr, 0x13u, 10);
position = atoi(&nptr);
value =  *(_DWORD *)&values[4 * position];
sock_printf(sockfd, "Value at position %d: %d\n", value);

There is 2 vulnerabilities here:
- There is no bound checking on the position value
- position can be signed, allowing to use a negative offset

Basically, you can read and write any memory, this will prove useful for information leak purpose.

Lets move to the "write" function:

readUntil(sockfd, (int)&nptr, 0x13u, 10);
position = atoi(&nptr);
if