홍가일보
2024년 04월 26일 23시
제7786호

일면 | 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 ...

위지윅 사용
번호
제목
닉네임
736 hongyver 2003.09.02
735 경희~ 2003.09.03
734 지영탱 2003.09.03
733
^^ +3
종현 2003.09.04
732 희! 2003.09.04
731
^^ +4
쭈군 2003.09.04
730 추락천사 2003.09.05
729 hongyver 2003.09.09
728 옆자리 2003.09.09
727 2003.09.16
726 옛친구.... 2003.09.20
725 hongyver 2003.09.23
724 hongyver 2003.10.02
723 랄랄라™ 2003.10.02
722 hongyver 2003.10.06
721 전인섭 2003.10.07
720 날군 2003.10.09
719 hongyver 2003.10.10
718 지영탱 2003.10.10
717 라인 2003.10.10
태그

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