前言

现在开始接触代码审计类型的题了,学长给我们讲过了bugku的一些题,然后我看了一些其他的社区的文章和博客,学习了简单的php代码审计,并在学习过后做几道相关的题来熟悉套路。

extract变量覆盖

知识了解

首先关于变量覆盖有这么一段简单代码可以说明(简单明了)

<?php
$a='lalala';
$lalala='xixixi';
echo $$a;
?>

输出结果是xixixi
再看看一个有漏洞的代码,

<?php
header("Content-type:text/html;charset=utf-8");//让浏览器能读懂
$a='aa';
$aa='123';
echo '第一次变量aa的值是'.$aa.'<br>';
$$a=$_GET['name'];
echo '第二次变量aa的值是'.$aa.'<br>';
?>

结果:
Augenstern
extract()函数的作用:
来自w3school
至于extract()变量覆盖就是两者综合。

例题实战

来自bugku
php代码:

<?php
$flag='xxx';
extract($_GET);
if(isset($shiyan)){
$content=trim(file_get_contents($flag));
if($shiyan==$content){
echo'flag{xxx}';
}else{
echo'Oh.no';
}
}
?>

学习过程中参考其他师傅的博客,然后发现有师傅尝试构造了?shiyan=1&flag=1,看起来是没错,但是flag没有显示出来。原因是变量覆盖的定义弄混淆了,覆盖的话,会覆盖数组中的同名元素会覆盖,那flag里,不只有数字吧,所以这样构造不行,也不能构造字母,那样也显示不出来,所以直接构造空,不用管flag里面是什么类型。
Augenstern
看出flag是有字母,有数字,还有杠。
还有一个大佬写的博客呢是这样的,先看题目代码。
Augenstern
这道题的话,那位师傅直接构造?gift=a&flag=a可以直接显示出来,为什么呢,就是因为这道题的flag全是字母。
因为我不知道这道题,所以就拿那个师傅的图记录一下,下面有这个师傅的博客的链接。
Augenstern
因为flag里都是字母,所以可以那样构造。这里放上那个师傅的博客51cto师傅博客

strcmp比较字符串

知识了解

strcmp(string $str1,string $str2);
如果str1>str2返回>0,如果str1<str2,返回<0,如果str1=str2,返回0。
来自w3school

例题实战

来自bugku
比较两个字符串大小,可以传入非字符串,直接传一个数组就行了。
strcmp()漏洞理解:
strcmp()要求传入字符串,如果传入的不是字符串,那么函数就会报错,返回return 0;这里虽然报错了,但是却让其函数值相等了。让flag显示出来了。
Augenstern

urldecode二次编码绕过

知识了解

urldecode()函数是对一个字符串(一般是URL字符串)进行解码。
Augenstern

例题实战

来自bugku
代码:

<?php
if(eregi("hackerDJ",$_GET[id])) {
echo("not allowed!");
exit();
}
$_GET[id] = urldecode($_GET[id]);
if($_GET[id] == "hackerDJ"){
echo "Access granted!";
echo "flag";
}
?>

使用$_GET时,浏览器就已经把hakerDJ进行了一次解码了,然后又用了urldecode函数又再次进行了一次解码。
再看代码逻辑是如果id=hackerDJ会返回not allowed。但是,要想得到flag,还是要让id=hackerDJ。绕过要进行二次编码。
字符串中随便一个字母,我选的是第一个h
所以找到它的URL编码格式
Augenstern
然后再次对%68进行编码
%2568,然后构造

?id=%2568ackerDJ

Augenstern

md5()函数

知识了解

来自w3school
php中MD5函数漏洞:
第一种:数组绕过

在PHP中,MD5是不能处理数组的,md5(数组)会返回null

第二种:

PHP在处理哈希字符串时,会利用”!=”或”==”来对哈希值进行比较,它把每一个以”0E”开头的哈希值都解释为0,所以如果两个不同的密码经过哈希以后,其哈希值都是以”0E”开头的,那么PHP将会认为他们相同,都是0。

常见的被MD5认成是0的几个字符串
纯数字类

240610708 0e462097431906509019562988736854
314282422 0e990995504821699494520356953734
571579406 0e972379832854295224118025748221
903251147 0e174510503823932942361353209384
1110242161 0e435874558488625891324861198103
1320830526 0e912095958985483346995414060832
1586264293 0e622743671155995737639662718498
2302756269 0e250566888497473798724426794462
2427435592 0e067696952328669732475498472343
2653531602 0e877487522341544758028810610885
3293867441 0e471001201303602543921144570260
3295421201 0e703870333002232681239618856220
3465814713 0e258631645650999664521705537122
3524854780 0e507419062489887827087815735195
3908336290 0e807624498959190415881248245271
4011627063 0e485805687034439905938362701775
4775635065 0e998212089946640967599450361168
4790555361 0e643442214660994430134492464512
5432453531 0e512318699085881630861890526097
5579679820 0e877622011730221803461740184915
5585393579 0e664357355382305805992765337023
6376552501 0e165886706997482187870215578015
7124129977 0e500007361044747804682122060876
7197546197 0e915188576072469101457315675502
7656486157 0e451569119711843337267091732412

