본문 바로가기

코딩 문제/해커스쿨

FTZ : level12

728x90

cat hint로 hint를 확인해준다.

level11과 유사한 hint인 것 같다.

그럼 이 문제도 BOF를 이용하여 푸는 문제라는 것이다.

한번 attackme를 실행해본다.

위의 코드와 같이 문장을 입력받으면

입력받은 문장을 그대로 출력하는 실행파일이다.

 

자꾸 이런 BOF문제가 나오는데 BOF에 대해

공부를 한번 해보겠다.

 

[ Memory Corruption 취약점 ]

예상되지 않은 메모리 값 변경, 참조 등에 의해서 발생한다.

대부분 안전하지 않은 함수의 사용, 잘못 된 함수 사용 등 프로그래밍 실수로 인해 발생한다.

대표적으로 BOF취약점이 있다.

 

[ BOF 공격 ]

버퍼란 데이터를 일시적으로 저장해두는 메모리 상의 공간을 의미한다.

BOF는 프로세스가 데이터를 버퍼에 저장할 때 원래 크기보다 초과되는 데이터를 입력하면

정상적인 경우에는 사용되지 않아야 할 영역에 데이터가 덮어씌워지는 것을 의미한다.

 

[ BOF에 취약한 대표적인 함수 ]

strcpy, strcmp, gets, scanf, strcat, getwd, sprintf 등

 

그럼 level11과 같이 tmp에 attackme 실행파일을 복사한 후

GDB 디버거를 이용하여 한번 살펴 보겠다.

이 문제는 gets함수로 입력을 받아서 printf함수로 출력을 하기 때문에

gets 함수 바로다음(main+61)에 break를 걸어서 주소를 확인해야겠다.

RET가 시작되는 주소는 0xbffff9d0이라는 것을 알 수 있다.

이유는 A가 16진수로 0x41이므로 AAAA는 0x41414141이 되기 때문이다.

GDB 디버거를 종료한 후 vi명령을 통해 파이썬 코드를 한번 짜주자.

일일히 타이핑 해도 괜찮지만 너무 길기 때문에 간편하게 하기 위해 인터넷 검색을 통해

짜는 법을 확인했다.

우선 이 코드를 설명 드리자면

import struct는 struct 뮤듈을 이용한다는 의미이다.

struct 모듈은 C구조체의 값을 파이썬에서 사용하는 데이터 값으로 변경하기 위하여 제공되는 파이썬 모듈이다.

 

그리고 a의 구조를 Nop + 쉘코드 + Nop + RET로 한 이유는

처음에 Nop + 쉘코드 + RET로 했을 때 안되길래

검색을 해보니 컴퓨터가 가끔 쉘코드 + RET를 그냥 쉘코드 하나로

인식할 때가 있다고 하여서 배치를 저렇게 하였습니다.

 

lambda x: 의 의미는 x를 이용한 함수를 사용하겠다는 것을 의미한다.

뒤의 struct.pack("<L", x)의 의미는 x를 리틀 엔디안으로 표시한다는 의미이다.

 

엔디안이란 바이트 순서란 뜻이며

순서에 따라 빅 엔디안과 리틀 엔디안으로 나누어 진다.

빅 엔디안과 리틀 엔디안의 차이는 위 그림을 보면 된다.

파이썬 코드를 완성했으면 이제 공격을 한번 해보자.

하나씩 하는 것이 귀찮아서 4번씩 실행을 시켜보았다.

 

;로 연결한 이유는 여러개의 명령어를 동시에 실행할 때

&&를 사용하면 앞의 명령어가 실패하면 뒤의 명령어들은 실행이 되지 않지만

;를 사용하면 앞의 명령어의 성공/실패 여부와 상관없이 뒤의 명령어가 실행되기 때문이다.

 

위의 (python a.py;cat)|./attackme를 풀어주자면

우선 (python a.py;cat)의 결과값을 ./attackme의 입력값으로 주기 위해 | 를 사용하였다.

python a.py는 a.py를 실행하는 것을 의미한다.

;cat을 사용한 이유는 밑의 그림으로 설명하겠다.

하다보면 알겠지만 Segmentation fault가 발생하기도 하는데 이는

ASLR 기법이 적용 되어 있기 때문이라고 한다.

[ ASLR 기법 ]

프로세스의 가상주소공간에 어떤 Object 가 매핑될 때, 그 위치를 프로그램 실행시마다

랜덤하게 변경하는 보안 기법을 의미한다.

 

또한 Illegal instruction가 발생하기도 하는데 이는

GDB에서의 주소와 실제 실행 시의 주소의 차이 때문에 발생하는 것이므로

주소를 증감 해 가며 올바를 주소를 찾아야 한다.

만약 Illegal instruction가 발생하면 다시 vi a.py를 실행시켜

보이는 RET의 주소를 UP/DOWN하며 일일히 찾아 주어야 된다.

수 많은 노가다 끝에 Enter을 눌렀을 때

오류가 뜨지않으면 id명령어를 입력하여

uid가 level13인지 확인하고 level13이면 my-pass 명령어를 이용하여

다음레벨의 Password를 얻으면 된다. 

 

'코딩 문제 > 해커스쿨' 카테고리의 다른 글

FTZ : level14  (0) 2019.07.13
FTZ : level13  (0) 2019.07.08
FTZ : level11  (0) 2019.06.29
FTZ : level10  (0) 2019.01.22
FTZ : level9  (0) 2019.01.19