php extract 变量覆盖,跟着crownless学Web之strcmp、extract变量覆盖

原标题:跟着crownless学Web之strcmp、extract变量覆盖

bc23649790398e5f60b68558c5494ab6.png

简介:

本文由Web安全版块的新版主crownless原创讲解。下文将以CTF赛题讲解的形式为大家介绍一系列的Web基础知识,讲解的顺序将是循序渐进,因此不需要读者有任何基础知识。希望能吸引更多人关注看雪的Web安全版块,为版块增加人气和活力。

本篇为『跟着crownless学Web系列』的第三和第四部分,建议没有了解前两部分的同学可以先了解学习前面两部分的内容,具体学习入口见下:

e32e98fa9a30abf4a7f666d2b7dc64a3.png

点击即可阅读:

跟着crownless学Web之(1)神奇的计算器

跟着crownless学Web之(2)calc2

跟着crownless学Web之(3)

在这篇文章中,你将学到:

php isset函数

php strcmp函数

php die函数

话不多说,让我们开始吧。首先打开这次的CTF赛题网站:

http://139.224.220.67:23900/dmsj/level0/

你会发现一片空白,网页的源代码也为空。这里,我提供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", newstdClass) => 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』的第三部分内容。

接下来,一起进入第四部分的学习吧~

跟着crownless学Web之(4)

在这篇文章中,你将学到:

php extract函数

php trim函数

php file_get_contents函数

php伪协议data://

话不多说,让我们开始吧。首先打开这次的CTF赛题网站:

http://139.224.220.67:23900/dmsj/level2/

你会发现一片空白,网页的源代码也为空。这里,我提供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函数,从$_GET数组中将变量导入到当前的符号表。什么意思呢?其实很简单。比如如果我们访问了:

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变量中并显示出来。

$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赛题讲解。

46d77f101f1e36aaaacd54ac785371c7.png

作者:周信安

看雪ID:crownless,毕业于复旦大学软件工程专业,看雪WEB安全版块 新版主,研究方向为WEB安全、Android、系统安全。

个人博客地址:

https://zhouxinan.github.io

- End -

9ea79ecbc95a49228e7725c9e4407188.png

看雪ID:crownless

https://bbs.pediy.com/user-833800.htm

本文由看雪论坛 crownless原创

转载请注明来自看雪社区

热门图书推荐:

戳立即购买!

责任编辑:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值