소스가 많이 길어졌습니다 .

// gain address of execve

fp = popen("/usr/bin/ldd /home/giant/assassin | /bin/grep libc | /bin/awk '{print $4}'", "r");

fgets(buffer, 255, fp);

sscanf(buffer, "(%x)", &lib_addr);

fclose(fp);

/home/giant/assassin 파일을 idd로 공유라이브러리를 확인한후에 libc(표준라이브러리) 를 grep으로 출력하고 그중에 4번째 열(libc 라이브러리의 주소)를 popen함수를 통해서 fp로 넘긴다 

 fp = popen("/usr/bin/nm /lib/libc.so.6 | /bin/grep __execve | /bin/awk '{print $1}'", "r");

        fgets(buffer, 255, fp);

        sscanf(buffer, "%x", &execve_offset);

        fclose(fp);

libc.so.6 오브젝트 파일에서 nm을 통해 심볼들을 출력하고 grep을 통해 execve함수만 출력하도록 하고 이중에서 execve의 오프셋을 출력한다


그리고 맨 아래를 보니 you must use execve라는 문구와 ret !=execve_addr 을 보니 ret에다가 반드시 execve의 주소를 사용해야 하는거 같다 


난이도가 저한테는 상당히 어려운거같습니다 . 

/home/giant/assassin파일은 역시나 권한이 할당되지 않았습니다 .

gain address of execve 인것을 보아하니 execve에 대해서 먼저 파악을 해봐야겠습니다 

execve는 리눅스 시스템 호출 함수네요 (프로그램을 실행합니다)

int execve (const char *filename, char *const argv [], char *const envp[]);

사용법 ? 구조는 이런식으로 되있습니다 . 

execve는 filename이 가리키는 파일을 실행하는데 filename은 바이너리 실행 파일이거나 #! interpreter [arg]와 같은 라인으로 시작하는 스크립트 파일이어야 합니다.

argv는 새로이 실행할 프로그램에 전달하는 인수 문자열의 배열입니다 
envp는 보통 key=value와 같은 형태로 문자열 배열이고 환경 변수를 설정해놓은 것처럼 전달됩니다 . argv와 envp는 모두 NULL 포인터로 끝나야만 합니다.

만약 filename이 가리키는 실행 파일의 set-uid 비트가 설정되어 있다면 호출한 프로세스의 실질적인 사용자 ID(uid)는 실행 파일의 소유자로 바뀝니다 
(여기서 execve를 RTL과 어떻게 엮어서 사용해야할지 대충 느낌이 갑니다)

먼저 execve의 주소를 구해보겠습니다 

execve는 라이브러리 함수입니다 . 라이브러리의 주소는 어떠한 파일(?)에서 열든지 주소가 동일합니다 . 먼저 그러면 tmp파일에 복사한 후 execve의 주소와
원래 문제상에서 제시한 얻는 방법인 execve_addr = lib_addr + (int)execve_offset
두개를 비교해서 봐보겠습니다 .


새로운 파일에서 얻은 execve주소 입니다 그렇다면 이번엔 원래 문제에서 제시한 얻
는 방법을 시도해보겠습니다

여러번 시도 해본 결과 저런식으로 lib_addr의 주소를 얻었습니다
이번엔 execve_offset을 얻어보겠습니다 

어찌 저찌 구햇으나 grep 명령어를 좀 더 공부해야될거같습니다..
0x40018000+00091d48을 더해야되는군요 음 

손수 계산했습니다 ㅎㅎㅎ 귀엽군요 아까 구한 execve의 주소와 맞아 떨어지는것을 확인했습니다 .
혹시나 싶어서 저 주소로만 공격을 해보겠습니다 

역시 안되는군요 

int execve (const char *filename, char *const argv [], char *const envp[])

execve의 이러한 구조를 이용해야겠습니다 . 

멍청하게 filename 을 giant 파일 이름의 주소를 찾아서 공격시도를 해보고잇었습니다-_-;;;;;;;;;; 저기 위에 filename은 바이너리 실행 파일이거나 하고 써놧네요 

뭔가 giant의 이름 주소를 공격하는건 아닌거같아서 좀 찾아봤습니다 

filename에 /bin/sh를 넣어주고있네요 

그럼 파일 네임부분에는 /bin/sh의 주소를 넣고 .. - 

execve에 대한 정보가 더 필요할거같아서 자료를 찾던 와중에
execve 항목에 보면 path에 지정한 경로명의 파일을 실행하고 argv와 envp를 인자로 전달한다 라는 항목을 보고 퍼뜩 떠올라 공격을 해보겠습니다

나름 회심의 공격이였는데 실패했습니다 . 뭐가 문제인걸까요 많이 어렵습니다 

gdb로 확인해보자는 마음으로 coredump를 시도해봤으나 역시나 실패했습니다 .


일반 gdb로 스택을 확인해보려고 했습니다

245즈음에 브레이크 포인트를 잡아 준후에 아까 
오류가 떳던 바로위에 스크린샷을 실행시켰습니다

기존 프로그램이 아니므로 assassin을 찾을 수 없다는 문구와 함께 역시 이 방법이 아닌가 하면서 gdb를 솔직히 두번 껏다가 다시 켰습니다 -_-; 스택을 확인해보겠습니다


놉코드를 넣어준 지점이 보여서 일일히 눈으로 하나하나 비교해가면서 확인을 했습니다.. 그러던 와중에 

이럴수가 /x48/x9d/x0a/x40 에서 0a가 사라져있습니다 .
전 또 그 짜증나는 bash의 짓이라고 예상하고 명령어들을 쳐도 무용지물 이였습니다
소스는 함정이고 0a를 어떻게 살리느냐가 이 문제의 핵심인가 하고 생각했습니다 

구글링으로 리눅스 0a.. 어셈블리 0a를 검색하던도중에 헥사코드로 0x0a는

문자로 줄바꿈을 한다고 합니다 그래서 없어진걸까요 ? 

심볼릭링크를 시도햇으나 마지막에 null 주소를 줬기에 만들어지지 않습니다.

https://wikidocs.net/13

ftz - level3에서 느낌을 받았습니다 
개행문자 결국 c로 보면 \n이지요 이걸 근데 level3에서 햇던거처럼 문자열로 묶어서 전달하면 주소 그 자체 0a로 읽히는게 갑자기 생각나서 시도하고 성공했습니다
이렇게 푸는게 제대로 푸는건가 싶긴 하지만.. 권한은 얻었습니다!


'해커스쿨 lob' 카테고리의 다른 글

LOB zombie_assassin  (0) 2016.05.16
LOB assassin  (0) 2016.05.13
LOB bugbear  (0) 2016.05.12
LOB darkknight  (0) 2016.05.11
LOB golem  (0) 2016.05.10

+ Recent posts