0x00简介
在漏洞挖掘和调试或者工具开发的过程中,我们经常会需要使用到不同架构的环境。比如你解开某设备固件后,想看看它的busybox支持哪些命令,但一看是mips64,傻眼了。这篇文章将探讨使用qemu来启动不同架构虚拟机的方法。
qemu有两种主要的运作模式,user mode和system mode。usermode一般用来启动单个的二进制程序,systemmode可以用来模拟整个系统,包括cpu和其他设备,这里我们用到的就是system mode。
0x01环境配置
在模拟虚拟机之前,需要安装准备一些工具。
$ sudo apt-get install qemu-system qemu-user qemu
$sudo apt-get install bridge-utils uml-utilities
安装完成后,输入qemu-
配合tab键可以看到
$ qemu-
qemu-aarch64 qemu-mipsn32el-static qemu-system-lm32
qemu-aarch64-static qemu-mipsn32-static qemu-system-m68k
qemu-alpha qemu-mips-static qemu-system-microblaze
qemu-alpha-static qemu-nbd qemu-system-microblazeel
qemu-arm qemu-or32 qemu-system-mips
qemu-armeb qemu-or32-static qemu-system-mips64
qemu-armeb-static qemu-ppc qemu-system-mips64el
qemu-arm-static qemu-ppc64 qemu-system-mipsel
qemu-cris qemu-ppc64abi32 qemu-system-moxie
qemu-cris-static qemu-ppc64abi32-static qemu-system-or32
qemu-debootstrap qemu-ppc64le qemu-system-ppc
qemu-i386 qemu-ppc64le-static qemu-system-ppc64
qemu-i386-static qemu-ppc64-static qemu-system-ppc64le
qemu-img qemu-ppc-static qemu-system-ppcemb
qemu-io qemu-s390x qemu-system-sh4
0x02虚拟机下载
从debian.org上下载网络安装加载映像。
$ wget https://people.debian.org/~aurel32/qemu/mips/debian_squeeze_mips_standard.qcow2
$ wget https://people.debian.org/~aurel32/qemu/mips/vmlinux-2.6.32-5-5kc-malta
#0x03网络配置
对qemu模拟的虚拟机配置系统网络,让宿主机能与其通讯和传输数据,便于进行调试和交叉编译。
修改ubuntu主机网络接口配置文件。
sudo gedit /etc/network/interfaces
修改ubuntu主机的网络配置文件 /etc/network/interfaces
# interfaces(5) file used by ifup(8) and ifdown(8)
auto lo
iface lo inet loopback
auto ens33
iface ens33 inet dhcp
#auto br0
iface br0 inet dhcp
bridge_ports ens33
bridge_maxwait 0
要注意的是ubuntu16.04
以前为eth0
查看ubuntu主机的网络接口卡信息。
$ ifconfig
ens33 Link encap:Ethernet HWaddr 00:0c:29:05:9f:18
inet addr:172.16.1.163 Bcast:172.16.1.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fe05:9f18/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:70 errors:0 dropped:0 overruns:0 frame:0
TX packets:108 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:22443 (22.4 KB) TX bytes:12529 (12.5 KB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:232 errors:0 dropped:0 overruns:0 frame:0
TX packets:232 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:18060 (18.0 KB) TX bytes:18060 (18.0 KB)
通过dmesg|grep -i eth
可以看到网卡ens33
是eth0
改名过来的。
$ dmesg|grep -i eth
[ 2.305522] e1000 0000:02:01.0 eth0: (PCI:66MHz:32-bit) 00:0c:29:05:9f:18
[ 2.305526] e1000 0000:02:01.0 eth0: Intel(R) PRO/1000 Network Connection
[ 2.307646] e1000 0000:02:01.0 ens33: renamed from eth0
创建qemu的网络接口启动脚本,重新启动网络使配置生效,使用以下命令,创建并编辑/etc/qemu-ifup
文件。
#!/bin/sh
echo "Executing /etc/qemu-ifup"
echo "Bringing $1 for bridged mode..."
sudo /sbin/ifconfig $1 0.0.0.0 promisc up
echo "Adding $1 to br0..."
sudo /sbin/brctl addif br0 $1
sleep 3
一般/etc/qemu-ifup
这个文件本来就存在,检查一下文件的末尾有没有这部分内容,没有的话加上。
#赋予可执行权限
$sudo chmod a+x /etc/qemu-ifup
#重启网络使所有配置生效
$sudo /etc/init.d/networking restart
在ubuntu主机运行命令,启动桥接网络。
$sudo ifdown ens33
$sudo ifup br0
再次查看执行后的网络接口信息。
$ ifconfig
br0 Link encap:Ethernet HWaddr 00:0c:29:05:9f:18
inet addr:172.16.1.164 Bcast:172.16.1.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fe05:9f18/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:14 errors:0 dropped:0 overruns:0 frame:0
TX packets:42 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:1622 (1.6 KB) TX bytes:5249 (5.2 KB)
ens33 Link encap:Ethernet HWaddr 00:0c:29:05:9f:18
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:109 errors:0 dropped:0 overruns:0 frame:0
TX packets:178 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:26944 (26.9 KB) TX bytes:20800 (20.8 KB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:300 errors:0 dropped:0 overruns:0 frame:0
TX packets:300 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:23080 (23.0 KB) TX bytes:23080 (23.0 KB)
使用以下脚本启动虚拟机。
sudo qemu-system-mips64 -nographic -M malta -kernel vmlinux-2.6.32-5-5kc-malta -hda debian_squeeze_mips_standard.qcow2 -net nic,macaddr=52:54:00:12:34:56 -net tap -append "root=/dev/sda1 console=tty0"
通过ifconfg
查看网络接口信息,并编辑/etc/network/interfaces
,保证接口名一致,这里是eth0
# vi /etc/network/interfaces
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
# The loopback network interface
auto lo
iface lo inet loopback
# The primary network interface
allow-hotplug eth0
iface eth0 inet dhcp
通过ifup eth0
启用eth0
,此时虚拟机ip就会分配到ubuntu主机一个c段,可以上网通信了。
# ifconfig
eth0 Link encap:Ethernet HWaddr 52:54:00:12:34:56
inet addr:172.16.1.166 Bcast:172.16.1.255 Mask:255.255.255.0
inet6 addr: fe80::5054:ff:fe12:3456/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:23 errors:0 dropped:0 overruns:0 frame:0
TX packets:28 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:2404 (2.3 KiB) TX bytes:2648 (2.5 KiB)
Interrupt:10 Base address:0x1020
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:10 errors:0 dropped:0 overruns:0 frame:0
TX packets:10 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:784 (784.0 B) TX bytes:784 (784.0 B)
此时可以上网了。
# ping baidu.com
PING baidu.com (220.181.38.148) 56(84) bytes of data.
64 bytes from 220.181.38.148: icmp_req=1 ttl=128 time=119 ms
64 bytes from 220.181.38.148: icmp_req=2 ttl=128 time=118 ms
64 bytes from 220.181.38.148: icmp_req=3 ttl=128 time=116 ms
64 bytes from 220.181.38.148: icmp_req=4 ttl=128 time=117 ms
0x04其他架构
mips64
$ mkdir debian-mips64-qemu
$ cd debian-mips64-qemu
$ wget https://people.debian.org/~aurel32/qemu/mips/debian_squeeze_mips_standard.qcow2
$ wget https://people.debian.org/~aurel32/qemu/mips/vmlinux-2.6.32-5-5kc-malta
$ echo "sudo qemu-system-mips64 -nosudo qemu-system-mips64 -nographic -M malta -kernel vmlinux-2.6.32-5-5kc-malta -hda debian_squeeze_mips_standard.qcow2 -net nic,macaddr=52:54:00:12:34:56 -net tap -append "root=/dev/sda1 console=tty0"" > start.sh
$ sudo chmod a+x start.sh
$ ./start.sh
mips
$ mkdir debian-mips-qemu
$ cd debian-mips-qemu
$ wget https://people.debian.org/~aurel32/qemu/mips/debian_squeeze_mips_standard.qcow2
$ wget https://people.debian.org/~aurel32/qemu/mips/vmlinux-2.6.32-5-4kc-malta
$ echo "sudo qemu-system-mips -nographic -M malta -kernel vmlinux-2.6.32-5-4kc-malta -hda debian_squeeze_mips_standard.qcow2 -net nic,macaddr=52:54:00:12:34:56 -net tap -append "root=/dev/sda1 console=tty0"" > start.sh
$ sudo chmod a+x start.sh
$ ./start.sh
armel
$ mkdir debian-armel-qemu
$ cd debian-armel-qemu
$ wget https://people.debian.org/~aurel32/qemu/mips/debian_squeeze_armel_standard.qcow2
$ wget https://people.debian.org/~aurel32/qemu/mips/vmlinuz-2.6.32-5-versatile
$ echo "sudo qemu-system-arm -nographic -M versatilepb -kernel vmlinuz-2.6.32-5-versatile -initrd initrd.img-2.6.32-5-versatile -hda debian_squeeze_armel_standard.qcow2 -net nic,macaddr=52:54:00:12:34:56 -net tap -append "root=/dev/sda1 console=tty0"" > start.sh
$ sudo chmod a+x start.sh
$ ./start.sh
armhf
$ mkdir debian-armhf-qemu
$ cd debian-armhf-qemu
$ wget https://people.debian.org/~aurel32/qemu/mips/debian_wheezy_armhf_standard.qcow2
$ wget https://people.debian.org/~aurel32/qemu/mips/vmlinuz-3.2.0-4-vexpress
$ echo "sudo qemu-system-arm -nographic -M vexpress-a9 -kernel vmlinuz-3.2.0-4-vexpress -initrd initrd.img-3.2.0-4-vexpress -drive if=sd,file=debian_wheezy_armhf_standard.qcow2 -net nic,macaddr=52:54:00:12:34:56 -net tap -append "root=/dev/sda1 console=tty0"" > start.sh
$ sudo chmod a+x start.sh
$ ./start.sh
mipsel
$ mkdir debian-mipsel-qemu
$ cd debian-mipsel-qemu
$ wget https://people.debian.org/~aurel32/qemu/mips/debian_squeeze_mipsel_standard.qcow2
$ wget https://people.debian.org/~aurel32/qemu/mips/vmlinux-2.6.32-5-4kc-malta
$ echo "sudo qemu-system-mipsel -nographic -M malta -kernel vmlinux-2.6.32-5-4kc-malta -hda debian_squeeze_mipsel_standard.qcow2 -net nic,macaddr=52:54:00:12:34:56 -net tap -append "root=/dev/sda1 console=tty0"" > start.sh
$ sudo chmod a+x start.sh
$ ./start.sh
mips64el
$ mkdir debian-mips64el-qemu
$ cd debian-mips64el-qemu
$ wget https://people.debian.org/~aurel32/qemu/mips/debian_squeeze_mipsel_standard.qcow2
$ wget https://people.debian.org/~aurel32/qemu/mips/vmlinux-2.6.32-5-5kc-malta
$ echo "sudo qemu-system-mips64el -nographic -M malta -kernel vmlinux-2.6.32-5-5kc-malta -hda debian_squeeze_mipsel_standard.qcow2 -net nic,macaddr=52:54:00:12:34:56 -net tap -append "root=/dev/sda1 console=tty0"" > start.sh
$ sudo chmod a+x start.sh
$ ./start.sh
0x05自启脚本
可以将需要的虚拟机放到各自文件夹下,并创建对应的启动脚本方便一键启动。
这里是armel
的启动脚本。
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import os
import time
try:
cmd = ' "sudo qemu-system-arm -nographic -M versatilepb -kernel vmlinuz-2.6.32-5-versatile -initrd initrd.img-2.6.32-5-versatile -hda debian_squeeze_armel_standard0.qcow2 -net nic,macaddr=52:54:00:12:10:65 -net tap,ifname=tap0 -append "root=/dev/sda1 console=ttyAMA0";exec bash"\''
os.system("gnome-terminal -e 'bash -c" + cmd)
time.sleep(30)
exit(0)
except OSError as e:
pass
通过复制qcow2文件和更改macadam,还可以实现批量启动,模拟大规模设备。