[문제풀이] Nebula, Level09, Level10 Wargames/e-exercises.com2017. 7. 19. 09:49
※ LEVEL 09
Q. There’s a C setuid wrapper for some vulnerable PHP code…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | <?php function spam($email) { $email = preg_replace("/\./", " dot ", $email); $email = preg_replace("/@/", " AT ", $email); return $email; } function markup($filename, $use_me) { $contents = file_get_contents($filename); $contents = preg_replace("/(\[email (.*)\])/e", "spam(\"\\2\")", $contents); $contents = preg_replace("/\[/", "<", $contents); $contents = preg_replace("/\]/", ">", $contents); return $contents; } $output = markup($argv[1], $argv[2]); print $output; ?> | cs |
A. 여기는 /e modifier의 기능으로 발생되는 취약점이다.
e(PCRE_REPLACE_EVAL) modifier
이 변경자를 지정하면 preg_replace()는 변경할 문자열을 PHP 코드로 처리하고, 그 결과를 검색된 문자열을 이용하여 일반적인 치환을 한다. 작은 따옴표, 큰 따옴표, 백슬래시와 NULL 문자는 백슬래시로 이스케이프된다.
preg_replace()만 이 변경자를 사용하고 다른 PCRE 함수는 무시한다.
출처 : http://php.net/manual/kr/reference.pcre.pattern.modifiers.php
지금은 preg_replace 함수에서 지원되지 않는 변경자란다. 대신 preg_replace_callback 함수를 사용하라는디~
(e modifier : This feature was DEPRECATED in PHP 5.5.0, and REMOVED as of PHP 7.0.0)
그럼 문제풀이로 들어가보도록 하겠다.
[그림 1] e modifier 테스트
인터넷에 찾아보니까 크게 두가지로 명령어를 실행시키는 것 같았다. 그래서 일단 테스트 목적상 php 파일을 만들어놓고 동작시켜보았다.
[그림 2] 테스트 결과
결과는 두 가지 방법 모두 실행되었다.
[그림 3] 문제풀이 실행
하지만 실제 문제에 대입하였을 때에는 ` ` 로 감싸는 방식의 명령어 실행은 동작하지 않았다. 뭐가 문제인지 모르겠다.
[그림 4] 플래그 획득
사실 치환 대상이 되는 문자열이라서 PHP 엔진이 다르게 인식하는 지 몰라도 실제 PHP 파일에서는 {${ }} 와 같은 대괄호를 씌우지 않고 단순히 system(sh) 라고만 하여도 실행이 되더라. 물론 파싱하는 과정에서 e modifier가 인식할 수 있도록 도와주는 지시자일 것이라 어림짐작은 하고 있다만..
(정확한 원인에 대해 아시는 분이 있다면 알려주시길 바랍니당 -ㅅ-)
※ LEVEL 10
Q. The setuid binary at /home/flag10/flag10 binary will upload any file given, as long as it meets the requirements of the access() system call.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <stdio.h> #include <fcntl.h> #include <errno.h> #include <sys/socket.h> #include <netinet/in.h> #include <string.h> int main(int argc, char **argv) { char *file; char *host; if(argc < 3) { printf("%s file host\n\tsends file to host if you have access to it\n", argv[0]); exit(1); } file = argv[1]; host = argv[2]; if(access(argv[1], R_OK) == 0) { int fd; int ffd; int rc; struct sockaddr_in sin; char buffer[4096]; printf("Connecting to %s:18211 .. ", host); fflush(stdout); fd = socket(AF_INET, SOCK_STREAM, 0); memset(&sin, 0, sizeof(struct sockaddr_in)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = inet_addr(host); sin.sin_port = htons(18211); if(connect(fd, (void *)&sin, sizeof(struct sockaddr_in)) == -1) { printf("Unable to connect to host %s\n", host); exit(EXIT_FAILURE); } #define HITHERE ".oO Oo.\n" if(write(fd, HITHERE, strlen(HITHERE)) == -1) { printf("Unable to write banner to host %s\n", host); exit(EXIT_FAILURE); } #undef HITHERE printf("Connected!\nSending file .. "); fflush(stdout); ffd = open(file, O_RDONLY); if(ffd == -1) { printf("Damn. Unable to open file\n"); exit(EXIT_FAILURE); } rc = read(ffd, buffer, sizeof(buffer)); if(rc == -1) { printf("Unable to read from file: %s\n", strerror(errno)); exit(EXIT_FAILURE); } write(fd, buffer, rc); printf("wrote file!\n"); } else { printf("You don't have access to %s\n", file); } } | cs |
A. 본 문제는 레이스 컨디션에 관련된 문제이다.
즉 access 함수로 접근 가능 여부를 판단하고 open 함수로 파일을 여는 시간 차이를 활용한다.
[그림 5] token 파일 접근 권한
본 워게임은 token 파일의 내용을 얻어야 하는데 보시다시피 읽기 권한이 없는 것을 알 수 있다. 따라서 조금 전에 말한 바와 같이 우리는 두 함수가 실행되는 그 차이를 이용해서 token 파일을 읽어올 것이다.
간단히 순서는 !
1. fake_token 파일 생성
2. fake_token 파일과 token 파일을 링크할 링크 파일 생성
3. 포트 오픈
4. flag10 실행 파일의 인자로 2번에서 생성한 링크 파일을 제공
위 순서를 계속 반복할 것이다.
[그림 6] 파일 생성 및 링크
[그림 7] flag10 실행
[그림 8] token 획득
[그림 9] 플래그 획득
이상~!
'Wargames > e-exercises.com' 카테고리의 다른 글
[문제풀이] Nebula, Level15 (0) | 2017.07.25 |
---|---|
[문제풀이] Nebula, Level13, Level14 (0) | 2017.07.23 |
[문제풀이] Nebula, Level11, Level12 (0) | 2017.07.21 |
[문제풀이] Nebula, Level05, Level06, Level07, Level08 (0) | 2017.07.16 |
[문제풀이] Nebula, Level00, Level01, Level02, Level03, Level04 (0) | 2017.07.15 |