大写字母类:

QLTHNDT 0e405967825401955372549139051580
QNKCDZO 0e830400451993494058024219903391
EEIZDOI 0e782601363539291779881938479162
TUFEPMC 0e839407194569345277863905212547
UTIPEZQ 0e382098788231234954670291303879
UYXFLOI 0e552539585246568817348686838809
IHKFRNS 0e256160682445802696926137988570
PJNPDWY 0e291529052894702774557631701704
ABJIHVY 0e755264355178451322893275696586
DQWRASX 0e742373665639232907775599582643
DYAXWCA 0e424759758842488633464374063001
GEGHBXL 0e248776895502908863709684713578
GGHMVOE 0e362766013028313274586933780773
GZECLQZ 0e537612333747236407713628225676
NWWKITQ 0e763082070976038347657360817689
NOOPCJF 0e818888003657176127862245791911
MAUXXQC 0e478478466848439040434801845361
MMHUWUV 0e701732711630150438129209816536

第三种:“0E”绕过
一些哈希后0E开头的字符

s878926199a
0e545993274517709034328855841020
s155964671a
0e342768416822451524974117254469
s214587387a
0e848240448830537924465865611904
s214587387a
0e848240448830537924465865611904
s878926199a
0e545993274517709034328855841020
s1091221200a
0e940624217856561557816327384675
s1885207154a
0e509367213418206700842008763514
s1502113478a
0e861580163291561247404381396064
s1885207154a
0e509367213418206700842008763514
s1836677006a
0e481036490867661113260034900752
s155964671a
0e342768416822451524974117254469
s1184209335a
0e072485820392773389523109082030
s1665632922a
0e731198061491163073197128363787
s1502113478a
0e861580163291561247404381396064
s1836677006a
0e481036490867661113260034900752
s1091221200a
0e940624217856561557816327384675
s155964671a
0e342768416822451524974117254469
s1502113478a
0e861580163291561247404381396064
s155964671a
0e342768416822451524974117254469
s1665632922a
0e731198061491163073197128363787
s155964671a
0e342768416822451524974117254469
s1091221200a
0e940624217856561557816327384675
s1836677006a
0e481036490867661113260034900752
s1885207154a
0e509367213418206700842008763514
s532378020a
0e220463095855511507588041205815
s878926199a
0e545993274517709034328855841020
s1091221200a
0e940624217856561557816327384675
s214587387a
0e848240448830537924465865611904
s1502113478a
0e861580163291561247404381396064
s1091221200a
0e940624217856561557816327384675
s1665632922a
0e731198061491163073197128363787
s1885207154a
0e509367213418206700842008763514
s1836677006a
0e481036490867661113260034900752
s1665632922a
0e731198061491163073197128363787
s878926199a
0e545993274517709034328855841020
240610708 
0e462097431906509019562988736854
314282422 
0e990995504821699494520356953734
571579406 
0e972379832854295224118025748221
903251147 
0e174510503823932942361353209384
1110242161 
0e435874558488625891324861198103
1320830526 
0e912095958985483346995414060832
1586264293 
0e622743671155995737639662718498
2302756269 
0e250566888497473798724426794462
2427435592 
0e067696952328669732475498472343
2653531602 
0e877487522341544758028810610885
3293867441 
0e471001201303602543921144570260
3295421201 
0e703870333002232681239618856220
3465814713 
0e258631645650999664521705537122
3524854780 
0e507419062489887827087815735195
3908336290 
0e807624498959190415881248245271
4011627063 
0e485805687034439905938362701775
4775635065 
0e998212089946640967599450361168
4790555361 
0e643442214660994430134492464512
5432453531 
0e512318699085881630861890526097
5579679820 
0e877622011730221803461740184915
5585393579 
0e664357355382305805992765337023
6376552501 
0e165886706997482187870215578015
7124129977 
0e500007361044747804682122060876
7197546197 
0e915188576072469101457315675502
7656486157 
0e451569119711843337267091732412
QLTHNDT 
0e405967825401955372549139051580
QNKCDZO 
0e830400451993494058024219903391
EEIZDOI 
0e782601363539291779881938479162
TUFEPMC 
0e839407194569345277863905212547
UTIPEZQ 
0e382098788231234954670291303879
UYXFLOI 
0e552539585246568817348686838809
IHKFRNS 
0e256160682445802696926137988570
PJNPDWY 
0e291529052894702774557631701704
ABJIHVY 
0e755264355178451322893275696586
DQWRASX 
0e742373665639232907775599582643
DYAXWCA 
0e424759758842488633464374063001
GEGHBXL 
0e248776895502908863709684713578
GGHMVOE 
0e362766013028313274586933780773
GZECLQZ 
0e537612333747236407713628225676
NWWKITQ 
0e763082070976038347657360817689
NOOPCJF 
0e818888003657176127862245791911
MAUXXQC 
0e478478466848439040434801845361
MMHUWUV 
0e701732711630150438129209816536

例题实战

来自bugku
代码:

