# Linux 命令行技巧 - [重定向输入字符](#重定向输入字符) - [从可执行文件中提取 shellcode](#从可执行文件中提取-shellcode) - [查看进程虚拟地址空间](#查看进程虚拟地址空间) ## 重定向输入字符 有时候我们需要在 shell 里输入键盘上没有对应的字符,如 `0x1F`,就需要使用重定向输入。下面是一个例子:[源码](../src/Others/4.2_0x1f.c) ![](../pic/4.2_0x1f.png) ## 从可执行文件中提取 shellcode ```text for i in `objdump -d print_flag | tr '\t' ' ' | tr ' ' '\n' | egrep '^[0-9a-f]{2}$' ` ; do echo -n "\x$i" ; done ``` 注意:在 objdump 中空字节可能会被删除。 ## 查看进程虚拟地址空间 有时我们需要知道一个进程的虚拟地址空间是如何使用的,以确定栈是否是可执行的。 ```text $ cat /proc//maps ``` 下面我们分别来看看可执行栈和不可执行栈的不同: ```text $ cat hello.c #include void main() { char buf[128]; scanf("hello, world: %s\n", buf); } $ gcc hello.c -o a.out1 $ ./a.out1 & [1] 7403 $ cat /proc/7403/maps 555555554000-555555555000 r-xp 00000000 08:01 26389924 /home/firmy/a.out1 555555754000-555555755000 r--p 00000000 08:01 26389924 /home/firmy/a.out1 555555755000-555555756000 rw-p 00001000 08:01 26389924 /home/firmy/a.out1 555555756000-555555777000 rw-p 00000000 00:00 0 [heap] 7ffff7a33000-7ffff7bd0000 r-xp 00000000 08:01 21372436 /usr/lib/libc-2.25.so 7ffff7bd0000-7ffff7dcf000 ---p 0019d000 08:01 21372436 /usr/lib/libc-2.25.so 7ffff7dcf000-7ffff7dd3000 r--p 0019c000 08:01 21372436 /usr/lib/libc-2.25.so 7ffff7dd3000-7ffff7dd5000 rw-p 001a0000 08:01 21372436 /usr/lib/libc-2.25.so 7ffff7dd5000-7ffff7dd9000 rw-p 00000000 00:00 0 7ffff7dd9000-7ffff7dfc000 r-xp 00000000 08:01 21372338 /usr/lib/ld-2.25.so 7ffff7fbc000-7ffff7fbe000 rw-p 00000000 00:00 0 7ffff7ff8000-7ffff7ffa000 r--p 00000000 00:00 0 [vvar] 7ffff7ffa000-7ffff7ffc000 r-xp 00000000 00:00 0 [vdso] 7ffff7ffc000-7ffff7ffd000 r--p 00023000 08:01 21372338 /usr/lib/ld-2.25.so 7ffff7ffd000-7ffff7ffe000 rw-p 00024000 08:01 21372338 /usr/lib/ld-2.25.so 7ffff7ffe000-7ffff7fff000 rw-p 00000000 00:00 0 7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0 [stack] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] [1]+ Stopped ./a.out1 $ gcc -z execstack hello.c -o a.out2 $ ./a.out2 & [2] 7467 [firmy@manjaro ~]$ cat /proc/7467/maps 555555554000-555555555000 r-xp 00000000 08:01 26366643 /home/firmy/a.out2 555555754000-555555755000 r-xp 00000000 08:01 26366643 /home/firmy/a.out2 555555755000-555555756000 rwxp 00001000 08:01 26366643 /home/firmy/a.out2 555555756000-555555777000 rwxp 00000000 00:00 0 [heap] 7ffff7a33000-7ffff7bd0000 r-xp 00000000 08:01 21372436 /usr/lib/libc-2.25.so 7ffff7bd0000-7ffff7dcf000 ---p 0019d000 08:01 21372436 /usr/lib/libc-2.25.so 7ffff7dcf000-7ffff7dd3000 r-xp 0019c000 08:01 21372436 /usr/lib/libc-2.25.so 7ffff7dd3000-7ffff7dd5000 rwxp 001a0000 08:01 21372436 /usr/lib/libc-2.25.so 7ffff7dd5000-7ffff7dd9000 rwxp 00000000 00:00 0 7ffff7dd9000-7ffff7dfc000 r-xp 00000000 08:01 21372338 /usr/lib/ld-2.25.so 7ffff7fbc000-7ffff7fbe000 rwxp 00000000 00:00 0 7ffff7ff8000-7ffff7ffa000 r--p 00000000 00:00 0 [vvar] 7ffff7ffa000-7ffff7ffc000 r-xp 00000000 00:00 0 [vdso] 7ffff7ffc000-7ffff7ffd000 r-xp 00023000 08:01 21372338 /usr/lib/ld-2.25.so 7ffff7ffd000-7ffff7ffe000 rwxp 00024000 08:01 21372338 /usr/lib/ld-2.25.so 7ffff7ffe000-7ffff7fff000 rwxp 00000000 00:00 0 7ffffffde000-7ffffffff000 rwxp 00000000 00:00 0 [stack] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] [2]+ Stopped ./a.out2 ``` 当使用 `-z execstack` 参数进行编译时,会关闭 `Stack Protector`。我们可以看到在 `a.out1` 中的 `stack` 是 `rw` 的,而 `a.out2` 中则是 `rwx` 的。 `maps` 文件有 6 列,分别为: - **地址**:库在进程里地址范围 - **权限**:虚拟内存的权限,r=读,w=写,x=执行,s=共享,p=私有 - **偏移量**:库在进程里地址偏移量 - **设备**:映像文件的主设备号和次设备号,可以通过通过 `cat /proc/devices` 查看设备号对应的设备名 - **节点**:映像文件的节点号 - **路径**: 映像文件的路径,经常同一个地址有两个地址范围,那是因为一段是 `r-xp` 为只读的代码段,一段是 `rwxp` 为可读写的数据段