Skip to content
Snippets Groups Projects
Commit e24ce4b6 authored by Timmy Chan's avatar Timmy Chan
Browse files

Add qemu background booting support

Refactored some code
The system now supports having multiple qemu instances running in the background
parent 6c1c8a74
Branches
No related tags found
1 merge request!5Feat/cve linux kernel
......@@ -2,7 +2,7 @@
# Check input parameters
while [[ "$#" > 0 ]]; do case $1 in
while [[ $# -gt 0 ]]; do case $1 in
-u|--user) USERNAME="$2"; shift;shift;;
-p|--pass) PASSWORD="$2";shift;shift;;
-v|--verbose) VERBOSE=1;shift;;
......@@ -24,12 +24,8 @@ adduser()
local USERNAME=$1
local PASSWORD=$2
# -m makes a home directory for the user
useradd -m $USERNAME
if [ "$?" -ne "0" ]; then
verbose_log "Useradd failed"
return 1
fi
passwd $USERNAME << EOF
useradd -m "$USERNAME" || { verbose_log "Useradd failed"; return 1; }
passwd "$USERNAME" << EOF
$PASSWORD
$PASSWORD
EOF
......@@ -53,10 +49,6 @@ auto eth0
iface eth0 inet dhcp
EOF
# Auto configure eth0 and assign router ip to DNS /etc/resolv.conf
# ifup eth0
}
configure_hostname()
......@@ -68,7 +60,6 @@ EOF
}
verbose_log "Apt install dependencies"
apt update
apt-get install -y \
......@@ -83,7 +74,7 @@ echo root:root | chpasswd
verbose_log "Adding guest user"
adduser $USERNAME $PASSWORD
adduser "$USERNAME" "$PASSWORD"
verbose_log "Configuring network"
......
#!/bin/bash
# Example run:
# bash debian_image_setup.sh -d <vm_dir>
set -eu
WORKING_DIR=$PWD
# Run:
# debian_image_setup.sh <parent_dir> <output_file_name>
VERBOSE=1
# Set defaults
VERBOSE=0
ARCH=i386
USERNAME=ctf
PASSWORD=ctf
# Name of the final disk image. DO NOT change this as other scripts depend on this name.
DISK_NAME=disk.img
# Download directory
DL_DIR=$1
#DL_DIR=~/ctf/qemu/debian_disks
ARCH=${2:-i386}
# Change the variables if passed
while [[ $# -gt 0 ]]; do case $1 in
-a|--arch) ARCH="$2"; shift;shift;;
-d|--dir) VM_DIR="$2";shift;shift;;
-u|--user) USERNAME="$2"; shift;shift;;
-p|--pass) PASSWORD="$2";shift;shift;;
-v|--verbose) VERBOSE=1;shift;;
*) echo "Unknown parameter passed: $1"; shift; shift;;
esac; done
DISK_NAME=disk.img
[ -n "${VM_DIR}" ] || { echo "VM directory is not passed as argument."; exit 1; }
# Make the dir if not exist
[ -d "$DL_DIR" ] || mkdir -p "$DL_DIR"
# Create the dir if not exist
[ -d "${VM_DIR}" ] || mkdir -p "${VM_DIR}"
function verbose_log {
......@@ -29,11 +40,11 @@ function verbose_log {
}
function download_debian {
# Create a debian image inside VM_DIR
verbose_log "Creating Debian disk image..."
# Create a debian image inside DL_DIR, inside a new vm dir
verbose_log "VM directory is created at path ${DL_DIR}"
cd "${DL_DIR}" || exit 1
cd "${VM_DIR}" || exit 1
# Create a directory for the src
mkdir -p src
......@@ -49,9 +60,10 @@ function download_debian {
verbose_log " - Creating a disk image"
# Create a disk with 5GiB
dd if=/dev/zero of="${DISK_NAME}" bs=1M count=5000
# format the disk as Linux primary parition
# Format the disk as Linux primary parition
fdisk "${DISK_NAME}" <<EOF
n
p
......@@ -72,29 +84,22 @@ EOF
verbose_log " - Copy in the source"
cp -r src/. mnt/.
rm -rf src/
verbose_log "Created Debian disk image"
verbose_log "Configuring Debian disk image..."
# cd mnt || exit
# mkdir -p /mnt/ctf/dev
# mount --bind /dev /mnt/ctf/dev
# mount --bind /dev/pts /mnt/ctf/dev/pts
# mount --bind /proc /mnt/temp/proc
# mount --bind /sys /mnt/temp/sys
cp "${WORKING_DIR}/debian_image_configuration_chroot.sh" mnt/custom_config.sh
chmod +x mnt/custom_config.sh
chroot mnt/ /custom_config.sh -u ctf_guest -p ctf_pass -v
echo "Exitted with code $?"
chroot mnt/ /custom_config.sh -u "${USERNAME}" -p "${PASSWORD}" -v || { echo 'my_command failed'; exit 1; }
rm mnt/custom_config.sh
verbose_log " - Unmounting the disk image"
umount mnt
# The journal feature causes some kernels to fail booting the image. Remove it.
verbose_log " - Removing journal feature of disk image"
tune2fs -O ^has_journal "${DISK_NAME}"
......
#!/bin/bash
set -eu
while [[ "$#" > 0 ]]; do case $1 in
-p|--port) PORT="$2";shift;shift;;
*) echo "Unknown parameter passed: $1"; shift; shift;;
esac; done
# Exit with error if PORT is not set
[ -n "${PORT}" ] || exit 1
echo "Trying to run qemu on port ${PORT}"
qemu-system-x86_64 \
-kernel bzImage \
-append "root=/dev/sda rw net.ifnames=0" \
-m 512 \
-hda disk.img \
-nographic \
-device rtl8139,netdev=net00 \
-netdev type=user,id=net00 \
-net nic \
-net user,hostfwd=tcp:127.0.0.1:${PORT}-:22 </dev/null \
&> /dev/null &!
PID=$!
echo "Checking if port "${PORT}" is open"
sleep 5
if nc -w 5 -z localhost "${PORT}" ; then
echo "The port "${PORT}" is open";
cat > config <<EOF
PORT=${PORT}
EOF
else
echo "The port "${PORT}" is NOT open"
kill -9 $PID
echo "Killed the qemu process (PID: $PID)"
exit 1
fi
exit
\ No newline at end of file
......@@ -17,6 +17,9 @@ import buildroot_setup
DEFAULT_ARCH = "i386"
DEFAULT_KERNEL_VERSION = "3.18.100"
DEFAULT_OS = "debian"
GUEST_USERNAME = "ctf"
GUEST_PASSWORD = "ctf"
QEMU_VMS_PATH = "./vms"
BUILDROOT_PATH = "./lib/buildroot"
BUILDROOT_OUTPUT_KERNEL_PATH = BUILDROOT_PATH + "/output/images/bzImage"
......@@ -64,7 +67,10 @@ def setup(**kwargs):
compile_kernel()
copy_kernel_to_vm_directory(vm_directory)
verbose_log("Running with QEMU")
verbose_log("Get a port for SSH connection")
port = get_available_port()
verbose_log("Running with QEMU", port)
boot_with_qemu(vm_directory)
......@@ -97,7 +103,7 @@ def derive_input_kwargs(**kwargs):
def simple_call_shell_command(command):
"""
Executes a command on shell. Use with caution.
Executes a command. There are limitations with this function. Use with caution.
"""
return subprocess.check_call(command.split(' '), stdout=sys.stdout, stderr=subprocess.STDOUT)
......@@ -125,7 +131,7 @@ def setup_vm_disk_image(vm_directory, **kwargs):
"""
# Debian repo uses amd64 instead of the general term "x86_64"
arch_name = kwargs['arch'] if not kwargs['arch'] == "x86_64" else "amd64"
args = f"{str(vm_directory)} {arch_name}"
args = f"-d {str(vm_directory)} -a {arch_name} -u {GUEST_USERNAME} -p {GUEST_PASSWORD}"
try:
simple_call_shell_command("bash debian_image_setup.sh " + args)
except (FileNotFoundError, subprocess.CalledProcessError) as e:
......@@ -166,21 +172,29 @@ def copy_kernel_to_vm_directory(vm_directory):
copyfile(BUILDROOT_OUTPUT_KERNEL_PATH, str(vm_directory) + "/bzImage")
def boot_with_qemu(vm_directory):
command = f"cd {str(vm_directory)}"
command += " && " + """qemu-system-x86_64 \
-kernel bzImage \
-append "root=/dev/sda rw biosdevname=0 net.ifnames=0 console=tty0 console=ttyS0,115200 earlyprintk=ttyS0,115200 consoleblank=0" \
-nographic \
-m 512 \
-hda disk.img \
-device rtl8139,netdev=net00 \
-netdev type=user,id=net00 \
-net nic \
-net user,hostfwd=tcp:127.0.0.1:59355-:22 \
;"""
subprocess.run(command, shell=True)
def get_available_port():
# TODO
return 56789
def boot_with_qemu(vm_directory, port):
command = f"cd {str(vm_directory)} && "
command += f"bash ../../qemu_background_boot.sh -p {port}"
try:
subprocess.run(command, shell=True, check=True)
print("QEMU VM is booted, and running on port", port)
with open(str(vm_directory) + '/config') as f:
pid = f.readline()
print("PID:", pid)
print("Available for ssh for:")
print(" user:", GUEST_USERNAME)
print(" pass:", GUEST_PASSWORD)
return
except subprocess.CalledProcessError as e:
print("Qemu failed to boot")
print(e)
subprocess.run("cd ../../", shell=True)
if __name__ == "__main__":
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment