Skip to main content

​🕸️​CTFWeb周报11

·430 words·3 mins
Yalois
Author
Yalois

十一次周报
#

Web
#

PHP特性
#

弱比较
#

字符串的运算(T1)
#
<?php
highlight_file(__FILE__);
error_reporting(0);

$s = $_GET['a'];
if(!is_numeric($s)){
  if($s+1 === 1000){
  die(getenv('FLAG'));
  }
}
?> 

payload =>

?a=999a

知识点
#

在PHP中,当你对一个字符串进行算术运算时,PHP会尝试将这个字符串转换为一个数字。如果字符串的开头部分是一个有效的数字,那么PHP会使用这个数字进行运算,忽略后面的非数字部分。

所以999a既绕过了!is_numberic,又在$s+1的时候得到1000。

Hash绕过(T2)
#
<?php
highlight_file(__FILE__);
error_reporting(0);

$a = $_GET['param1'];
$b = $_POST['param2'];
$c = $_GET['param3'];
$d = $_POST['param4'];

if($a!=$b && md5($a)==md5($b) && $c!=$d && sha1($c)==sha1($d)){
    echo getenv('FLAG');
}else{
    echo "fail";
}
?> 

payload=>

GET param1=240610708&param3=aaroZmOk

POST param2=QLTHNDT&param4=aaK1STfY

知识点
#

某些字符串经过hash处理后的值为0e开头的,PHP会当作科学计数法来处理。两个0e开头的hash值弱比较是相等的。

在此中情况下被弱比较类型判定为相等的hash值就被成为magic hash

Plaintext MD5 Hash
240610708 0e462097431906509019562988736854
QLTHNDT 0e405967825401955372549139051580
QNKCDZO 0e830400451993494058024219903391
PJNPDWY 0e291529052894702774557631701704
NWWKITQ 0e763082070976038347657360817689
NOOPCJF 0e818888003657176127862245791911
MMHUWUV 0e701732711630150438129209816536
MAUXXQC 0e478478466848439040434801845361
IHKFRNS 0e256160682445802696926137988570
GZECLQZ 0e537612333747236407713628225676
GGHMVOE 0e362766013028313274586933780773
GEGHBXL 0e248776895502908863709684713578
EEIZDOI 0e782601363539291779881938479162
DYAXWCA 0e424759758842488633464374063001
DQWRASX 0e742373665639232907775599582643
BRTKUJZ 00e57640477961333848717747276704
ABJIHVY 0e755264355178451322893275696586
aaaXXAYW 0e540853622400160407992788832284
aabg7XSs 0e087386482136013740957780965295
aabC9RqS 0e041022518165728065344349536299
0e215962017 0e291242476940776845150308577824

Plaintext SHA1 Hash
aaroZmOk 0e66507019969427134894567494305185566735
aaK1STfY 0e76658526655756207688271159624026011393
aaO8zKZF 0e89257456677279068558073954252716165668
aa3OFF9m 0e36977786278517984959260394024281014729

Plaintext MD4 Hash
bhhkktQZ 0e949030067204812898914975918567
0e001233333333333334557778889 0e434041524824285414215559233446
0e00000111222333333666788888889 0e641853458593358523155449768529
0001235666666688888888888 0e832225036643258141969031181899

更多Magic Hashes请参考:https://github.com/spaze/hashes
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。          
原文链接:https://blog.csdn.net/qq_42739469/article/details/133311487
数组绕过 T3
#

这里是强比较,没法用hash绕过,因为'0e666’===‘0e777’的值为false。上一题hash绕过的题也是可以进行数组绕过的。

<?php
highlight_file(__FILE__);
error_reporting(0);

$a = $_GET['a'];
$b = $_GET['b'];
if($a!==$b && md5($a)===md5($b)){
    echo "success!";
}else{
    echo "fail";
}
?> 

传入?a[]=c&b[]=d就行

PHP中hash绕过和常用函数_php hash强比较绕过-CSDN博客

intval绕过
#

intval() 函数用于获取变量的整数值,可使用指定的base进制转换。

语法: int intval ( mixed $var [, int $base = 10 ] )

1、进制自动转换
#

第二个参数 $base 允许为空。

当 base 为空时,默认值是 0,会根据 $var 的格式来调整转换的进制。

  • 如果 $var 以 0 开头,就使用 8进制
  • 如果 $var 以0x开头,就使用 16进制
  • 否则,就使用 10进制

数字被过滤时,可使用其他进制来绕过。

2、转换数组
#

intval()转换数组类型时,不关心数组的内容,只判断数组中有没有元素。

  • 空数组 ==> 返回0
  • 非空数组 ==> 返回1

