- 下载并安装 UTM,可以用命令:
brew install --cask utm
- 从 https://releases.ubuntu.com/22.04/ 下载镜像并安装。
然后在 Ubuntu 虚拟机中安装 gdbserver:
sudo apt install gdbserver
如果需要调试 32 位可执行文件,还需要执行:
sudo dpkg --add-architecture i386
sudo apt update
sudo apt install libc6:i386 libncurses5:i386 libstdc++6:i386
环境搭建完成后,在 Ubuntu 虚拟机中运行:
gdbserver :1234 ./test
在 Mac 上使用以下命令连接:
gdb ./test \
-ex "target extended-remote 192.168.64.13:1234"
记得替换 IP 地址和端口。
在 Mac 上执行:
gdb ./pwn101-1644307211706.pwn101 \
-ex "target extended-remote gdbserver.local:1234" \
-ex "set remote exec-file /home/gdb/pwn101-1644307211706.pwn101" \
-ex "break main"
注意:target extended-remote 192.168.64.13:1234 必须是第一条命令,否则不会生效。
你也可以用 pwndbg 来运行调试器。
如果需要禁用 ASLR,可以临时禁用:
sudo sysctl -w kernel.randomize_va_space=0
或永久禁用:
echo "kernel.randomize_va_space = 0" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
如果想通过域名(如 gdbserver.local)访问虚拟机,需要安装 avahi-daemon:
sudo apt install avahi-daemon
sudo systemctl enable avahi-daemon
sudo systemctl start avahi-daemon
下面是一个自动上传待调试文件到远程服务器的脚本。
可以将它保存为 /usr/local/bin/rdbg,然后像这样使用:
rdb pwn_test --host gdbserver.local --port 1234
#!/usr/bin/env bash
# Usage:
# ./debug.sh <local-path-to-binary> [--host <remote-host>] [--port <port>]
# Example:
# ./debug.sh ./vuln --host gdbserver.local --port 1234
set -e
# ====== Argument Parsing ======
if [ $# -lt 1 ]; then
echo "Usage: $0 <local-path-to-binary> [--host <remote-host>] [--port <port>]"
exit 1
fi
# Default values
REMOTE_USER="dbg"
REMOTE_HOST="gdbserver.local"
PORT=1234
# Extract the first non-flag argument as the local file
LOCAL_FILE=""
POSITIONAL_ARGS=()
for ((i=1; i<=$#; i++)); do
arg="${!i}"
case "$arg" in
--host)
((i++))
REMOTE_HOST="${!i}"
;;
--port)
((i++))
PORT="${!i}"
;;
--help|-h)
echo "Usage: $0 <local-path-to-binary> [--host <remote-host>] [--port <port>]"
exit 0
;;
-*)
echo "Unknown option: $arg"
exit 1
;;
*)
if [ -z "$LOCAL_FILE" ]; then
LOCAL_FILE="$arg"
else
POSITIONAL_ARGS+=("$arg")
fi
;;
esac
done
# Validate local file
if [ ! -f "$LOCAL_FILE" ]; then
echo "Error: File '$LOCAL_FILE' not found."
exit 1
fi
# Remote path
REMOTE_DIR="/home/$REMOTE_USER/pwn"
FILENAME=$(basename "$LOCAL_FILE")
# Upload
# Calculate local file hash
LOCAL_HASH=$(sha256sum "$LOCAL_FILE" | cut -d ' ' -f1)
# Get remote file hash (if exists)
REMOTE_HASH=$(ssh "$REMOTE_USER@$REMOTE_HOST" "sha256sum '$REMOTE_DIR/$FILENAME' 2>/dev/null | cut -d ' ' -f1 || true")
if [ "$LOCAL_HASH" == "$REMOTE_HASH" ]; then
echo "[✓] Remote file is identical to local file. Skipping upload."
else
echo "[*] Uploading updated file to $REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR ..."
scp "$LOCAL_FILE" "$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/"
fi
# Start pwndbg
echo "[*] Starting GDB with remote target $REMOTE_HOST:$PORT ..."
pwndbg -ex "file $LOCAL_FILE" \
-ex "target extended-remote ${REMOTE_HOST}:${PORT}" \
-ex "set remote exec-file $REMOTE_DIR/$FILENAME" \
-ex "break main"