-
hacker2003.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);
}
번호
|
제목
|
닉네임
| |
---|---|---|---|
676 | 애림 | 2003.12.19 | |
675 |
홍사형 보오...
+3
| 불면왕 | 2003.12.29 |
674 |
홍가버형..토욜날??
+2
| 제수리 | 2004.01.02 |
673 | 태후니 | 2004.01.03 | |
672 | 상동여인 | 2004.01.05 | |
671 | 알아서 뭐하시 | 2004.01.06 | |
670 |
부탁좀 할까 하는데
+4
| 전인섭 | 2004.01.06 |
669 | hongyver | 2004.01.07 | |
668 | 제수리 | 2004.01.07 | |
667 |
모할까?...
+4
| 지영탱 | 2004.01.09 |
666 |
월간궁년...
+2
| hongyver | 2004.01.09 |
665 |
첫방문
+1
| 권정인 | 2004.01.09 |
664 |
좀 거시기 합니다...
+1
| 상동여인 | 2004.01.09 |
663 |
잘봤습니다...KBS
+4
| 상동여인 | 2004.01.09 |
662 | hongyver | 2004.01.12 | |
661 |
컴맹질문
+4
| 전인섭 | 2004.01.12 |
660 |
사랑하고있습니다..
+7
| 아침이슬 | 2004.01.13 |
659 |
홍회장님~!
+5
| 제수리 | 2004.01.13 |
658 | 박창오 | 2004.01.13 | |
657 |
IEEE1394카드
+2
| 제수리 | 2004.01.15 |