About

Check the home directory of flag03 and take note of the files there.

There is a crontab that is called every couple of minutes.

To do this level, log in as the level03 account with the password level03 . Files for this level can be found in /home/flag03.

Source code

There is no source code available for this level


문제의 핵심부터 살펴보자.


crontab에 설정되어 있는 문제 파일을 이용 해 쉘을 획득하라.


문제의 디렉토리로 가보면 쉘 스크립트로 보이는 파일이 하나 존재하며 소스를 보면 다음과 같이 되어 있다.


[그림 1 - 쉘 스크립트]


코드 자체는 단순하다. writable.d  디렉토리의 파일 이름을 가지고 와 일정시간에 주기적으로 bash -x [writable.d의 파일명] 명령을 수행하고 명령을 수행한 파일은 삭제하는 스크립트이다. 그렇다면 우리가 실행해야 할 명령은 writable.d 디렉토리에 파일이름으로 존재해야 한다. 하지만 일반적인 명령어를 파일 이름으로 지어 저장해 둔다고 하여도 level03 쉘에는 영향을 미치지 못한다. writable.sh는 level03 쉘에서 실행되는 것이 아니기 때문이다. 쉘 스크립트를 이용해 우리가 level03 계정에서 실행해 줄 또 하나의 파일을 만들어야 한다. 이 문제는 flag03의 쉘을 획득하는 것이 목표이니 우리가 어떤 파일을 실행했을 때 flag03 계정의 쉘이 띄어지는 프로그램을 만들어 flag03의 권한으로 실행되게끔 해보도록 하자. 일단 flag03의 권한으로 설정 해 쉘을 띄어주는 프로그램의 소스이다.


[그림 2 - flag03의 쉘을 띄어줄 프로그램 코드]


이 파일을 flag03의 권한으로 컴파일하고 flag03의 SUID를 걸어주고 우리가 실행을 시킨다면 우리는 flag03의 쉘을 획득 할 수 있을 것이다. 


[그림 3 - bash 명령 파일 생성]


gcc를 직접 파일명으로 하지 않은 이유는 -o 옵션으로 인해 touch 명령이 실행되지 않기 때문에 생성이 되질 않는다. 또 bash의 -x 옵션으로 인해 명령이 확장되면서 위처럼 할 경우 bash 파일이 실행되면서 gcc 명령도 같이 실행된다.

위 코드를 간단히 설명을 하자면, writable.sh 스크립트가 실행되면서 bash -x bash 명령을 실행하게 된다. bash 파일에는 gcc 명령이 들어있고 컴파일이 완료되면 chmod로 생성된 실행파일에 SUID와 실행권한을 준다. 우리는 생성된 shell 실행 파일을 실행하면 되는 것이다.


[그림 4 - 쉘 획득]



About

There is a vulnerability in the below program that allows arbitrary programs to be executed, can you find it?

To do this level, log in as the level02 account with the password level02 . Files for this level can be found in /home/flag02.

Source code

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <stdio.h>

int main(int argc, char **argv, char **envp)
{
char *buffer;

gid_t gid;
uid_t uid;

gid = getegid();
uid = geteuid();

setresgid(gid, gid, gid);
setresuid(uid, uid, uid);

buffer = NULL;

asprintf(&buffer, "/bin/echo %s is cool", getenv("USER"));
printf("about to call system(\"%s\")\n", buffer);

system(buffer);
}


문제의 핵심은 이전 문제와 동일하다. 문제의 소스코드를 보게 되면 이전 문제에서는 /usr/bin/env echo 형식으로 되어 있어 echo만을 심볼릭링크 걸어 문제를 풀 수 있었는데 이번에는 /bin/echo로 되어 있어 level02 계정으로는 심볼릭 링크를 걸 수 없다. 그 대신 이전 문제와는 다르게 사용자에게 입력을 받을 수 있는 부분이 추가 되었다. 바로 USER라는 환경 변수이다. 이 부분은 level02 계정으로도 충분히 수정이 가능하므로 우리가 수정한 값이 프로그램의 입력 값으로 들어가게 될 것이다. 일단 실행 화면부터 살펴보자.


[그림 1 - 프로그램 기본 실행 화면]


