文章目录
很久没写WP了,稍微记录下自己的做题过程:
Crypto
0x01 Ordinary keyboard
这是一道安恒18年11月份的密码原题:
题目提示是凯撒,但是我没按提示来做,首先根据题目将明文和密文对应起来做一个表,如下所示:
数字不会发生变化,直接写脚本,替换一下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
from string import maketrans a='iloveyoublogwechat}{flag' b="+p)g$_)'hp)uA$ezr&,.spru" c='spru.r5sf3h7660h7394e169699hffe0s0h$4,' d=maketrans(b,a) f=c.translate(d) flag=[] for i in range(len(c)): if c[i] == f[i] and ord(f[i])>57: print c[i],f[i] flag+='?' else: flag+=f[i] print ''.join(flag) |
结果为:
?是没有确定的值,可以把其他没用过的字母填上测试,最后测出来是d
0x02 RSA
利用openssl得到公钥中n和e的值:
openssl rsa -pubin -text -modulus -in pub.key
1 2 3 4 5 6 7 8 |
Exponent: 65537 (0x10001) Modulus=C0332C5C64AE47182F6C1C876D42336910545A58F7EEFEFC0BCAAF5AF341CCDD writing RSA key -----BEGIN PUBLIC KEY----- MDwwDQYJKoZIhvcNAQEBBQADKwAwKAIhAMAzLFxkrkcYL2wch21CM2kQVFpY9+7+ /AvKr1rzQczdAgMBAAE= -----END PUBLIC KEY----- |
得到n的值,直接到http://factordb.com分解一下得到p和q:
可以计算出d,最后利用pow(c,d,n)计算出m来,脚本如下:
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 |
#-*- coding:utf-8 -*- import gmpy2 from gmpy2 import invert, iroot from Crypto.PublicKey import RSA def rsa1(n, p, q, e): assert n == p * q d = invert(e, (p - 1) * (q - 1)) return d with open('pub.key','r') as f: key=RSA.importKey(f) n=key.n e=key.e p=285960468890451637935629440372639283459 q=304008741604601924494328155975272418463 print n assert q*p==n d=rsa1(n, p, q, e) with open("flag.enc","rb") as f: c=f.read().encode('hex') c=int(c,16) m=pow(c,d,n) print hex(m)[3:].decode('hex') |
0x03 DSA attack
之前没做过DSA这种非对称加密方式的题,这次好好学习了下新知识:


本题给出的message3和message4的签名中r是相同的,也就是说,这两个签名使用了相同的k,可以轻松解出私钥x,脚本如下:
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 |
#coding=utf8 from Crypto.PublicKey import DSA import hashlib import gmpy2 with open('./dsa_public.pem') as f: key = DSA.importKey(f) y = key.y g = key.g p = key.p q = key.q f3 = open("packet3/message3", 'rb') f4 = open("packet4/message4", 'rb') data3 = f3.read() data4 = f4.read() m3 = int(hashlib.sha1(data3).hexdigest(), 16) m4 = int(hashlib.sha1(data4).hexdigest(), 16) print m3, m4 s3 = 0x1B474F2C1C9E85B72841AD84D9A871A11EF0F323 s4 = 0x0EA21858C18AA1EDF4058B6EB9E02B0176243658 r = 0x12E780EE8471DC3552572BB6E818F6D22CE16EA4 ds = s4 - s3 dm = m4 - m3 k = gmpy2.mul(dm, gmpy2.invert(ds, q)) k = gmpy2.f_mod(k, q) tmp = gmpy2.mul(k, s3) - m3 x = tmp * gmpy2.invert(r, q) x = gmpy2.f_mod(x, q) flag=hex(int(x))[2:-1] print flag print hashlib.md5(flag.decode('hex')).hexdigest() |
Misc
0x01 qr
直接一扫得到flag:
0x02 wireshark
在第二个流里就直接找到了:
0x03 百里挑一
首先搜到flag的位置,但是这只是flag的前半部分,还得继续找后半部分:
后半部分在第114个流里:
Web
0x01 WebScan
1 2 |
payload: 101.71.29.5:10009/index.php?act=about&file=/etc/httpd/conf/httpd.conf |
0x02 刀塔
使用敏感文件泄露扫描,发现有www.zip
flag.php里有明文flag
0x03 美男子
在源代码里发现提示,有index.phps:
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 |
<?php include 'global.php'; function AttackFilter($StrKey,$StrValue,$ArrReq){ if(is_array($StrValue)) { $StrValue=implode($StrValue); } if (preg_match("/".$ArrReq."/is",$StrtValue)==1){ print "holy shit!"; exit(); } } $filter = "union|select|from|where|join|sleep|benchmark|,|\(|\)"; foreach($_POST as $key=>$value){ AttackFilter($key,$value,$filter); } if(!isset($_POST['key1']) || !isset($_POST['key2'])) { print <<<DBAPP <img src='image/img.jpg' /> <!--index.phps--> DBAPP; die; } $query = mysql_query("SELECT * FROM tb_ctf WHERE key1 = '{$_POST['key1']}'"); if(mysql_num_rows($query) == 1) { $key = mysql_fetch_array($query); if($key['key2'] == $_POST['key2']) { print $flag; }else{ print "Error!"; } }else{ print "Error!"; } |
代码审计一波,绕过注入,rollup回滚
REVERSE
0x01 Mysterious
IDA打开找到可疑字符串,直接跟到代码段:
可以看到输入的字符串中的v12是一段数字,v12+1=123,说明v12是122,v14为x,v15为y,v16为z,输入122xyz即可得到flag
0x02 findKey
这里连续使用了两个 push,需要把下面一个nop掉才能使用f5插件
根据库函数可以看出这里经过md5加密,直接写脚本解决异或,再将得到的md5去查下明文
得到值以后只需要动态调试时修改参数,就能得到最后的flag
或者根据代码逻辑写个脚本,再进行一次上面的异或操作,即可得到flag
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
a='0kk`d1a`55k222k2a776jbfgd`06cjjb' b='SS' md5='' for i in range(len(a)): md5+=chr(ord(a[i])^ord(b[i%2])) print md5 c=[0x57,0x5E,0x52,0x54,0x49,0x5F,0x1,0x6D,0x69,0x46,0x2,0x6E,0x5F,0x2,0x6C,0x57,0x5B,0x54,0x4C] d='123321' flag='' for i in range(len(c)): flag+=chr(c[i]^ord(d[i%len(d)])) print flag |
0x03 CrackRTF
首先是第一个比较,和40个字节的字符串比较,使用sub_40100A,跟进去发现是sha1,而且前六位是数字,直接利用字符串和@DBApp拼接爆破得到前6位字符串:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import string import itertools import hashlib import requests import re sha256enc='6E32D0943418C2C33385BC35A1470250DD8923A9'.lower() key='@DBApp' code = '' strlist = itertools.product(string.digits, repeat=6) for i in strlist: code = i[0] + i[1] + i[2] + i[3]+ i[4]+ i[5] encinfo = hashlib.sha1(code+key).hexdigest() if encinfo == sha256enc: print code |
得到前六位123321
到达第二步:
这次变成了md5,爆破六位未知字符有点吃力,为了省事直接到google的gpu里用hashcat爆:
最后把字符串输入,直接打开生成的rtf文件获得flag