the third day

 · 2019-8-1 · 次阅读


9.本地包含(http://123.206.87.240:8003/)
进入链接后,发现如下代码:
<?php
error_reporting(0);

include ‘flag.php’;
$a = @$REQUEST[‘hello’];
eval(“ var_dump( $a );”);
highlight_file(_FILE
);
?>

  又是一道代码审计的题目,第二行的error_reporting(0),是关闭错误报告。第4行使用了include函数包含了一个flag.php.第五行是说变量a是由request方式传入的hello的值。(搜了一下@$_REQUEST 的意思是获得参数,不论是@$_GET还是@$_POST可以得到的参数@$_REQUEST都能得到。)

  第六行的eval函数还不太熟悉,经查验它的用法是把字符串按照PHP代码来计算,该字符串必须是合法的PHP代码,且必须以分号结尾,如果没有在代码字符串中调用return语句,则返回NULL如果代码中存在解析错误则返回false.其实看到这里我不是很明白他的用法,但括号里面的var_dump是以数组对应的形式输出变量a.最后一行代码是显示FILE.
  读完代码依然不是很清楚解题思路,先从其中具体的函数分析,首先是eval里面的var_dump函数,上文说过它是输出变量的数组表示形式,但这个函数还有一个很特殊的地方是它是代码片段执行,也就是说变量a可以是几串代码的组合形式,然后再被var_dump一起显示出来,首先测试了一下?hello=1);print_r(2 —对于这里hello=1后面加的括号我很懵逼,对于新手的我赶紧查阅了资料,原来跟sql注入的引号是一个原理啊,哈哈—默默感到自己蠢了。不说废话了,接下来应该测试将flag.php显示出来,首先任然使用hello=1);进行闭合,之后写入关键语句show_source(‘flag.php’);—show_source即highlight的别名也为高亮度显示文件内容,括号内为文件名。也就是以get形式传给request,在URL中的payload为?hello=1);show_source(‘flag.php’
  以上为阅览多篇wp自己总结下来的,就这样得到了flag.
  summary:这次应该做一次很深刻的反省了。第一自己的PHP学习的实在太差了,对于关键的函数掌握的非常浅显,因而还亟需补给一下自己的PHP知识。第二关于代码的审计,其实就几行代码很好理解,但是对于其利用自己还是没有那种意思去构造,去绕过,比如这里的eval函数是执行其中的代码串,由于其中有一个变为输出数组的函数因而采用sql注入中闭合的类似用法括号闭合因而绕过var_dump,之后的;也须使用一个var_dump来闭合,然后中间部分写入payload,即show_source(‘flag.php’),让其直接显示出flag.此题解法还有很多,不同人写出的payload不尽相同,但我更能理解自己的这一种方法。

要点:
eval() 函数存在命令执行漏洞,构造出文件包含会把字符串参数当做代码来执行。
file() 函数把整个文件读入一个数组中,并将文件作为一个数组返回。
10.变量1(http://123.206.87.240:8004/index1.php
  首先进入链接,会看到提示信息说是flag在变量中。以下是提示代码内容:
<?php

error_reporting(0);
include “flag1.php”;
highlight_file(file);
if(isset($_GET[‘args’])){
$args = $_GET[‘args’];
if(!preg_match(“/^\w+$/“,$args)){
die(“args error!”);
}
eval(“var_dump($$args);”);
}
?>
  第三行就不说了关闭错误报告,也就是不给错误回显。又是一个include函数包含了flag1.php.下一行依旧提示会高亮显示文件内容。之后是关键的条件语句。如果以get方式设置了args这个参数,那么args变量就为那个参数的值,如果args不匹配正则表达式的内容的话,就报错,最后一行任是一个eval函数执行里面的输出数组函数。可以看到很有趣的是var_dump函数中写的是$$args.
  接下来去url中进行尝试。首先我输入了?args=args,很明显输出了args的数组对应形式–string(4)”args”,这里设置了args,并且变量args的内容也为args,因而这样条件判断下来输出了args的var_dump形式。这里还须对正则表达式的理解,首先是//这是括号里面的两个分界,也就是说处于这里面的内容是正则表达式需要匹配的内容。^是匹配其首部,而$正好为匹配其尾部,\w代表的是匹配包括下划线的字符串—记忆的话因为w是word的缩写,因而应当为匹配字符。可以看到后面还有个+号,它是匹配前面的子表达式一次或多次。例如zo+能匹配zo以及zoo但不能匹配z。
综上也就是args要为一个字符串否则就报错。但是很明显如果args为其他变量,很明显应该在没有设置的情况下都为Null.因而接下来测试采用很特殊的超全局变量$GLOBALS进行测试—对于$GLOBALS的学习,这种全局变量在PHP脚本中的任意位置访问全局变量,从函数或方法中均可,PHP在$GLOBLAS[index]的数组中存储了所有的全局变量。变量的名字就是数组的键。例如如果有变量$x=74,那么采用$GLOBALS[‘x’]就能访问到它。
最后在Url中写入payload,为?args=$GLOBALS,得到flag.
  summary:这道题我还算做的可以,主要是对正则表达式的理解以及preg_match函数掌握的还可以。最关键的是懂得利用$GLOBALS这个超全局变量,便能显示出所有的变量内容,再根据提示flag在变量中便拿下来了flag.

关于今天一天的总结:虽然每天的学习只有两个小时,并且今天只做了2道题,并且还是很早前做过的,虽然之前都是跟着WP操作一遍,并没有深刻的理解,但随着自己的博客的记录我觉得自己对于php代码的理解与审计加深了,今天这一天的题都是代码审计,最关键的就是对于PHP函数的重复理解以及利用,对此我还需要下去更深刻的去测试与理解,像C语言一样理解每一个东西都去自己敲一遍,去执行一下看一下结果,去测试那些语言的用法只有这样自己才能记得住,下次遇到才不会一脸懵,然后再去查php手册,that’s all.