[해커스쿨 ftz] level 12 -> level 13

2014.08.22 17:40

hint 

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>


int main ()

{

char str[256];


setreuid(3093, 3093);

printf("문장을 입력하세요.\n");

gets(str);

printf("%s\n", str);

}



풀이

1. RTL 방법으로 풀이한다.

1-1 $ cp attackme ./tmp/attackme

1-2 $ gdb attackme

1-3 (gdb) b *main+3

1-4 (gdb) print system

1-5 (gdb) print exit


(RTL은 Return to Libc 의 약자로 리턴 주소를 공유 라이브러리 함수의 주소로 적어 해당 함수를 실행시키는 방법이다. 스택의 구조를 생각해보면 system() 함수를 ret주소에 써주면 프로세스가 종료되고 리턴할 때 system()함수로 가게 된다. 또한, system() 함수가 끝나게 되면 그 다음 4바이트가 리턴주소이기 때문에 정상적으로 종료될 수 있게 하기 위해 exit()함수를 써준다.

system()함수를 사용하는 이유는 쉘을 실행해주는 함수이기 때문이고 쉘을 실행할 수 있는 다른 함수를 사용해도 된다. 

또한, 인수로 /bin/sh를 넣어주는데, 위치는 스택 구조에서 매개변수는 ret주소 다음에 위치하기 때문에 결국 스택 모양을 다음과 같이 만들면 된다. 

low address ... | [sfp] |[ret] system() | exit() | "bin/sh" | ...  high address

)



2. "/bin/sh" 주소 구함


system() 함수는 내부적으로 /bin/sh를 실행하고 동작하는 함수이기 때문에 "/bin/sh" 문자열을 내부에 가지고 있으므로, system()함수의 주소부터 주소값을 증가해가며 찾을 수 있다.




3. 공격 명령어 작성

smleenull WARGAME/hackerschool ftz,lob

  1. 감사합니다 :)! 저 코드가 무슨 일을 하는지 몰랐는데 알게되었네요 !

  2. 어떤 코드 말씀하시는지요?? ㅎㅎ

  3. 메모라에서 bin\sh를 찾는 코드가 보이길레 먼가햇는데 그런 용도로 쓰엿던거군요 :)

  4. 아 ㅎㅎ 저도 그 코드는 어떤 문서에서 참고한건데 출처를 안써놔서 부끄럽네요 ㅠㅠ

  5. #include <stdio.h>

    int main (int argc, char *argv[])
    {
    long sh = 0x40058ae0; //system()의 주소
    while(memcmp((void*)sh, "/bin/sh", 8)) sh++;

    printf("address is %p\n", sh);

    return 0;
    }

  6. 감사합니다

티스토리 툴바