USER 환경 변수를 수정하지 않았을 때는 사용자 계정 명이 들어가 있는데 이를 입력 받아 소스코드에 코딩되어 있는 루틴을 통해 [그림1]과 같이 출력 되는 것을 다들 예상 할 수 있었을 것이다. 이제 flag02 계정의 쉘을 띄어야 하는데 어떤 방법으로 접근을 해야 할까? 혹시 SQL Injection 해킹기법을 아는가? SQL Injection 기법은 기본적으로 다음과 같은 원리를 이용한다.


 1. 정상적인 SQL 쿼리문

      - Select user, pass from AccountTB where user='$user' and password='$pass';


 2. 정상적이지 않은 입력 값 '1' or '1'='1 입력

      - Select user, pass from AccountTB where user=''1' or '1'='1' and password=''1' or '1'='1';


 3. 서버에서는 SQL 쿼리문을 정상으로 인식


임의로 쿼리문을 참으로 만드는 문자열을 입력 해 쿼리문을 실행 시키는 것이 SQL Injection의 기본원리이다. 여기서 이와 비슷한 방법으로 쉘을 실행 시킬 수 있다. echo는 문자열을 stdout으로 출력 시키는 행위를 하는 명령이다. 이를 리다렉션 문자로 출력 방향을 표준 출력이 아닌 파일로 출력하고 해당 파일을 실행 파일로 만들어 실행 시킨다면 어떻게 될까? 만약 리다렉션 된 문자열이 쉘이라면? 이쯤이면 어느정도 감이 왔을거라 생각이 든다. 그럼 자신이 생각한 것과 필자가 한 것이 맞는지 한번 보기 바란다. 


[그림 2 - 명령 실행]


; 문자는 리눅스에서 여려 명령을 순차적으로 자동 실행하기 위해 사용하는 문자이다. 앞의 명령이 실행되고 ; 뒤에 문자가 차례로  실행되게끔 하는 것이다. 하드코딩 되어 있던 is cool은 쉘이 실행되면서 무시가 되어 프로그램 실행에 아무런 문제를 일으키지 않는 것을 볼 수 있다. 




요즘 NSHC의 취약적 분석팀(RedAlert)에서 여러가지 분석 보고서를 발행하고 있습니다. 요즘은 주로 BOF에 대한 문서가 자주 나오네요 ^^



20120724_Photodex_ProShow_Producer_v.5.0.3256_Local_BUffer_Overf


출처 : NSHC RedAlert

Level01의 문제는 다음과 같다.

About

There is a vulnerability in the below program that allows arbitrary programs to be executed, can you find it?

To do this level, log in as the level01 account with the password level01 . Files for this level can be found in /home/flag01.

Source code

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <stdio.h>

int main(int argc, char **argv, char **envp)
{
gid_t gid;
uid_t uid;
gid = getegid();
uid = geteuid();

setresgid(gid, gid, gid);
setresuid(uid, uid, uid);

system("/usr/bin/env echo and now what?");
}


문제의 핵심은 다음과 같다.

위 소스코드로 컴파일 된 프로그램을 이용해 다른 프로그램을 실행 시킬 수 있는가?


[그림 1 - 문제 프로그램의 권한과 소유자 정보]


결국 목적은 위 프로그램의 취약한 부분을 이용 해 flag00의 쉘을 띄우는 것이다. 소스코드를 보면 정말 간단한 소스코드라는 것을 알 수 있다. 프로그램의 SUID, GUID를 얻어와 얻어온 SUID, GUID로 설정 한 후 system() 함수를 실행 시킨다. 시스템 해킹에서 자주 볼 수 있는 패턴이다. 일단 우리가 공략 할 수 있는 부분은 system() 함수 부분밖에 보이지 않을 것이다. 일단 system() 함수에 인자로 들어가 있는 명령을 일반 쉘에서 실행시켜 보자.


[그림 2 - 일반 쉘에서의 명령 실행]


정상적으로 echo 명령이 실행 되는 것을 볼 수 있다. 그럼 echo 명령이 실행 될 때 쉘을 띄어주는 /bin/bash 명령이 실행 되면 어떻게 될까? flag01 계정의 쉘이 띄어지지 않을까? 충분히 가능한 일이다. echo 명령이 실행 될 때 /bin/bash 명령을 어떻게 실행해주어야 할까? 기본적으로 생각나는 방법은 심볼릭 링크가 있다. 명령이 실행 될 때 리눅스는 기본적으로 $PATH 환경변수에 설정 된 디렉토리 경로들을 검색하여 명령을 찾아 실행한다. 이때 echo 명령에 심볼릭 링크를 걸어두고 $PATH 환경 변수에 이 명령의 디렉토리 경로를 설정해 둔다면 echo 명령을 찾고 그 심볼릭 링크를 찾아 system() 함수가 최종적으로 찾은 명령을 실행 할 것이다. 


[그림 3 - /bin/echo의 권한과 사용자 정보]


