0x00 前言

咳咳,正好这个月还没交文章,就拿这篇文章充数吧。上周日为了锻炼我们的实战能力,队内进行了一次AWD模式的比赛,顺便总结一下经验教训。顺便一提,比赛时用来提交Flag的网站蛮好看的啊 (o゜゜)o

0x01 正文

开始比赛之后,第一件事肯定是要把网站什么的备份一下,拿到网站源代码。顺便在服务器里面找找flag的位置,方便一会直接拿,什么鬼?有两个flag,一个在根目录下面,一个在home文件里面。运维!!解释一下。当然,帅气的运维小哥哥很快的解决掉了呢,flag只在根目录下。

网站源代码

丢到Rips里面看看
丢你Rips

几秒钟之后就拿到了审计报告(审计速度是真的快,连口水都没来及喝,差评)
代码漏洞审计报告

与此同时的是,队友发现了一个PHP文件,目测可以直接出flag
这个我绝对不说是出题人故意的

当我们拿到这个flag的时候,发现了一个绝望的事情,没有提交Key?运维小哥哥,Key呢?几分钟之后,我们成功的拿到了第一血。当然也要赶紧把自己这边的这个文件删掉(/\)。

审计代码这边也发现了几处问题。
一句话
参数覆盖漏洞?

当然不止这一个问题,这里还有个上传文件的问题,这里有个上传函数并没有对上传的文件进行限制,也就是我们甚至可以直接上传PHP文件执行(这里我稍后会给一个相对通用的脚本进行解决这个文件上传的问题)。

在随后的比赛中,我们找到了两处任意文件读取的漏洞,这个解决方案也很简单。

文件任意读取

文件任意读取

直接上代码了

1
2
3
4
5
6
7
8
9
<?php 

if($_GET['id']){
if(strstr($id, ‘.’)){return} // 加上一句这个,只要判断存在"."我就直接pass掉,就是这么任性。不服来咬我啊。
file_get_contents('/files/'.$id);
}else{
echo '<script>window.location.href="index.php?file=job";</script>'
}
?>

敲黑板,我刚才说写个脚本来通杀一下文件上传的这个问题,没错,就是基本通杀,如果有什么问题,就直接在评论中骂我就行了,反正我是不会看的。

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
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018/6/12 下午9:44
# @Author : 土豆豆
# @File : Directory protection.py
# @Software: PyCharm
# 其他說明: 本代碼除團隊內成員可以隨意使用,其他任何情況下(包括但不限於修改,使用)需表明代碼出處
# 如果認為腳本執行效率存在問題,我才不會告訴你可以嘗試使用 Cython 編譯後執行會提高一點效率。


import os, re

FILE_LIST = {}
FILE_LIST_NOW = {}
PROHIBITED = 'php' # 正則判斷語句,需要的條件寫在這裡
PROHIBITED = re.compile(PROHIBITED, re.I) # 編譯正則語句,目測可以讓效率提升
TEMP = []


def flush():
"""獲取目錄下的全部文檔

:return: 返回所有文檔路徑的set
"""
for fpathe, dirs, fs in os.walk('.'):
for f in fs:
TEMP.append(os.path.join(fpathe, f))

return set(TEMP)


def scanning():
""" 掃描當前所有新添加的文檔

:return: 返回新添加的文檔set
"""
TEMP = []
for fpathe, dirs, fs in os.walk('.'):
for f in fs:
TEMP.append(os.path.join(fpathe, f))
FILE_LIST_NOW = set(TEMP)

return FILE_LIST_NOW - FILE_LIST


if __name__ == '__main__':
FILE_LIST = flush()
while True:
file = scanning()
for i in file:
try:
f = str(open(i, 'rb').read()) # 讀取文檔
if re.search(PROHIBITED, f).group(): # 檢測文檔是否包含指定內容,如果存在,立刻移除,並返回提示
os.remove(i)
print('There has find a warning file, and it was remove,the file name is {}'.format(i))
except FileNotFoundError:
print('F')
except UnicodeDecodeError:
print('U')
except AttributeError:
print('A')
if not file:
# 移除文檔後更新文檔列表
FILE_LIST = flush()

0x02 结束语

嗯,就酱吧,上面的代码看不懂就算了,反正我也不会讲给你的。還有就是謝謝运维小哥哥的辛苦付出,另外,提交flag的網站真的很好看的呢,稀飯。哼~不打个赏点个赞的嘛。