#include <syslog.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define BUFLEN 16
#define WORDSIZE 2
#define DWORDSIZE WORDSIZE+WORDSIZE
void mylog(intkind, char *msg){
// 3번 취약점, 포맷스트링
syslog(LOG_USER | kind, msg);
}
void mycpy(char *dst, char *src){
if(strlen(src) < BUFLEN -1)
while(*src)
*dst++ = *src++;
*dst= '\x00';
}
int main(int argc, char *argv[]){
char buf1[16];
char buf2[16];
char buf3[BUFLEN];
char *buf4;
char *buf5;
char buf6[16];
char *buf7;
int i, len;
if(argc != 12)
exit(0);
// 1번 취약점
// argv[1]의 길이가 17바이트 이상일 경우 NULL이 복사되지 않음
// 즉, buf1이 NULL 없는 문자열이 되어버림
// 이로 인해 차후 이상작동 혹은 취약점이 발생 할 수 있음
strncpy(buf1, argv[1], sizeof(buf1));
len= atoi(argv[2]);
if (len< 16)
// 2번 취약점
// integer overflow 발생
// 예를 들어 argv[3]의 값을 -4로 줄 경우 -4=4294967296가 되어버림
memcpy(buf2, argv[3], len);
else {
char *buf= malloc(len+ 20);
if(buf){
// 취약점 없음
snprintf(buf, len+20, "String too long: %s", argv[3]);
// 3번 취약점, 포맷스트링
mylog(LOG_ERR, buf);
}
}
// 취약점 없음
mycpy(buf3, argv[4]);
// 4번 취약점
// 위 mycpy에 의해 buf3이 가득 찰 경우 버퍼오버플로우 발생
strncat(buf3, argv[5], sizeof(buf3)-1);
if(fork()){
// 취약점 없음
execl("/bin/ls", "/bin/ls", argv[6], 0);
}
// filter metacharacters
char *p;
if(p = strchr(argv[7], '&'))
*p = 0;
if(p = strchr(argv[7], '`'))
*p = 0;
if(p = strchr(argv[7], ';'))
*p = 0;
if(p = strchr(argv[7], '|'))
*p = 0;
if(strlen(argv[7]) < 1024){
buf4 = malloc(20 + strlen(argv[7]));
// 취약점 없음
sprintf(buf4, "/bin/cat %s", argv[7]);
// 5번 취약점
// $ 특수 문자를 이용하여 시스템 명령 실행 가능
// > 특수 문자를 이용하여 root 권한 파일 복사 가능
system(buf4);
}
// 6번 취약점
// integer overflow + Null Pointer Dereference
// argv[8]과 argv[9]의 길이가 각각 0x7fffffff(-1)일 경우 결과는 malloc(0)이 됨
// 리턴 값은 0 = Null Pointer Dereference
buf5 = malloc(strlen(argv[8]) + strlen(argv[9]) + 2);
strcpy(buf5, argv[8]);
strcat(buf5, argv[9]);
// 7번 취약점, 버퍼 오버플로우
memcpy(buf6, argv[10], strlen(argv[10]));
// 8번 취약점, 매크로 우선순위 오류
// #define WORDSIZE 2
// #define DWORDSIZE WORDSIZE+WORDSIZE
// buf7 = malloc(4 * DWORDSIZE);
// 4*2+2=10
buf7 = malloc(4 * DWORDSIZE);
for(i=0; i<4; i++){
// 총 복사 길이 : 4+4+4+4=16
memcpy(buf7 + 4 * i, argv[11] + 4 * i, DWORDSIZE);
}
printf("\nGot%s, (%d) %s, %s, %s, %s, %s, %s\n", buf1, len, buf2,buf3, buf4, buf5, buf6, buf7);
} |