출처: http://www.joinc.co.kr/modules/moniwiki/wiki.php/article/%C6%C4%C0%CF%BA%AF%C1%B6%B0%CB%BB%E7
파일변조검사
윤 상배
dreamyun@yahoo.co.kr
- 차례
- 1절. 소개
- 2절. 파일보안
- 1절. 소개
- 2.1절. 파일보안의 필요성
- 2.2절. 인터넷 에서의 파일보안
- 2.3절. 시스템 파일 보안
- 2.4절. 시스템파일 변조 검사 어플리케이션
- 2.2절. 인터넷 에서의 파일보안
- 2.4.1절. 파일이름 & MD5 목록작성 프로그램
- 2.4.2절. 파일 변조검사 프로그램
- 2.4.3절. 테스트
- 2.4.2절. 파일 변조검사 프로그램
- 2.4.1절. 파일이름 & MD5 목록작성 프로그램
- 2.1절. 파일보안의 필요성
- 3절. 결론
1절. 소개
현재 인터넷의 가장큰 이슈는 보안이다. 이 문서는 이러한 보안문제중 호스트단에서 일어날수 있는 파일변조와 관련된 문제와 그 해결을 위한 간단한 해결책을 제시해보고자 한다.
이러한 문제의 해결을 위해서 MD5 해쉬 알고리즘과 STL의 몇가지 컨테이너와 알고리즘을 사용하게 될것이다.
2절. 파일보안
2.1절. 파일보안의 필요성
일단 크래커가 어떤방법을 통해서든지 크래킹하고자하는 목적 호스트에 접근했다면, 이 크래커가 단순한목적 - 임의의 파일들을 무작위로 삭제한다거나, 단순히 자신의 실력 을 테스트할목적 - 이 아니라면, 지속적으로 호스트를 감시하면서 중요 데이타들을 수집하기를 원할것이다. 심할경우 특정 명령을 수행하면(ls 같은) 아예 모든 파일이 삭제되어 버리도록 만들수도 있을것이다. 혹은 특정 웹페이지를 변조하는 작업등을 할수 있는데, 어떤 경우이던지 간에 기업에 좋지 않은 결과를 초래할것이다.
2.2절. 인터넷 에서의 파일보안
특히 인터넷을 통해 파일을 주고 받을경우 파일이 변조되었는지를 확인하는 것은 더욱 중요해진다. APM [1] 설치를 하기 위해서 어떤 사이트에서 php쏘쓰를 다운받았다고 하자. 그런데, 이 PHP쏘쓰가 변조가 되어서 악의적인 코드가 들어가 있는지는 100% 장담할수 없을것이다. 심지어는 php.net 사이트에서 받았다고 하더라도 100% 안전한 코드라는걸 확인할수 없을것이며, 실제로 심심찮게 "어느 사이트에서 받은 쏘쓰는 변조되어있음으로 사용하고 있을경우 업데이트 시키세요" 라는 보안 경고가 인터넷 상에 발표되곤 한다. 평소 보안문제에 관심을 가지고 있었다면, sendmail "쏘쓰가 변조되었네, 어떤 쏘쓰가 변조되었으니 다시 설치해야 하네.." 하는 보안소식을 접해보았을것이다.
그래서 요즘에는 인터넷상에서 파일을 전송할경우 "md5 문자" 까지를 함께 전송해서 변조된 파일이 아님을 확인할수 있는 방법을 제공한다. md5 는 단방향 hash 알고리즘을 제공해주는 함수이다. 이 함수를 이용하면 어떠한 데이타에 대해서 128 비트의 크기를 가지는 메시지 축약을 만듦으로써 데이타에 대한 무결성을 검증할수 있다.
그럼 실제 예를 하나 들어보도록 하겠다. www.php.net 에 가면 여러가지 쏘쓰파일을 배포하면서 쏘쓰파일에 대한 무결성을 검증시켜주기 위해서 md5 문자열까지 같이 제공한다. 여러분이 이 사이트에서 어떤 쏘쓰파일을 받았는데, 과연 원본그대로의 파일인지를 검증받고 싶다면, 해당 파일에 대한 md5 문자열을 얻어서 www.php.net 의 md5 문자열과 일치하는지를 확인하면 된다.
필자는 www.php.net 에서 PHP 4.2.0 to 4.2.2 patch 라는 패치파일을 다운로드 받았다. 다음은 www.php.net 에서 제공하는 패치파일과 이 패치파일에 대한 md5 값이다.
PHP 4.2.0 to 4.2.2 patch [313Kb] - 22 July 2002This unified diff will enable you to update your local PHP source to the latest version from 4.2.0.md5: 254bccc245d65cece1f40f782b70ec6b |
예제 : getmd5.c
#include <openssl/md5.h>#include <string.h>#include <unistd.h>#include <sys/stat.h>#include <sys/types.h>#include <fcntl.h>int main(int argc, char **argv){ MD5_CTX lctx; unsigned char digest[16]; char md5msg[40]; int i; int fd; struct stat status; char *file_name = argv[1]; char *data; MD5_Init(&lctx); fd = open(file_name, O_RDONLY); if (fd < 0) { perror("error : "); exit(0); } fstat(fd, &status); data = (char *)malloc(status.st_size); read (fd, data, status.st_size); MD5_Update(&lctx, data, status.st_size); MD5_Final(digest, &lctx); for (i = 0; i < sizeof(digest); ++i) { sprintf(md5msg+(i*2), "%02x", digest[i]); } printf ("%s\n", md5msg); free(data);} |
gcc -o getmd5 getmd5.c -lssl -lcrypto |
[root@localhost md5]# ./getmd5 php-4.2.0-to-4.2.2.patch.gz 254bccc245d65cece1f40f782b70ec6b |
파일의 내용이 달라지면 정말로 md5 값이 달라지는지 확인하기 원한다면 위의 프로그램을 이용해서 특정 파일을 변경전후의 md5 값을 비교하면 될것이다.
2.3절. 시스템 파일 보안
시스템파일보안 역시 기본적으로는 위의 인터넷파일 보안과 같은 방법을 이용해서 구현가능하다. 보안이 필요한 파일의 리스트를 만든다음에 각파일에 대한 MD5 문자열을 얻은후, 이 데이타를 저장해 놓고, 일정시간 간격으로 파일의 리스트에 대한 MD5 문자열을 가져와서, 처음 만들어 놓은 MD5 문자열과 비교하면 될것이다.
+----------------+----------------+ +----------------------------+ | 파일 목록 | MD5 문자 | <---- | MD5 해쉬목록 작성 프로그램 | |---------------------------------| +----------------------------+ | /bin/login | 347717f89a ... | | /bin/passwd | 1629a99f6c ... | +--------------------+ | /usr/bin/httpd | d044f3d3ad ... | ----> | 파일 검사 프로그램 | | ... | ... | +--------------------+ +---------------------------------+ |
2.4절. 시스템파일 변조 검사 어플리케이션
이제 어떤식으로 파일의 변조 유무를 검사할수 있는지에 대한 기본적인 아이디어를 얻었으니, 아이디어를 코드로 구현해보도록 하자. 이 아이디어를 구현하기 위해서 2개의 어플리케이션이 만들어질것이다.
우선은 검사하기 원하는 시스템파일의 목록을 만들어야 할것이다. 그리고 만든 파일목록에 대한 MD5 문자열을 구하는 어플리케이션을 만들어서 파일로 저장하는 프로그램이다.
다음은 실제 파일을 검사하는 프로그램으로 파일검사 목록에서 파일목록과 파일에 대한 MD5 문자를 읽어들여서 메모리에 저장하고, 일정시간마다 파일목록의 파일에 대한 MD5 문자열을 얻어와서 원래의 MD5 문자열과 일치하는지 검사하는 프로그램이다.
파일 목록 검사를 위한 가장 간단한 방법은 파일검사 목록과 MD5 정보를 읽어들여서 vector 등을 이용해서 배열로 만들고, 첫번째 배열부터 마지막 배열의 파일목록이름을 가져와서 이 파일에 대한 MD5 검사를 수행해서 원본 MD5 문자열과 비교하는 방법일 것이다.
2.4.1절. 파일이름 & MD5 목록작성 프로그램
검사할 파일이름이 들어있는 list.cfg 를 읽어들여서 파일에 대한 md5 문자열을 얻어오고, 이것을 .listmd5.cfg 에 저장하는 프로그램이다. list.cfg 는 다음과 같은 내용을 가진다.
1.txt2.txt3.txt4.txt5.txt |
예제 : makelist.cc
#include <openssl/md5.h>#include <string.h>#include <unistd.h>#include <stdio.h>#include <sys/stat.h>#include <sys/types.h>#include <fcntl.h>#include <vector>using namespace std;#define LISTFNAME "list.cfg"#define LISTFMDNAME ".listmd5.cfg"#define chop(str) str[strlen(str) - 1] = '\0' typedef struct _filelist{ char filename[80]; char md5[40];} filelist;int file2md5(char *, char *);int main(int argc, char **argv){ int i; FILE *fp; struct stat status; char *data; filelist md5info; vector<filelist> vmd5info; char buf[80]; char md5msg[40]; // 리스트를 읽어와서 파일 목록을 만든다. if ((fp = fopen(LISTFNAME, "r")) == NULL) { perror("error : "); exit(0); } while(fgets(buf, 80, fp) != NULL) { chop(buf); // md5 문자를 얻어온다. file2md5(buf, md5msg); strcpy(md5info.filename, buf); strcpy(md5info.md5, md5msg); // .listmd5.cfg 에 내용을 적는다. vmd5info.push_back(md5info); } fclose(fp); if ((fp = fopen(LISTFMDNAME, "w")) == NULL) { perror("error : "); exit(0); } for (int i = 0; i < vmd5info.size(); i++) { char listbuf[80]; sprintf(listbuf, "%s:=%s\n", vmd5info[i].filename, vmd5info[i].md5); fputs(listbuf, fp); } fclose(fp);}// 입력된 파일에 대한 md5 문자열을 얻어온다. int file2md5(char * file_name, char *md5msg){ char *data; int fd; int i; struct stat status; unsigned char digest[16]; char *x; MD5_CTX lctx; MD5_Init(&lctx); fd = open(file_name, O_RDONLY); if (fd < 0) { perror("error : "); exit(0); } fstat(fd, &status); data = (char *)malloc(status.st_size); read (fd, data, status.st_size); MD5_Update(&lctx, data, status.st_size); MD5_Final(digest, &lctx); for (i = 0; i < sizeof(digest); ++i) { sprintf(md5msg+(i*2), "%02x", digest[i]); } free(data); close(fd); return 1;} |
1.txt:=fb20e95d00a91f81936f84dc0fb3f7702.txt:=c34f2efffd4a8079cec1aff2c5dc98f03.txt:=5da1f11dd590919eb2465151fbaad1374.txt:=b3f56e50a03224ce395eb4c34c6322da5.txt:=6ceadb3fae1a5a893b9c39dfa64e19b7 |
2.4.2절. 파일 변조검사 프로그램
이제 본격적으로 파일변조 검사 프로그램을 만들어 보자. 이 프로그램은 .listmd5.cfg 의 내용을 읽어들이고, 내용에 있는 파일이름에 대한 MD5 문자열을 만들어서 내용에 있는 MD5 와 내용이 같은지를 확인하는 프로그램이다. 역시 간단한 코드임으로 설명은 주석으로 대신한다.
예제 : checklist.cc
#include <openssl/md5.h>#include <string.h>#include <unistd.h>#include <stdio.h>#include <sys/stat.h>#include <sys/types.h>#include <fcntl.h>#include <vector>using namespace std;#define LISTFMDNAME ".listmd5.cfg"#define chop(str) str[strlen(str) - 1] = '\0' typedef struct _filelist{ char filename[80]; char md5[40];} filelist;int file2md5(char *, char *);int main(int argc, char **argv){ int i; FILE *fp; struct stat status; char *data; filelist md5info; vector<filelist> vmd5info; char buf[80]; char md5msg[40]; vector<filelist>::iterator mi; // 리스트를 읽어와서 파일 & md5 메시지 목록을 만든다. if ((fp = fopen(LISTFMDNAME, "r")) == NULL) { perror("error : "); exit(0); } while(fgets(buf, 80, fp) != NULL) { char null[3]; chop(buf); sscanf(buf, "%[^:=]%[:=]%s", md5info.filename, null, md5info.md5); vmd5info.push_back(md5info); } fclose(fp); // 파일 변조를 검사한다. while(1) { int check = 1; mi = vmd5info.begin(); while(mi != vmd5info.end()) { printf("파일검사 : %s, ", mi->filename); if (file2md5(mi->filename, md5msg) < 0) printf("WARN : 파일삭제", --check); else if (strcmp(mi->md5, md5msg) != 0) printf("WARN : 파일변조 %s => %s", mi->md5, md5msg, --check); *mi++; if (check == 1) printf("OK"); printf("\n"); } printf("\n"); sleep(2); }}int file2md5(char * file_name, char *md5msg){ char *data; int fd; int i; struct stat status; unsigned char digest[16]; char *x; MD5_CTX lctx; MD5_Init(&lctx); fd = open(file_name, O_RDONLY); if (fd < 0) { return -1; } fstat(fd, &status); data = (char *)malloc(status.st_size); read (fd, data, status.st_size); MD5_Update(&lctx, data, status.st_size); MD5_Final(digest, &lctx); for (i = 0; i < sizeof(digest); ++i) { sprintf(md5msg+(i*2), "%02x", digest[i]); } free(data); close(fd); return 1;} |
2.4.3절. 테스트
먼저 적당하게 list.cfg 를 만들고 나서 makelist 를 실행시킨다. 그리고 나서 checklist 를 실행시키도록 한다.
[root@localhost md5]# ./makelist [root@localhost md5]# ./checklist 파일검사 : 1.txt, OK파일검사 : 2.txt, OK파일검사 : 3.txt, OK파일검사 : 4.txt, OK파일검사 : 5.txt, OK... |
파일검사 : 1.txt, WARN : 파일변조 fb20e95d00a91f81936f84dc0fb3f770 => 7e8d5617272c76ad7ef16a113f50ed79파일검사 : 2.txt, 파일검사 : 3.txt, |
3절. 결론
이상 간단하게 파일변조를 검색하는 방법에 대해서 알아보았다. 위의 내용에 대해서 이해를 했다면 - 이해하고 말것도 없는 간단한 내용이지만 - 다양한 용도로의 응용이 가능할것이다. 이러한 응용은 여러분의 몫이 될것이다
'UNIX_LINUX_C_C++' 카테고리의 다른 글
라이브러리및 컴파일 하기 (0) | 2011.10.16 |
---|---|
[FreeTDS] freetds 설치- 리눅스 apache, php 에서 mssql connecting 하기 (0) | 2011.10.16 |
unix 파일구조/파일탐색 (0) | 2011.10.16 |
정규표현식 java(?) - 표현식예제 (0) | 2011.10.16 |
정규표현식이란 (0) | 2011.10.16 |