홍가일보
2019년 10월 20일 23시
제6136호

일면 | BBS | BLOG | KB | PHOTO | ABOUT_ME

  • ftz.hackerschool.org user : wiseguyz
  • hacker
    2003.10.29 20:28:44
  • WG_1
    일반적인 Stack Overflow 취약점에서 약간 응용된 것입니다.
    공격 성공 시 public_html의 index.html에 도장을 찍어주세요.
    -> 쉘코드가 들어갈수 있는 버퍼가 20바이트밖에 안되므로 버퍼내 삽입불가
    -> 환경변수를 사용하려 했으나 프로그램내에서 환경변수 초기화
    ->
    int main(int argc, char *argv[])
    {
        char buffer[20];
        int i;
        extern **environ;

        for(i=0; environ[i]; i++)
            memset(environ[i], 0, strlen(environ[i]));

        strcpy(buffer, argv[1]);
    }              


    WG_2

    디버깅과 버퍼 오버플로우 문제입니다.

    1. vuln 파일을 디버깅하여, vuln-2.c의 원래 소스를 유추하세요.
       유추하신 후에는 그에 맞게 프로그램을 작동시켜 test.txt에
       특정 문자열을 저장할 수 있습니다.

    2. vuln의 취약점을 이용하여 쉘을 획득하신 후, index.html에
       도장을 찍어주세요.
                          


    WG_3

    문제 나갑니다~!
    다음은 가장 일반적인 BOF 문제입니다.

    ===============================================
    int main(int argc, char *argv[])
    {
            char string[100];
            strcpy(string, argv[1]);
    }
    ===============================================

    여기서 우리가 리턴어드레스로 사용할 수 있는 것들은 다음과 같습니다.

    1. string 변수에 쉘코드를 넣고 그 곳을 리턴어드레스로..
    2. 환경 변수에 쉘코드를 넣고 그 곳을 리턴어드레스로..
    3. argv[0], argv[1]....argv[x]에 쉘코드를 넣고 그 곳을 리턴 어드레스로..
    4. 리턴 어드레스가 system 계열 함수를 향하도록.. (Return to Library)
    5. Text 영역에 쉘코드를 복사한 후 그곳을 리턴 어드레스로.. (진보된 RTL)

    그럼 이제 위 5가지 공격 방법들을 하나씩 방어해 나가도록
    하겠습니다.

    먼저.. 변수에 쉘코드를 넣을 수 없도록..

    ===============================================
    int main(int argc, char *argv[])
    {
            char string[4];
            strcpy(string, argv[1]);
    }
    ===============================================

    4바이트로 감소시키구요.

    또.. 환경 변수를 사용할 수 없도록..

    ===============================================
    int main(int argc, char *argv[])
    {
            char string[4];
            extern **environ;
            int *pointer;
            strcpy(string, argv[1]);

            // 리턴 어드레스의 주소가 환경 변수의 주소 영역인지를 확인.
            pointer = (int *)(string+8);
            if(*pointer >= environ[0]){
                    printf("오우.. 환경 변수 노우!n");
                    exit(1);
            }
    }
    ===============================================

    요번엔 argv[x]를...

    ===============================================
    int main(int argc, char *argv[])
    {
            char string[4];
            extern **environ;
            int *pointer;
            strcpy(string, argv[1]);

            // 리턴 어드레스의 주소가 환경 변수의 주소 영역인지를 확인.
            pointer = (int *)(string+8);
            if(*pointer >= environ[0]){
                    printf("오우.. 환경 변수 노우!n");
                    exit(1);
            }

            // argv에 쉘코드를 넣지 못하도록!
            if(argc>2 || strlen(argv[0]) > 12 || strlen(argv[1]) > 12){
                    printf("오우.. argv 노우!n");
                    exit(1);
            }
    }
    ===============================================

    마지막으로 라이브러리를 사용할 수 없도록~

    ===============================================
    int main(int argc, char *argv[])
    {
        char string[4];
        extern **environ;
        int *pointer;
        strcpy(string, argv[1]);

        // 리턴 어드레스의 주소가 환경 변수의 주소 영역인지를 확인.
        pointer = (int *)(string+8);
        if(*pointer >= environ[0]){
                printf("오우.. 환경 변수 노우!n");
                exit(1);
        }

        // argv에 쉘코드를 넣지 못하도록!
        if(argc>2 || strlen(argv[0]) > 12 || strlen(argv[1]) > 12){
                printf("오우.. argv 노우!n");
                exit(1);
        }

        // 리턴 어드레스가 라이브러리 영역을 향하는지 확인!
        if(string[11] == 'x08' || string[11] == 'x40' || string[11] == 'x41' || s
    tring[11] == 'x42'){
                printf("오우.. RTL 노우!n");
                exit(1);
        }
    }
    ===============================================

    이상입니다. 보다시피 기존의 공격 방법들을 모두 방어하였습니다.
    이 환경에서 쉘을 획득해 보세요. 분명 어딘가에 답은 있습니다..
    고롬 화이팅~!
                      
    int main(int argc, char *argv[])
    {
        char string[4];
        extern **environ;
        int *pointer;
        strcpy(string, argv[1]);

        // 리턴 어드레스의 주소가 환경 변수의 주소 영역인지를 확인.
        pointer = (int *)(string+8);
        if(*pointer >= environ[0]){
                printf("오우.. 환경 변수 노우!n");
                exit(1);
        }

        // argv에 쉘코드를 넣지 못하도록!
        if(argc>2 || strlen(argv[0]) > 12 || strlen(argv[1]) > 12){
                printf("오우.. argv 노우!n");
                exit(1);
        }

        // 리턴 어드레스가 라이브러리 영역을 향하는지 확인!
        if(string[11] == 'x08' || string[11] == 'x40' || string[11] == 'x41' || s
    tring[11] == 'x42'){
                printf("오우.. RTL 노우!n");
                exit(1);
        }
    }    



    WG_4

    FTZ 서버 udp 500번 포트에는 허접한 퀴즈 머신이 돌아가고 있습니다.

    소스를 잘 보시고 /home/WG_4/public_html/index.html에
    자신의 id나 코멘트가 들어가도록 해보세요~

    *문제 푸실 때 주의 할 점
    1.문제를 푸는데 사용한 소스 올릴 것.
    2.소스 분석해서 간단히 주석달기.

    이 문제의 점수는 10점입니다.
    총합 20점 이상의 점수를 획득하시면 3차 평가를 통과하시게 됩니다.


    #include <stdio.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <sys/file.h>
    #include <signal.h>
    #include <errno.h>

    #define QUESTION_NUM   5

    struct QUIZ{

        unsigned int x;
        unsigned int y;
        char op;
    };

    struct REPLY{
        unsigned int ans;
        char name[50];
    };


    void DieWithError(char *errorMessage);
    void SIGIOHandler(int signalType);

    int sock;

    int main(int argc, char *argv[])
    {
        struct sockaddr_in ServAddr;
        unsigned short ServPort;
        struct sigaction handler;

        if (argc != 2)
        {
            fprintf(stderr,"Usage:  %s <SERVER PORT>n", argv[0]);
            exit(1);
        }

        ServPort = atoi(argv[1]);


        if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
            DieWithError("socket() failed");


        memset(&ServAddr, 0, sizeof(ServAddr));
        ServAddr.sin_family = AF_INET;
        ServAddr.sin_addr.s_addr = htonl(INADDR_ANY);
        ServAddr.sin_port = htons(ServPort);


        if (bind(sock, (struct sockaddr *) &ServAddr, sizeof(ServAddr)) < 0)
            DieWithError("bind() failed");

        handler.sa_handler = SIGIOHandler;
        if (sigfillset(&handler.sa_mask) < 0)
            DieWithError("sigfillset() failed");
        handler.sa_flags = 0;

        if (sigaction(SIGIO, &handler, 0) < 0)
            DieWithError("sigaction() failed for SIGIO");

        if (fcntl(sock, F_SETOWN, getpid()) < 0)
            DieWithError("Unable to set process owner to us");

        if (fcntl(sock, F_SETFL, O_NONBLOCK | FASYNC) < 0)
            DieWithError("Unable to put client sock into non-blocking/async mode");


        for (;;)
            sleep(3);

    }


    void DieWithError(char *errorMessage)
    {
        perror(errorMessage);
        exit(1);
    }

    void SIGIOHandler(int signalType)
    {
        struct sockaddr_in ClntAddr;
        unsigned int clntLen;
        int recvMsgSize;
        struct QUIZ *question;
        struct REPLY *answer;
        int i=0;
        int correct=0;
        FILE *fp;

        question = (struct QUIZ *)malloc(sizeof(struct QUIZ));
        answer = (struct REPLY *)malloc(sizeof(struct REPLY));

        srand( (unsigned)time( NULL ) );

        clntLen = sizeof(ClntAddr);

        if ((recvMsgSize = recvfrom(sock, answer, sizeof(struct REPLY), 0,
            (struct sockaddr *) &ClntAddr, &clntLen)) < 0) return;

        printf("Handling client %sn", inet_ntoa(ClntAddr.sin_addr));
        printf("%s received..n",answer->name);
        if(strcmp(answer->name, "start!")!=0){
            printf("start error!n");
            return;
        }

        for(i=0;i<QUESTION_NUM;i++)
        {

            question->x=(rand()%10000);
            question->y=(rand()%10000);
            question->op=question->x > question->y ? '-':'+';


            if (sendto(sock, question, sizeof(struct QUIZ), 0, (struct sockaddr *)
                &ClntAddr, sizeof(ClntAddr)) !=sizeof(struct QUIZ))
            DieWithError("sendto() failed");

            printf("question %d: %d %c %d sentn",i+1,question->x,question->op,quest
    ion->y);

            sleep(1);

            if ((recvMsgSize = recvfrom(sock, answer, sizeof(struct REPLY), 0,
                   (struct sockaddr *) &ClntAddr, &clntLen)) !=sizeof(struct REPLY))
            {

                if (errno != EWOULDBLOCK)
                    DieWithError("recvfrom() failed");
            }

            printf("answer received from %s:%dn",answer->name,answer->ans);

            if(answer->ans==(question->x > question->y)?question->x-question->y:ques
    tion->x+question->y ){
                printf("good!n");
                if(++correct==5){
                    printf("Congraturation!n");
                    fp=fopen("/home/WG_4/public_html/index.html","a");
                    if(fp==NULL){
                        printf("File open error!n");
                        return;
                    }
                    fputs(answer->name,fp);
                    fclose(fp);
                }
            }

        }

    }
              

    WG_5

    문제를 푸는 법은 소스를 보시고 버그를 찾아서 그 버그를 이용,
    특정 쉘코드를 수행시키는데 성공 하시면 됩니다. 쉘코드는 간단한
    문자열을 출력하는등 아주 간단한 것이라도 상관이 없습니다.
    단지 프로그램의 수행 흐름을 성공적으로 바꿨는지 여부를 판단합니다.

    이 문제의 점수는 20점입니다.
    총합 20점 이상의 점수를 획득하시면 3차 평가를 통과하시게 됩니다.  


    int main(int argc,char **argv) {
            printf(argv[1]);
            while(1);
    }



    WG_6

    문제를 푸는 법은 소스를 보시고 버그를 찾아서 그 버그를 이용,
    특정 쉘코드를 수행시키는데 성공 하시면 됩니다. 쉘코드는 간단한
    문자열을 출력하는등 아주 간단한 것이라도 상관이 없습니다.
    단지 프로그램의 수행 흐름을 성공적으로 바꿨는지 여부를 판단합니다.

    이 문제의 점수는 20점입니다.
    총합 20점 이상의 점수를 획득하시면 3차 평가를 통과하시게 됩니다

    int main(int argc,char **argv) {
            char *pbuf;
            char buf[256];

            signal(10,main);
            pbuf=(char*)malloc(strlen(argv[2])+1);

            strcpy(buf,argv[1]);
            for (;*pbuf++=*(argv[2]++););
            while(1);
    }              

댓글 0 ...

위지윅 사용
번호
제목
닉네임
556 hongyver 2004.06.16
555 나드래요~ 2004.06.17
554 제수리 2004.06.21
553 won 2004.06.22
552 あに 2004.06.24
551 순미래여~~ 2004.06.25
550 kim 2004.06.28
549 문홍이다옹 2004.06.29
548 카미 2004.07.04
547 니하오마 2004.07.05
546 JUさん 2004.07.05
545 JUさん 2004.07.05
544 JUさん 2004.07.06
543 hongyver 2004.07.07
542 클림튼 2004.07.08
541 니하오마 2004.07.12
540 봉이룬 2004.07.13
539 카미 2004.07.14
538 이태해 2004.07.19
537 제수리 2004.07.22
태그

본 홈페이지는 COPYLEFT로 정보의 독점을 거부하고 정보를 공유하자는 뜻을 가지고 있습니다.
(단 일부 저작권 표기를 명시한것은 예외로 합니다.)
COPYLEFT (c) 2012 홍가일보 ALL RIGHTS UNRESERVED