ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • File Stream Pointer에 관한 글
    Hack/Pwnable 2017. 1. 24. 14:53

    일단 글 쓰면서 생각하는건 내일 일본을 가는데 저가 항공이여서 비행기 사고가 날 가능성이 있어 이렇게 유적을 좀 남기고자 함


    Exploit을 다루지는 않을거같다.. 아직 문제가 몇개없고 최근에 풀어본문제가 pwnable.tw의 '어떠한' 문제인데, 워게임은 삽질해가면서 배우는거고, 풀이는 공식적으로 공유하지않는게 예의, 코래서 해당 주제로 작성된 한글문서도 없고 외국문서도 많이없길래 한번 작성해보려고 해요


    File Stream Pointer는 일단 기본적으로 알고있듯이 파일로 버퍼를 슥삭슥삭하는 거다. fopen,fwrite,fread 등 수 많은 함수가있지만 이걸 다 적기엔 모든 함수를 다 사용해봐야 해서 이게 fp를 얻었을때 어떻게 동작하는지 볼 예정...


    여기서 다루는 모든 예제는 16.04 LTS 환경에서 다루는 것..




    코드 자체는 별거 없이 읽고 출력하는 내용이다.


    이걸 이제 디버깅 해가면서 볼것임!





    저 인스트럭션이 실행되면 fp는 file의 임시버퍼포인터를 가질거임




    저 주소가 뭔 주소인지, 어떠한 데이터가 들어가있는지 보겠3!



    저 주소의 베이스 주소를 보면 HEAP 주소인것을 알 수 있다.


    다른버전에서는 모르겠지만 우선 16.04에서는 file의 버퍼는 heap에 작성되는것을 알 수 있었음


    16.04는 스트링을 다루는 몇개의 함수가 heap에 임시버퍼를 할당한다.


    fread가 안된 상태에서, 어떠한 데이터가 작성되어있는지를 볼것이다!!



    우선 우리가 아는, heap chunk가 생성되고 그안에 데이터가 관리 된다.


    이제 여기서 봐야할것은, size들은 중요하지않고, 그다음인 fbad가 어떠한 플래그인지 확인을 해볼것임


    /usr/include/libio.h 를 확인 해보면 된다.



    매크로로 플래그들이 선언되어있는데, 0xFBAD는 매직값인것을 알 수 있고, 0xfbad2488 값을 가지고있었으니 마지막값은 NO_WRITES를 가리킨다.


    fopen("flag,"r")을 줬으니 당연히 NOWRITE겠지만!? 자이제 0x80인데, IO_LINKED란다. 이렇게 설명하지말고 요약으로 간단 정렬!



    0xfbad2488


    _IO_NO_WRITES

    _IO_LINKED,

    _IO_TIED_PUT_GET

    _IO_IS_FILEBUF


    이렇게 플래그가 구성되어있다. 그럼 저 파일버퍼에 저값이 왜 쓰여진지 이해했고, 그 다음 요상한 포인터값들이 있다. (아직 별로 안중요)


    여기서! fread를 통해 파일을 읽어보았다.



    힙에 막 요상한 주소들이 써져있는데 좀만 밑에내려가보면 존재한다. 저 포인터값들은 fread를 하되, 저 값에 read값이 저장되게 한다.



    buf에도 저장되고 힙 임시버퍼에도 저장되는 아주 쩌는 16.04 캬~


    코건 됬고, 제일 중요한걸 언급해보려하는데, file 함수를 쓰게되면 무조건 iO_FILE_JUMPS라는 vtable이 생성된다.


    이게 뭔지 라이브러리를 직접 분석해보자!




    IO_file_jumps는 여러개의 함수가 존재하는데, 만약 fread가 호출된다면 해당 vtable이 실행된다.


    vtable는 기본적으로 더블포인터로 되어있기때문에 익스플로잇할때 이거 감안해서 공격하면된다 ㅎㅎ 이따가 익스플로잇 간단하게 해볼거지만 ..


    뭐 아무튼간에.... 요래 생긴게 힙 버퍼에 존재하는데, 아래와같이 gdb로 보면 다 잘 정렬되어있다.



    저 라이브러리와 비교해가면서 뭐가 뭔지 보면 될것같다.


    하나 콕 찝어보면 님들이 잘 아는 함수가 나옴!



    fwrite임! 이렇게 ** 로 되있다는것을 알 수 있음 고로 익스할때 잘 쓰까쓰까하면되는데, 기본적인거 다뤘으니 간단하게 eip만 바꾸는거 해볼예정 물론 오버플로우 취약점이 존재해야된다.


    딱히 취약점 코드를 작성하지않고 그냥 set *을 이용해서 값을 수정하는식으로 대충 할예정!


    저 위 vtable 주소로 fread의 offset을 보아하니 오프셋 계산을 해보면 아래와 같이 나옴



    0x38은 56byte니까 4바이트씩 14번넣어주면 fread가 덮히게된다. 하지만 이건 vtable이라 말했으니 double pointer임!!


    이제부터 fread를 다시 실행시킬거임 




    이제 *0x804b09c값을 0x804b0b0으로 바꾸면 vtable이 저긴줄알고 갔다가 fread가 실행되면 EIP가 바뀔것이다.



    근데 여기서 중요한것은, ROP는 절대 되지않는다. vtable로 한 주소만 실행되기때문에 익스는 각자의 능력껏하면된다.


    pwnable.tw - seethefile 문제가 이 내용을 다루는 문제인데, 나도 몰랐는데 6시간 삽질하면서 깨달은내용을 블로그에 슥슥 해보았다...


    틀린거, 고쳐야할점은 지적해주세요!



















    'Hack > Pwnable' 카테고리의 다른 글

    ASIS CTF 2018 Tinypwn  (1) 2018.08.30
    Shallow Copy 문제점  (0) 2018.01.29
    nc서버 열기 (XINETD)  (0) 2016.12.19
    malloc large_chunk exploit scenario  (2) 2016.12.02
    malloc - do_check_inuse_chunk()  (0) 2016.12.01

    댓글

Designed by Tistory.