弱比较 a==b 可以传入空数组使他们的intval()值相等。

3、转换小数
#

转换小数类型时,只取个位数,小数全丢了。

增加小数位来判断原来的值不相等,但是intval()相等

4、转换字符串
#

转换字符串时从左到右遇到字母就结束,返回字母之前的数字。

var_dump(intval('12abc'));		//int(12) 
var_dump(intval('abc123'));		//int(0) 
var_dump(intval('1a2b3c'));		//int(1) 
var_dump(intval('0101'));		//int(101)
var_dump(intval("0x2b"));		//int(0) 
var_dump(intval(0x2b));		//int(43)
5、取反~
#

intval()支持取反符号。

echo ~123; //result: -124
var_dump(intval(~-124)); //result int(123)

可以用取反来绕过过滤

6、算数运算符
#

如果传入的包含算数运算符,则会运算再进行函数处理。

var_dump(intval(5*3)); //int(15)
var_dump(intval('5*3')); //int(5) 因为它是字符串

运算符绕过

7、浮点数精度缺失问题
#
var_dump(intval(0.34*100.0));
var_dump(intval(0.58*100.0));

第一个输出int(34)
第二个输出int(57) 出现了精度缺失

这个感觉有点不常用,,出现了也不好想。。。

PHP intval()函数详解,intval()函数漏洞原理及绕过思路_intval函数-CSDN博客

strcmp绕过 T4
#
strcmp(string1,string2)
返回值
    string1==string2 返回 0
    string1>string2 >0
    string1<string2 <0

strcmp比较的是字符串类型,如果强行传入其他类型参数,会出错,出错后返回值NULL,NULL==0为true,正是利用这点进行绕过。

<?php
include 'pass.php';
highlight_file(__FILE__);


if(isset($_GET['password'])){
    if(strcmp($_GET['password'], $password)==0){
        echo getenv('FLAG');
    }else{
        echo "Wrong";
    }
}
?>

这里传入password[]=xxx传入的是数组,就会绕过了。

变量覆盖
#

extract函数
#

extract() 函数从数组中将变量导入到当前的符号表。

extract($_GET); // 把GET请求中的内容变为变量

?a=1&b=2之后,$a的值是1 $b的值是2

<?php
highlight_file(__FILE__);
error_reporting(0);

$param2 = 'param2';
extract($_GET);
if($param2==='getflag'){
	echo getenv('FLAG');
}
?>

这题传入?param2=getflag就能把get请求中的param2的getflag变成变量,覆盖掉原来的param2。

双重$(可变变量)
#

NSS上面的题,第一眼看到还是比较蒙的,但是GPT告诉我,get请求可以直接传入数组,第一次知道

以前遇到问题就百度,难在描述问题和寻找对应的回答,现在GPT可以直接解惑,降低了门槛,这是一个快速解决问题的好时代。

payload =>

/?a[param1]=abc&a[content]=abc&a[param2]=getflag

<?php
highlight_file(__FILE__);
error_reporting(0);

$param2 = 'param2';
foreach($_GET['a'] as $key => $value){
    $$key = $value;
}
if (isset($param1)) {
    if ($param1 == $content){
        if($param2==='getflag'){
            echo getenv('FLAG');
        }
    }else{
        echo "Oh..nooo";
    }
}
?>

举个例子,如果 URL 是 example.com?a[foo]=bar&a[baz]=qux,那么 $_GET['a'] 将是:

array('foo' => 'bar', 'baz' => 'qux');

这个可变变量就是两个美元符号,最终的变量由第二个美元符号变量的值决定。

比如 $a=‘flag’; $$a就是$flag;

多重$ 套娃变量
#
<?php
highlight_file(__FILE__);
$a='b';
$b='c';
$c='d';
$d='e';
echo $$$$a;
?>

这个最后执行返回的是’e’;

从右到左一层一层分析,第一次见到的时候是比较懵b的。之前遇到过一个题,是获取scheme的,也是多重$记不清了。。。

parse_str
#

parse_str() 函数把查询字符串解析到变量中。

<?php
parse_str("name=Peter&age=43");
echo $name."<br>";
echo $age;
?>

上面的代码取自菜鸟教程。可以看到parse_str就是把字符串转为变量。

import_request_variables
#

import_request_variables() 函数将 GET/POST/Cookie 变量导入到全局作用域中。该函数在最新版本的 PHP 中已经不支持。

import_request_variables() 函数将 GET/POST/Cookie 变量导入到全局作用域中。如果你禁止了 register_globals,但又想用到一些全局变量,那么此函数就很有用。

版本要求:PHP 4 >= 4.1.0, PHP 5 < 5.4.0