Session 4: Intro to memory corruption mitigation.

Tasks

Summary

Tasks along with descriptions and hints are available only on the lab machines. The lab format is split into two parts and is challenge-oriented:

  • Each task ca be accessed only by its owner user (e.g. task randmin_01 and its source can only be read by user randmin_01)
  • The tasks have elevated permission on execution (e.g. task randmin_01 has permissions to read files of randmin_01 and randmin_02)
  • The password for the next level is in flags/next_task_level
  • Your goal is to 'trick' the application into reading the content of that file
  • After you obtain the password you can advance to the next level by switching to that user
  • You are initially given the password to log into randmin_01: “1234” and gatekeeper_01: “4321”

Categories

Category 1 (address space recap) requires you to enter a password in order to print the flag for the next level, but there's a catch: you don't enter a password, you need to enter a memory address

  • gatekeeper_01
  • gatekeeper_02
  • gatekeeper_03 (Bonus)

Category 2 (memory corruption)

  • randmin_01, randmin_02: You need to defeat NX by returning to .text
  • randmin_03, randmin_04: You need to defeat NX by returning to libc
  • randmin_05: You need to defeat NX + ASLR
  • randmin_06: You need to defeat NX + ASLR + PIE
  • randmin_07 (Bonus) : You need to defeat NX + ASLR + PIE + SSP

Example run

dmns@dmns-VirtualBox:/$ su gatekeeper_01
Password: 
gatekeeper_01@dmns-VirtualBox:/$ cd
gatekeeper_01@dmns-VirtualBox:~$ ls
flags  gatekeeper_01  gatekeeper_01.c
gatekeeper_01@dmns-VirtualBox:~$ cat flags/gatekeeper_01_flag 
cat: flags/gatekeeper_01_flag: Permission denied
gatekeeper_01@dmns-VirtualBox:~$ cat gatekeeper_01.c | head
/*
 * Workshop "Memory Management in C", July 2013
 * Memory corruption tasks
 * Radu Caragea
 */
 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
gatekeeper_01@dmns-VirtualBox:~$ ./gatekeeper_01
Welcome to <<Gate 1>> human, what is your name?
testing
What is the passphrase testing? Give me a memory address of where it is and you shall be granted access
Enter the address in hex like so: 0x123ABC
0x123ABC
Checking contents of 0x123abc
Segmentation fault
gatekeeper_01@dmns-VirtualBox:~$ ./gatekeeper_01
Welcome to <<Gate 1>> human, what is your name?
testing2
What is the passphrase testing2? Give me a memory address of where it is and you shall be granted access
Enter the address in hex like so: 0x123ABC
[solution commented out]
Checking contents of [solution commented out]
Access granted! The password to gatekeeper_02 is:
[flag commented out]
gatekeeper_01@dmns-VirtualBox:~$ su gatekeeper_02
Password: 
gatekeeper_02@dmns-VirtualBox:/home/gatekeeper_01$ cd
gatekeeper_02@dmns-VirtualBox:~$ ls
flags  gatekeeper_02  gatekeeper_02.c
gatekeeper_02@dmns-VirtualBox:~$ cat flags/gatekeeper_02_flag 
cat: flags/gatekeeper_02_flag: Permission denied
gatekeeper_02@dmns-VirtualBox:~$

NOTE: The segmentation fault is expected as that address is not mapped into the process address space.

Gdb tricks you might need

Check the Gdb cheat sheet especially in the 'information' and 'various useful stuff' sections

Hijacking control flow

  • The exact location of a segfault is written in the kernel log. You can view it with dmesg (you'll only need the last line)
randmin_01@102lin:~$ ./randmin_01
Enter the password:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
You entered:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
You are not the Randministrator!
This unauthorized attempt will be logged.
Segmentation fault
randmin_01@102lin:~$ dmesg|tail -1
[ 5277.100200] randmin_01[5839]: segfault at 41414141 ip 0000000041414141 sp 00000000ffffd370 error 14
randmin_01@102lin:~$ 
  • You can use a pattern so that you can easily see what was written into the return address instead of trial and error.
    randmin_01@102lin:~$ ./randmin_01
    Enter the password:
    Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5
    You entered:
    Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5
    You are not the Randministrator!
    This unauthorized attempt will be logged.
    Segmentation fault
    randmin_01@102lin:~$ dmesg|tail -1
    [ 5481.155852] randmin_01[5853]: segfault at 64413764 ip 0000000064413764 sp 00000000ffffd370 error 14
  • When you want to jump to a function that takes no arguments you only need to append its address to the exploit pattern
        <code c>
        ...
        int f()
        {
            printf("Hello\n");
            return 42;
        }
        ...
        </code>

    * If the address of the function is 0x0804849c your exploit pattern will look like “AAAAAA…AAA\x9c\x84\x04\x08” because calling this function will look like

        <code asm>
        ...
        call   804849c <f>
        ...
        </code>

    * For tasks randmin_03 and up you will need to call system(char *cmd)

        <code c>
        ...
        int f(char *str)
        {
            printf("%s\n", str);
            return 42;
        }
        ...
        </code>

    * Translated to asm:

        <code asm>
        ...
        movl   $0x80485a0,(%esp)      (0x80485a0 is the address of the string parameter)
        call   804849c <f>            
        ...
        </code>

    * Because 'call' also pushes 4 bytes on the stack the parameter is offset by exactly 4 bytes, so if you want to call f with the address of that string your exploit should look like “AAAAAA…AAA\x9c\x84\x04\x08ABCD\xa0\x85\x04\x08” where ABCD is the 4 byte value mentioned (any value will work)

Tools you will need

sesiuni/memory/4.txt · Last modified: 2013/07/12 15:21 by rcaragea