FC3 gate->iron_golem

Posted by dw0rdptr
2017. 4. 7. 17:56 System/FC3

/*
    The Lord of the BOF : The Fellowship of the BOF
    - iron_golem
    - Local BOF on Fedora Core 3
    - hint : fake ebp
*/
int main(int argc, char *argv[])
{
    char buffer[256];

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

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


소스는 매우 간단하지만 fedora성부터는 LOB와 달리 여러 보호 기법이 적용되어 있기 때문에 공격하기 훨씬 복잡해진다.

[환경 요약]
Stack Dummy : O
Down privileage of bash : O
Random Stack : O
Random Library : X
Random Program Binary Mapped : X
ASCII Armor : O
Non-Executable Stack : O
Non-Executable Heap : O
Stack Carany : X
Stack Smashing Protector : X


몇개 간단하게 설명을 하자면

Random Stack,heap(ASLR) : 스택,힙에 할당되는 주소를 프로그램이 실행될때마다 랜덤으로 배치해 고정적인 메모리주소를 참조하지 못하게 하는 보호기법

Non-Executable Stack,heap(Nx bit) : 스택과 힙영역에서의 실행권한을 제거해 해당 영역 내에서 쉘코드를 실행하지 못하게하는 보호기법


ASCII Armor : 공유 라이브러리 주소의 최상위 비트를 \x00으로 매핑해 공유라이브러리 주소가 포함된 공격코드 실행 중간에 \x00을 NULL값으로 인식하고 이를 기점으로 실행을 중단하게 만드는 보호기법. 때문에 RTL뒤에 인자전달이나 연속호출이 불가능

위의 보호기법때문에 스택내에서 직접 쉘코드를 실행시키는 공격기법과 일반적인 RTL공격은 불가능하게된다.


hint에 fake ebp가있어 fake ebp로 풀겠다.

ASCII Armor -> ASCII Armor가 적용되지 않는 got영역을 실행
ASLR -> fake ebp로 고정적 인자 참조가능


GOT는 나중에 ROP기법에서 매우 중요하게 쓰인다. PLT와 함께 미리 공부해두자

PLT (Procedure Linkage Table) :  함수 첫 호출시 함수의 실제주소를 알아내 호출 후 GOT에 함수주소 저장. 두번째 호출시 GOT에 저장된 주소를 참조해 함수호출

GOT (Global Offset Table) : 실제 함수 주소를 저장하는곳

PLT GOT 자세히알기 : https://bpsecblog.wordpress.com/2016/03/09/about_got_plt_2/


공격 시나리오는 이렇다

1. ASCII Armor가 걸려있지 않은 got영역을 이용한다.

2. fake ebp로 ebp를 got주소로 이동시킨다. 

3. got로 쉘을 실행시키는 프로그램을 심볼릭 링크로 연결해 최종적으로 쉘을 딴다.

gdb로 스택구성을 먼저 보자
| buffer[256] | dummy[8] | sfp[4] | ret[4] |
로 구성되어 있다.



구해야 하는것 : got.plt, execl 주소
execl : 0x00715720  (ASLR기법으로 첫바이트가 00임)
got.plt : 0x08049618



0x804954c <_DYNAMIC> : 0x00000001

got를 호출하면 0x00000001을 참조하는데, 이때 마지막바이트가 '\x01'이면 작성한 exploit 프로그램이 실행되게 심볼릭링크를 만들어준다.


쉘을 실행하는 exploit 프로그램

got에서 0x00000001 가 실행되면 exploit 프로그램이 실행된다.
그럼 공격 성공

그렇다면
| dummy[264] | &GOT | &execl |
이 페이로드가 되겠지만 이대로 공격을 해도 쉘이 따지지 않는다. execl의 프롤로그와 에필로그 과정에서 ebp와 esp를 건드리게 되고 fake ebp가 제대로 성공하지 않기 때문. 공격이 성공하려면 이러한 과정을 고려해야 한다.
 

execl의 첫부분이다. 기껏 fake ebp로 ebp를 got로 보내버렸는데

push %ebp / mov %esp,%ebp(프롤로그) 과정을 거치면 ebp가 엉뚱한데로 가버린다. 그래서 이부분을 무시하기위해 execl+3을 페이로드에 쓴다.

또 이 함수가 끝날때 leave / ret (에필로그) 부분에서 esp를 ebp로 옮기고 pop을 두번 수행하는데 이렇게되면 got+8주소가 실행된다. 때문에 페이로드에서 got-8을 쓰면 정상적으로 got를 실행하게 되는 것이다.

페이로드
| dummy[264] | &GOT-8 | &execl+3 |

./iron_golem `python -c 'print "A"*264 + "\x10\x96\x04\x08"+"\x23\x57\x7a\x00"'`

 









의문점 :

execl함수를 쓰는 이유는 아마 프로그램 실행권한을 가진 함수라 작성한 exploit 프로그램을 iron_golem 권한으로 실행시켜주기 때문인거 같은데.. 같은기능인 system함수로는 되지 않는다. execv함수로도 공격이 성공했는데 execl, execv와 system의 차이가 무엇인지 더 공부해야겠다.


결론 :

system함수는 exec와 fork의 조합이다. exec는 새로운 프로세스를 실행시킬때 현재 프로세스 메모리 공간에 덮어쓴다.

반면에 system은 fork로 새로운 자식 프로세스를 생성후 exec를 호출해 명령어를 실행하는 구조이다. 아마 system으로 공격이 실패한 이유가 이러한 차이때문인 것 같다.


'System > FC3' 카테고리의 다른 글

FC3 evil_wizard->dark_stone  (1) 2017.04.07
FC3 hell_fire->evil_wizard  (0) 2017.04.07
FC3 dark_eyes->hell_fire  (0) 2017.04.07
FC3 iron_golem->dark_eyes  (0) 2017.04.07