한눈에 보더라도 심볼릭 링크를 현재 상황에서는 걸어 줄 수 없다는 것을 알 수 있을 것이다. 즉 우리는 새로운 echo를 만들어야 한다. 지금의 계정이 손쉽게 접근 할 수 있는 곳은 /tmp 이다. /tmp 디렉토리는 기본적으로 누구나 접근이 가능하도록 설정 되어 있기 때문이다. /tmp 디렉토리에 가짜 echo 프로그램을 만들고 시스템이 명령을 검색 할 시 /tmp 디렉토리에 echo 프로그램이 먼저 검색되도록 $PATH 환경변수 값을 수정하도록 하자.


[그림 4 - 환경 변수 설정]


지금까지는 완벽한 것처럼 보인다. 하지만 문제를 다시보면 and now what? 이라는 문자열이 존재한다. 해당 문자열을 어떻게 처리해주어야 하는 것일까? 만약에 지금까지의 시나리오대로 문제를 진행한다면 추후 system에서 수행되는 명령은 /usr/bin/env /bin/bash and now what? 이 되어버릴 것이다. 이는 맞지 않는 명령이다. 결국 echo 안에서 /bin/bash 명령을 실행해주어야 한다. 

[그림 5 - 부정확한 명령어]


여기서 필자는 간단한 쉘프로그래밍을 이용해 우리가 사용하려하는 echo 프로그램 내에서 /bin/bash 프로그램이 실행 되도록 하였다.


[그림 6 - 쉘 프로그래밍과 권한의 적절한 사용]


echo가 실행되게 되면 /bin/bash가 실행되고 실행 된 /bin/bash는 /tmp/echo2를 실행하도록 쉘 프로그래밍을 하였다. 또 /tmp/echo2 프로그램이 /bin/bash 프로그램을 가리키도록 하여 결국 system() 함수가 최종적으로 실행하는 명령은 /bin/bash 가 된다.


[그림 7 - flag01 쉘 획득]


'[+] Hacking > [-] Challenge Report' 카테고리의 다른 글

exploit-exercises Nebula - Level03  (0) 2012.07.26
exploit-exercises Nebula - Level02  (0) 2012.07.26
exploit-exercises Nebula - Level01  (0) 2012.07.25
exploit-exercises Nebula - Level00  (0) 2012.07.25
GitS CTF Packet 200 풀이  (1) 2012.06.29

Nebula는 리눅스에 기초적인 여러 문제들을 다루고 있다. Level00의 문제는 다음과 같다.


About

This level requires you to find a Set User ID program that will run as the "flag00" account. You could also find this by carefully looking in top level directories in / for suspicious looking directories.

Alternatively, look at the find man page.

To access this level, log in as level00 with the password of level00 .

Source code

There is no source code available for this level



문제의 요점은 다음과 같다.

flag00 계정의 SUID가 설정 된 프로그램을 찾아라.


level00으로 로그인 하기 위해서는 level00:level00 으로 로그인하면 된다. 로그인을 하게 되면 home 디렉토리가 보이게 되는데 문제에서는 flag00 계정의 SUID가 설정 된 프로그램을 찾으라고 했으니 home 디렉토리를 상관하지 말고 find 명령을 통해 다음과 같이 명령을 내리면 된다.


[그림 1 - 명령과 결과]


총 2개의 결과가 나오는데 /home/flag00은 flag00 계정의 home 디렉토리이기 때문에 문제 풀이와는 상관이 없다. 즉 일반적으로 실행 프로그램들이 위치하고 있는 /bin 디렉토리의 하위 디렉토리인 .../에 위치하고 있는 flag00 프로그램이 우리가 찾는 프로그램이다. 실행 할 경우 다음과 같은 메시지가 출력 된다.


[그림 2 - /bin/.../flag00 실행 결과]


메시지가 출력 되면서 쉘이 flag00의 쉘로 바뀐 것을 볼 수 있다. 메시지에서 지시하는 대로 getflag 명령을 수행하면 메시지가 출력 되면서 해당 문제의 목적이 달성되게 된다.


[그림 3 - getflag 명령 수행]



'[+] Hacking > [-] Challenge Report' 카테고리의 다른 글

exploit-exercises Nebula - Level02  (0) 2012.07.26
exploit-exercises Nebula - Level01  (0) 2012.07.25
exploit-exercises Nebula - Level00  (0) 2012.07.25
GitS CTF Packet 200 풀이  (1) 2012.06.29
RootBSD Forensic Challenge 풀이  (2) 2012.06.16

+ Recent posts