<?php
error_reporting(0);
$flag = 'flag{test}';
if (isset($_GET['username']) and isset($_GET['password'])) {
if ($_GET['username'] == $_GET['password'])
print 'Your password can not be your username.';
else if (md5($_GET['username']) === md5($_GET['password']))
die('Flag: '.$flag);
else
print 'Invalid password';
}
?>

==等于,只需要等号两边的值是否相等。比如‘1’==1就成立,返回true。
===全等,需要全等号两边的值和类型全都相等才成立。
这道题需要username和password全等但是username又不能等于password。比较矛盾,多看几遍理解还是比较容易理解的。
数组绕过:构造?username[]=1&password[]=2
Augenstern

数组返回NULL绕过

知识了解

  • ereg — 正则表达式匹配
    ereg函数的漏洞:
    ①%00截断及遇到%00则默认为字符串的结束
    ②当传入的不是字符串而为一个数组时它的返回值不是FALSE,而是NULL
  • strpos的参数同样不能够是数组,所以返回的依旧是null,null不等于false也是正确。

    例题实战

    Augenstern
    [a-zA-Z0-9]
    方括号表示字符集,[A-Za-z0-9]匹配大小写字母和数字其中一个字符
    其他的是正则表达式。
    看代码:
    这个password必须以数字或者字母开头
    并且还要在password中检测到--的存在
    第一种:
    可以考虑%00截断
    构造?password=a%00--
    得到flag
    第二种:
    考虑数组
    构造?password[]=--
    得到flag
    第三种:
    这个得到flag有点不明白,同样是数组,但是构造?password[]=1
    同样得到flag。看了大佬的博客知道可以这样得到flag,但是具体原因,不晓得。
    结果:
    Augenstern

    弱类型整数大小比较绕过

    题中了解相关知识

    来自bugku
    代码:
    三元运算符判断传入的是不是一个数字,是返回no mumeric(不是数字),否返回NULL。
    再判断传入的是否大于1336.,大于就打印flag。
    我想的是构造?password=2587abc
    这样它既不是一个数字又大于1336.应该是可以打印出flag的。
    第二种,
    代码本来自身矛盾,但是PHP数组有一个缺陷就是大多数的函数都没有办法去判断数组。可以通过数组绕过。
    构造?password[]=a两种方法都可以得到flag
    Augenstern

    刷题(随便记一下)

    一、十六进制与数字比较

十六进制与数字比较,参考bugku的一道题,代码还是比较简单的,代码还是有矛盾,要想办法绕过,有一点记住就行了php在转码时会把16进制转化为十进制,所以在构造payload的时候将数字转换为十六进制的就行了。
这个还有就是可以数组绕过,直接构造数组就可以绕过。也没什么需要注意的。

二、数字验证正则绕过

<?php
error_reporting(0);
$flag = 'flag{test}';
if ("POST" == $_SERVER['REQUEST_METHOD']){
$password = $_POST['password'];
if (0 >= preg_match('/^[[:graph:]]{12,}$/', $password)) //preg_match — 执行一个正则表达式匹配
{
echo 'flag';
exit;
}
while (TRUE){
$reg = '/([[:punct:]]+|[[:digit:]]+|[[:upper:]]+|[[:lower:]]+)/';
if (6 > preg_match_all($reg, $password, $arr))
break;
$c = 0;
$ps = array('punct', 'digit', 'upper', 'lower'); //[[:punct:]] 任何标点符号 [[:digit:]] 任何数字 [[:upper:]] 任何大写字母 [[:lower:]] 任何小写字母
foreach ($ps as $pt){
if (preg_match("/[[:$pt:]]+/", $password))
$c += 1;
}
if ($c < 3) break;//>=3,必须包含四种类型三种与三种以上
if ("42" == $password) echo $flag;
else echo 'Wrong password';
exit;
}
}
?>

源码给出,一点一点看,先看打印flag的地方,
Augenstern
[:graph:]是代表printable and visible的字符,是除空格符(空格键与[TAB]键)之外的所有按键,
控制字符不算[:graph:]
然后这个意思是匹配的password的长度要大于12,这里我用lalalalalalala
然后继续看
Augenstern
[:punct:]是匹配这些特殊字符

[!"#$%&'()*+, \-./:;<=>?@ [\\\]^_`{|}~]

[:digit:]是匹配0-9的数字
[:upper:]是匹配大写字母A-Z
[:lower:]是匹配小写字母a-z
关于正则匹配的一些知识参考大佬博客

所以这一句的意思是password里还要匹配到数字、字符、大写和小写字母。
我这里将上面的payload改一下lalaLal4_ala
继续
Augenstern
这里提示已经有了 ,必须包含四种类型三种与三种以上
上面的payload已经符合要求。
"42"==$password这个是个弱类型比较数字大小,只要前两位是数字,后面的字母在进行比较时会被强行转换成数字来比较,这里相等,所以我再把payload改一下,42laLal4_ala就可以绕过了吧,试一下。
还有一点就是,题目上的请求方式是post方式,所以这里抓一下包进行修改
Augenstern
得到flag
最后这两题原本也是要详细的写一下知识了解的,后来想想还是不写了,过于啰嗦了。 继续学习加油。