跟着crownless学Web之strcmp、extract变量覆盖
简介:
本文由Web安全版块的新版主crownless原创讲解。下文将以CTF赛题讲解的形式为大家介绍一系列的Web基础知识,讲解的顺序将是循序渐进,因此不需要读者有任何基础知识。希望能吸引更多人关注看雪的Web安全版块,为版块增加人气和活力。
本篇为『跟着crownless学Web系列』的第三和第四部分,建议没有了解前两部分的同学可以先了解学习前面两部分的内容,具体学习入口见下:
点击即可阅读:
在这篇文章中,你将学到:
php isset函数
php strcmp函数
php die函数
话不多说,让我们开始吧。首先打开这次的CTF赛题网站:
http://139.224.220.67:23900/dmsj/level0/
你会发现一片空白,网页的源代码也为空。这里,我提供php后端的源代码供你审计:
<?php
$flag = "flag{xxxxx}";
if (isset($_GET['a'])) {
if (strcmp($_GET['a'], $flag) == 0)
die('Flag: '.$flag);
else
print 'No';
}
?>
首先,flag
变量被设置为flag{xxxxx}
。当然,这是一个假的flag,真实运行的后端中的flag
变量才是真的flag,需要我们去夺取。
接着,isset函数判断HTTP GET请求中的参数a
是否已设置并且非NULL。strcmp函数将a
参数与flag
相比较,如果一致,则调用die函数。die函数的作用是打印die函数的参数,并立即停止该php后端的运行。那么我们的目标很明显,就是要让php执行到die函数,让flag显示出来。
那么我们怎么给php后端传参呢?在第一篇教程中,我们可以通过在输入框中输入内容并点击提交按钮,由浏览器帮助我们自动传参。现在,我们必须要手动传参了。其实也很简单,只要访问http://139.224.220.67:23900/dmsj/level0/?a=123即可给a
参数传入123
。
接下来难题来了,你根本不知道flag是什么,又怎么让strcmp函数返回0,即比较相等呢?
查看strcmp的介绍页面,我们可以发现下方有一条注释:
If you rely on strcmp for safe string comparisons, both parameters must be strings, the result is otherwise extremely unpredictable.
即,如果我们给strcmp传入非字符串的参数,那么结果是非常未知的。
下面还给出了一些例子:
strcmp("5", 5) => 0
strcmp("15", 0xf) => 0
strcmp(61529519452809720693702583126814, 61529519452809720000000000000000) => 0
strcmp(NULL, false) => 0
strcmp(NULL, "") => 0
strcmp(NULL, 0) => -1
strcmp(false, -1) => -2
strcmp("15", NULL) => 2
strcmp(NULL, "foo") => -3
strcmp("foo", NULL) => 3
strcmp("foo", false) => 3
strcmp("foo", 0) => 1
strcmp("foo", 5) => 1
strcmp("foo", array()) => NULL + PHP Warning
strcmp("foo", new stdClass) => NULL + PHP Warning
strcmp(function(){}, "") => NULL + PHP Warning
怎么样,是不是让人大开眼界呢?这就是“世界上最好的语言”——php。
事实上,我们可以给a
参数传入一个数组。比如,如果我们访问:
http://139.224.220.67:23900/dmsj/level0/?a[0]=123
那么我们就相当于给a
参数传入了一个数组,该数组的第0个元素是123
字符串。
试试看访问:
http://139.224.220.67:23900/dmsj/level0/?a[0]=123
你会惊喜地发现打印出了flag。当php将一个数组变量和一个字符串进行比较时会意外地返回0,即相等,是不是很让人惊讶呢?
好了,以上就是『跟着crownless学Web』的第三部分内容。
接下来,一起进入第四部分的学习吧~
在这篇文章中,你将学到:
php extract函数
php trim函数
php file_get_contents函数
php伪协议data://
话不多说,让我们开始吧。首先打开这次的CTF赛题网站:
http://139.224.220.67:23900/dmsj/level2/
你会发现一片空白,网页的源代码也为空。这里,我提供php后端的源代码供你审计:
<?php
$flag='xxx';
extract($_GET);
if(isset($sixstars)) {
$content=trim(file_get_contents($flag));
if ($sixstars==$content) {
echo 'flag{xxx}';
} else {
echo 'Oh.no';
}
}
?>
首先,flag
变量被设置为'xxx'
,一个简单的字符串。
接着,后端运行了extract函数,从$_GE
T
数组中将变量导入到当前的符号表。什么意思呢?其实很简单。比如如果我们访问了:
http://139.224.220.67:23900/dmsj/level2/?sixstars=1
那么$_GET["sixstars"]
的值为字符串1
。执行extract($_GET);
时,就相当于执行了$sixstars='1'
。
然后,程序将会执行isset($sixstars)
。我们看到,为了获取flag,必须执行到echo 'flag{xxx}';
,所以isset($sixstars)
的返回值必须为TRUE
。
所以,我们必须通过extract($_GET);
将sixstars
变量设置为任意值,即使是空字符串也可以。
也就是说,即使访问:
http://139.224.220.67:23900/dmsj/level2/?sixstars=
也是可以的。但绝对不能不包含sixstars
参数。
接着,程序将会执行$content=trim(file_get_contents($flag));
。我们分步看。首先会执行file_get_contents($flag)
。正常情况下,如果你不通过URL传入flag
参数,那么,因为程序的最开始已经执行过$flag='xxx';
,所以到了这里将会执行file_get_contents('xxx')
。
file_get_contents函数可以“将整个文件读入一个字符串”。
比如如下代码可以将http://www.example.com/网站的源代码读取到homepage
变量中并显示出来。
<?php
$homepage = file_get_contents('http://www.example.com/');
echo $homepage;
?>
接着,php又会执行trim函数,它将会“去除字符串首尾处的空白字符(或者其他字符)”。
最后,php将会执行if ($sixstars==$content)
,如果为TRUE
,那么将会显示flag。
读到这里,你想必已经知道了我们该怎么做:首先,给sixstars
变量传入一个值,比如1
。然后,给flag
变量传入一个我们能控制的网站的地址,并让这个我们能控制的网站的源代码设置为1
。由于extract
能起到“变量覆盖”的作用,在extract
后,flag
变量就会被覆盖为我们能控制的网站的地址,而不再是'xxx'
,这样当执行到file_get_contents
时php后端将会从我们能控制的网站上读取到1
,并将其和sixstars
变量比较,并返回TRUE
,然后就能打印flag。
虽然这个方法是可行的,但是今天我要教你一个更简单的方法,那就是php伪协议。我们可以直接给flag
变量传入data://text/plain,1
。意思是明文1
。
这样file_get_contents('data://text/plain,1')
将会直接返回1
,就不需要我们在公网上开一台服务器了。
所以,最后我们的payload是:
http://139.224.220.67:23900/dmsj/level2/?sixstars=1&flag=data://text/plain,1
这里再强调一下,给后端传参的方法是:在?
后跟变量名字,不同的变量之间用&
隔开。
关于伪协议,我们以后有机会还会碰到。请大家继续关注看雪Web安全板块crownless的CTF赛题讲解。
作者:周信安
看雪ID: crownless,毕业于复旦大学软件工程专业,看雪WEB安全版块 新版主,研究方向为WEB安全、Android、系统安全。
个人博客地址:
https://zhouxinan.github.io
- End -
看雪ID:crownless
https://bbs.pediy.com/user-833800.htm
本文由看雪论坛 crownless 原创
转载请注明来自看雪社区
热门图书推荐:
(点击图片即可进入)
热门技术文章:
公众号ID:ikanxue
官方微博:看雪安全
商务合作:wsc@kanxue.com