홍가일보
2024년 04월 18일 19시
제7778호

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

새로운 댓글을 작성합니다.

hacker

2003.10.29 20:28

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);
}              
문서 첨부 제한 : 0Byte/ 2.00MB
파일 크기 제한 : 2.00MB (허용 확장자 : *.*)
돌아가기

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