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은 쉘이 실행되면서 무시가 되어 프로그램 실행에 아무런 문제를 일으키지 않는 것을 볼 수 있다. 




+ Recent posts