Apple Silicon 맥북에서는 Arm64v8 아키텍쳐를 택하고 있다.
이후 Apple Silicon에 등장으로 Arm Cpu 또한 많이 증가하는 추세이며
Arm과 X86_64의 대결 구도가 그려지고 있다.
M1맥북을 쓴지 어느덧 10개월 포너블을 하기위해 버렸던 사투와 그 사투끝에 결국 택한 방안을 정리해보고자 한다.
과거 많은 사람들이 Docker를 활용한 포너블 환경을 구축하려 했지만
Qemu에 Ptrace 이슈로 실패했고 Rosetta2_Linux의 출시로 도커의 Rosetta2 에뮬 기능이 추가되었지만 로제타2 에뮬레이션 원리로는 X86_64 디버깅을 정상적으로 할 수 없었다.
결국 최종적으로 남은것은 Rosetta_DEBUGSERVER 인데 이또한 결국 원격으로 진행하는 거와 같아 속도가 보다 느리며 heap영역과 libc 버전을 정상적으로 gdb에서 알 수 없었다.
그렇게 지금까지 시간이 흘러 기존에 Apple Silicon 맥북으로 포너블 환경은 대부분 아래와 같이 구축했다.
UTM(Qemu)를 활용한 전체 에뮬레이션
원격 서버를 활용한 pwnable
위 두 경우가 크게 있는데 UTM 같은 경우는 너무 느리며 파일 옮기는 작업까지 해야되어 상당히 번거로운 작업들을 해야한다.
원격 서버 같은 경우에는 Pwnable 워게임을 푸는데에는 크게 지장이없지만 로컬 서버로만 진행되는 CTF에서는 무용지물이 되는 경우가 허다하다.
심지어 서버가 항상 켜져있어야 하기에 집 내에서 구축하면 전기세를 담당해야 하며 호스팅 사용시 비용이 든다.
그렇게 필자는 UTM, Rosetta2를 활용한 포너블 구축 환경을 만들기로 했다.
최대한 로컬에서 활동하는 거와 같이 이루어지게 하는 게 목표다.
위에서 총 2개의 가상머신을 돌릴 예정이다.
4Core 8GB를 할당했으며 이 VM에서는 Docker 컨테이너를 통해 Gdb_Server을 열거다.
ubuntu 18.04
FROM --platform=linux/amd64 ubuntu:18.04
ARG DEBIAN_FRONTEND=noninteractive
ENV TZ Asia/Seoul
ENV PYTHONIOENCODING UTF-8
ENV LC_CTYPE C.UTF-8
WORKDIR /root
RUN apt update && apt install -y netcat
RUN apt install vim git gcc ssh curl wget gdb sudo zsh python3 python3-pip libffi-dev build-essential libssl-dev libc6-i386 libc6-dbg gcc-multilib make -y
RUN sudo apt install -y openssh-server
RUN sudo sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
RUN sudo sed -i 's/#Port 22/Port 22/' /etc/ssh/sshd_config
RUN echo "root:1804" | sudo chpasswd
RUN sudo systemctl enable ssh
RUN sudo service ssh restart
RUN dpkg --add-architecture i386
RUN apt update
RUN apt install libc6:i386 -y
RUN python3 -m pip install --upgrade pip
RUN pip3 install unicorn
RUN pip3 install keystone-engine
RUN pip3 install pwntools
RUN pip3 install ropgadget
RUN apt install libcapstone-dev -y
RUN bash -c "$(wget https://gef.blah.cat/sh -O -)"
RUN apt install ruby-full -y
RUN pip3 install one_gadget
RUN pip3 install ROPgadget
RUN wget https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh -O - | zsh || true
RUN mkdir -p "$HOME/.zsh"
RUN git clone https://github.com/sindresorhus/pure.git "$HOME/.zsh/pure"
RUN echo "fpath+=("$HOME/.zsh/pure")\nautoload -U promptinit; promptinit\nprompt pure" >> ~/.zshrc
RUN git clone https://github.com/zsh-users/zsh-syntax-highlighting.git
RUN echo "source ./zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" >> ~/.zshrc
RUN git clone https://github.com/zsh-users/zsh-autosuggestions ~/.zsh/zsh-autosuggestions
RUN echo "source ~/.zsh/zsh-autosuggestions/zsh-autosuggestions.zsh" >> ~/.zshrc
RUN echo "ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE='fg=111'" >> ~/.zshrc
RUN mkdir /root/pwn
EXPOSE 22
ENTRYPOINT ["/usr/bin/sudo", "/usr/sbin/sshd", "-D", "-o", "ListenAddress=0.0.0.0"]
#docker run -d -it --privileged --platform linux/amd64 --name pwn1804 --cap-add=SYS_PTRACE --security-opt seccomp=unconfined -p 1804:22 pwn1804 export LANG=C.UTF-8
Ubuntu 20.04
FROM --platform=linux/amd64 ubuntu:20.04
ARG DEBIAN_FRONTEND=noninteractive
ENV TZ Asia/Seoul
ENV PYTHONIOENCODING UTF-8
ENV LC_CTYPE C.UTF-8
WORKDIR /root
RUN apt update && apt install -y netcat
RUN apt install vim git gcc ssh curl wget gdb sudo zsh python3 python3-pip libffi-dev build-essential libssl-dev libc6-i386 libc6-dbg gcc-multilib make file nano -y
RUN sudo apt install -y openssh-server
RUN sudo sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
RUN sudo sed -i 's/#Port 22/Port 22/' /etc/ssh/sshd_config
RUN echo "root:2004" | sudo chpasswd
RUN sudo systemctl enable ssh
RUN sudo service ssh restart
RUN dpkg --add-architecture i386
RUN apt update
RUN apt install libc6:i386 -y
RUN python3 -m pip install --upgrade pip
RUN pip3 install unicorn
RUN pip3 install keystone-engine
RUN pip3 install pwntools
RUN pip3 install ropgadget
RUN apt install libcapstone-dev -y
RUN bash -c "$(wget https://gef.blah.cat/sh -O -)"
RUN apt install ruby-full -y
RUN pip3 install one_gadget
RUN pip3 install ROPgadget
RUN wget https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh -O - | zsh || true
RUN mkdir -p "$HOME/.zsh"
RUN git clone https://github.com/sindresorhus/pure.git "$HOME/.zsh/pure"
RUN echo "fpath+=("$HOME/.zsh/pure")\nautoload -U promptinit; promptinit\nprompt pure" >> ~/.zshrc
RUN git clone https://github.com/zsh-users/zsh-syntax-highlighting.git
RUN echo "source ./zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" >> ~/.zshrc
RUN git clone https://github.com/zsh-users/zsh-autosuggestions ~/.zsh/zsh-autosuggestions
RUN echo "source ~/.zsh/zsh-autosuggestions/zsh-autosuggestions.zsh" >> ~/.zshrc
RUN echo "ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE='fg=111'" >> ~/.zshrc
RUN export LANG=C.UTF-8
RUN mkdir /root/pwn
EXPOSE 22
ENTRYPOINT ["/usr/bin/sudo", "/usr/sbin/sshd", "-D", "-o", "ListenAddress=0.0.0.0"]
#docker run -d -it --privileged --platform linux/amd64 --name pwn2004 --cap-add=SYS_PTRACE --security-opt seccomp=unconfined -p 2204:22 pwn2004 zsh
Ubuntu 22.04
FROM --platform=linux/amd64 ubuntu:22.04
ARG DEBIAN_FRONTEND=noninteractive
ENV TZ Asia/Seoul
ENV PYTHONIOENCODING UTF-8
ENV LC_CTYPE C.UTF-8
WORKDIR /root
RUN apt update && apt install -y netcat
RUN apt install vim git gcc ssh curl wget gdb sudo zsh python3 python3-pip libffi-dev build-essential libssl-dev libc6-i386 libc6-dbg gcc-multilib make nano file -y
RUN sudo apt install -y openssh-server
RUN sudo sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
RUN sudo sed -i 's/#Port 22/Port 22/' /etc/ssh/sshd_config
RUN echo "root:2204" | sudo chpasswd
RUN sudo systemctl enable ssh
RUN sudo service ssh restart
RUN dpkg --add-architecture i386
RUN apt update
RUN apt install libc6:i386 -y
RUN python3 -m pip install --upgrade pip
RUN pip3 install unicorn
RUN pip3 install keystone-engine
RUN pip3 install pwntools
RUN pip3 install ropgadget
RUN apt install libcapstone-dev -y
RUN bash -c "$(wget https://gef.blah.cat/sh -O -)"
RUN apt install ruby-full -y
RUN pip3 install one_gadget
RUN pip3 install ROPgadget
RUN wget https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh -O - | zsh || true
RUN mkdir -p "$HOME/.zsh"
RUN git clone https://github.com/sindresorhus/pure.git "$HOME/.zsh/pure"
RUN echo "fpath+=("$HOME/.zsh/pure")\nautoload -U promptinit; promptinit\nprompt pure" >> ~/.zshrc
RUN git clone https://github.com/zsh-users/zsh-syntax-highlighting.git
RUN echo "source ./zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" >> ~/.zshrc
RUN git clone https://github.com/zsh-users/zsh-autosuggestions ~/.zsh/zsh-autosuggestions
RUN echo "source ~/.zsh/zsh-autosuggestions/zsh-autosuggestions.zsh" >> ~/.zshrc
RUN echo "ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE='fg=111'" >> ~/.zshrc
RUN export LANG=C.UTF-8
RUN mkdir /root/pwn
EXPOSE 22
ENTRYPOINT ["/usr/bin/sudo", "/usr/sbin/sshd", "-D", "-o", "ListenAddress=0.0.0.0"]
#docker run -d -it --privileged --platform linux/amd64 --name pwn2204 --cap-add=SYS_PTRACE --security-opt seccomp=unconfined -p 2204:22 pwn1804 zsh
위 도커파일을 빌드하고 컨테이너를 만들어 디버깅 환경을 구축할 것이다.
그리고 OrbStack이나 ubuntu22.04-Desktop-Arm64를 구축하여 편한데로 쓰면 된다.
필자는 Orbstack 기준으로 환경을 구축했다.
OrbStack으로 Rosetta 2 에뮬레이션을 통해 X86_64 Linux_Machine을 사용했다.
Orbstack에는 가상머신과 MAC 호스트의 파일 접근이 자유롭기에 선택했다.
Orbstack은 평소 자신이 사용하던대로 Pwnable환경을 구축하면 된다.
#!/bin/bash
directory_path="$1"
ubuntu_version="$2"
debug_your_binary="$3"
directory_name=$(basename "$directory_path")
host=10.211.56.9
username=kch3dri4n
sshpass -p "$(cat ~/.password)" scp -r -o StrictHostKeyChecking=no "$directory_path" "$username"@"$host":~/pwn
echo "Success: Files copied to remote server"
sshpass -p "$(cat ~/.password)" ssh -o StrictHostKeyChecking=no "$username"@"$host" "docker cp ~/pwn/$directory_name pwn$ubuntu_version:/root/pwn"
echo "Success: Files copied to Docker container"
sshpass -p "$(cat ~/.password)" ssh -o StrictHostKeyChecking=no "$username"@"$host" "docker start pwn$ubuntu_version"
echo "Success: Docker container started"
sshpass -p "$ubuntu_version" ssh -o StrictHostKeyChecking=no "root"@"$host" -p "$ubuntu_version" "echo '$ubuntu_version' | sudo -S sudo"
echo "Success: Password entered"
sshpass -p "$ubuntu_version" ssh -t -o StrictHostKeyChecking=no "root"@"$host" -p "$ubuntu_version" "
cd '/root/pwn/$directory_name' &&
chmod +x $debug_your_binary &&
export LANG=C.UTF-8 &&
gdb ./$debug_your_binary;
"
echo "from pwn import *" > ./ex.py
echo "s = ssh(user='root', host='$host', port=$ubuntu_version, password='$ubuntu_version')" >> ./ex.py
echo "p = s.process('/root/pwn/$directory_name/$debug_your_binary')" >> ./ex.py
echo "Success: Debugging session ended, zsh started"
sshpass -p "$ubuntu_version" ssh -t -o StrictHostKeyChecking=no "root"@"$host" -p "$ubuntu_version" "zsh"
exit 0
위는 디버깅 스크립트다.
Ubuntu 버전과 바이너리 및 디렉토리 경로를 입력받아 가상머신의 ssh로 접속하여 바이너리의 디버깅을 시작한다.
from pwn import *
s = ssh(user='root', host='10.211.56.9', port=2204, password='2204')
p = s.process('/root/pwn/deploy/baby-bof')
이후 환경에 맞게 ex.py를 Orbstack 머신에 생성해준다.
(Arm64든 Amd64 로제타 에뮬레이션을 쓰든 상관없다.)
→ 어차피 익스코드는 여기서 실행함
이를 통하여 사용자는 pwntools을 활용한 exploit 코드 제작을 순조롭게 갈 수 있다.
화면 기록 2023-11-17 오후 1.19.11.mov
#!/usr/bin/env bash
dir="$(realpath "${1:-$(pwd)}")"
echo "Opening $dir in VSCode..."
exec mac code --folder-uri "vscode-remote://ssh-remote+$(whoami)@$(hostname)@orb$dir"
이후 위 스크립트를 통해서 vscode를 로컬 환경에서 열듯 손 쉽게 열 수 있다.
화면 기록 2023-11-17 오후 1.21.43.mov
그냥 UTM으로 에뮬레이터 해서 진행해도 되지만 구지 위와 같이 구축한 이유로는 아래와 같다.
솔직히 말하자면 원래 외부 서버를 통해 Pwnable을 진행했지만 서버가 꺼지거나 했던 경우가 있거나 하는 변수가 존재하기 때문
그렇다고 UTM으로만 포너블을 하자니 속이 타들어가기도 하고 좀 신박한 방법으로도 하고 싶었다.
이상 끝!
UTM에뮬레이터에서 도커만 열고 orbstack에서 utm으로 접속을 하는 건가요?