본문 바로가기

시스템

(8)
hackerschool FTZ : lv1 hint파일을 열어 level2 권한에 setuid가 걸린 파일을 찾으라는 문장을 확인할 수 있다. 먼저 setuid와 setgid 그리고 stickybit에 대해 알아보겠다. setUID와 setGID는 파일에 다른 계정과 그룹의 권한을 일시적으로 빌려주는 개념이다. setUID가 설정된 파일을 실행하게 되면 실행하는 동안은 그 파일의 소유자 권한을 지니게 된다. 예시를 통해 살펴보도록 하겠다. 그림과 같이 stickytest라는 파일을 만든 후 root만 사용할 수 있도록 권한을 준다. root만 사용할 수 있으므로 root가 아닌 계정으로 파일내용 출력을 시도하면 거부되는 것을 확인할 수 있다. uid와 euid를 출력하고 cat명령어를 통해 stickytest파일을 출력하는 stickybit.c파..
쉘코드를 이용한 Buffer Overflow (NOP Sled) 쉘코드를 이용해 버퍼 오버플로우 공격을 시험해보자. 시험을 위해서는 먼저 버퍼 오버플로우 취약점을 가진 프로그램이 필요하다. 위의 프로그램에서는 strcpy()를 사용하고 있다. strcpy()는 NULL Byte(문자열의 끝)를 만나기 전까지의 문자열를 복사하는 함수로 문자열의 길이를 검사하지 않는다. 따라서 256바이트에 해당하는 버퍼의 크기를 넘어서는 값을 입력하더라도 그대로 버퍼에 복사가 되므로 해당 프로그램은 버퍼 오버플로우 취약점을 가지게 된다. 위의 프로그램에서 버퍼 오버플로우가 일어나는 과정을 확인하기에 앞서 편의를 위해 메모리 보호기법 중 하나인 ASLR을 비활성하겠다. ASLR(Address Space Layout Randomization)이란 메모리상의 공격을 어렵게 하기 위해 프로그..
[시스템] 쉘코드를 작성해보자. [2] 저번시간에 이어서 setreuid를 이용해 root권한 획득과 exit(0)를 이용해 프로그램이 정상적인 종료가 되도록 만들어 보자. 먼저 root권한 획득에 대해 알아보자. sh03실행파일의 소유자와 실행권한이 각각 hd, 755인 것을 확인할 수 있다. chown명령어를 이용해 소유자를 root로 변경하고 chmod명령어를 이용해 파일에 대한 권한을 4755로 변경한다. 4755은 setuid bit를 설정하는 것을 의미한다. 원래의 8진수 퍼미션 설정에 4를 붙여 설정할 수 있으며, 4755로 변경시 실행권한이 -rwsr-xr-x로 변경된다. 이를 통해 실행시킨 사용자의 권한이 아닌 소유자의 권한으로 파일을 실행할 수 있게 된다. 설정을 마쳤다면 쉘코드를 통해 root권한 획득이 되는지 확인해보자...
[시스템] 쉘코드를 작성해보자. 쉘 코드란 쉘을 실행시키는 코드를 말하며, 쉘이란 실행파일을 실행시키거나 커널에 어떠한 명령을 내릴 수 있는 대화통로이다. 우선 쉘코드를 만들기 위해서 먼저 쉘을 실행시키는 프로그램을 작성해야한다. 이때 쉘을 실행시키는 프로그램은 C언어로 작성하며 컴파일을 통하여 어셈블리 코드로 변환 후 라이브러리에 종속적이지 않도록 만들어주어야 한다. 먼저 C언어로 작성한 쉘 실행 프로그램은 다음과 같으며, 프로그램을 실행시키면 쉘이 실행되는 것을 확인할 수 있다. execve()를 통해 쉘을 실행시키는데 execve()란 바이너리 형태의 실행파일이나 스크립트 파일을 실행시키는 함수이다. execve()가 어떠한 동작을 하는지 내부를 살펴보도록 하자. 이 프로그램에서의 execve()는 Dynamic Link Libr..
[리눅스] -mpreferred-stack-boundary=2 프롤로그부터 시작하지 않는다. 그냥 마음한켠이 불편하다. 논리주소 또한 프롤로그가부터 시작하지 않는다. 그냥 마음한켠이 불편하다. gcc로 컴파일할때 -mpreferred-stack-boundary=2 옵션을 줘보자. (편안..)
[시스템] Stack Frame (스택 프레임) 어셈블리를 통해 스택프레임의 생성과 소멸의 과정에 대해 살펴보자. 예제코드는 다음과 같다. 다음은 gcc명령어를 통해 컴파일한다. gcc -m32 -fno-stack-protector -mpreferred-stack-boundary=2 -no-pie -fno-pic -o stackframe stackframe.c 옵션을 하나하나 살펴보자. -m32 : 32bit로 컴파일 -fno-stack-protecotr : 버퍼오버플로우가 발생했을 때 gcc는 canary를 이용해 버퍼오버플로우가 발생한 것을 감지하고 프로그램을 종료하는데 우리는 이를 SSP(Stack Smashing Protection)라 부르는데 이러한 보호기법(SSP)을 off한다. -mpreferred-stack-boundary=2 : 32b..
[시스템] Prologue / Epilogue (프롤로그 / 에필로그) 프롤로그의 사전적 정의는 음악 및 이야기 또는 영화등의 도입부를 의미한다. 스택구조에서도 프롤로그는 사전적의미와 유사한 의미를 가진다. 바로 함수의 시작을 말한다. (시작은 곧 구분을 의미한다.) 프롤로그가 일어나기 전 스택에서는 2가지 값이 먼저 쌓이게 되는데 이는 다음과 같다. RET SFP 먼저 RET부터 알아보자. 함수가 호출되면 스택에는 먼저 함수가 모든 일을 마치고 돌아갈 주소를 저장한다. 즉, push eip가 일어나는데 우리는 이를 RET라고 부른다. 여기서 eip(Extended Instruction Pointer)란 다음 명령어가 저장되어 있는 주소를 가리키는 포인터를 말한다. 그림으로 살펴보면 다음과 같다. 그림을 통해 조금 더 쉽게 설명하자면 func1함수를 호출하면 다음 명령어의 ..
메모리 구조 [Memory Structure] 메모리는 크게 커널영역과 유저영역으로 나뉜다. 유저영역은 다시 스택영역, 힙영역, 데이터영역, 코드영역으로 나뉘며, 유저영역을 제외한 영역을 커널영역이라고 한다. 커널영역에는 커널(kernel)이 위치하고 있으며 이 커널은 컴퓨터의 운영체제의 핵심이라고 할 수 있다. 커널은 시스템의 모든 것을 완전히 통제하기 때문에 사용자(유저모드)가 직접 접근할 수 없으며, 접근 시 system call을 통한 커널모드로의 전환이 필요하다. 유저영역은 스택영역, 힙영역, 데이터영역, 코드영역으로 나뉜다. 엄밀히 말하자면 하나의 프로세스를 묶어 놓은 세그먼트(Segment)가 존재하는데 이 세그먼트가 스택영역, 힙영역, 데이터영역, 코드영역으로 이루어져 있는 것이다. 즉, 프로세스마다 스택영역, 힙영역, 데이터영역, 코..