简单网管协议 发现snmp协议,跟踪UDP流可发现 flag{077149a68b9d4f25f52bb11530f44028}
炫酷的战队Logo 下载看到是张bmp图片,头部有缺失,补上424D,保存发现只是张普通的图片,发现最后有IEND的png结尾,使用dd将其裁剪出来
1 dd if =./phrack.bmp of=out.png ibs=0x1171a9 skip=1 count=1
发现ihdr有错误,根据ihdr crc32爆破出相应的w,h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import binasciiimport structwith open("./out.png" ,'rb' ) as f: data = f.read() f.close() crc = struct.unpack(">I" ,data[29 :33 ])[0 ] for w in range(1024 ): for h in range(1024 ): ihdr = b"IHDR" + struct.pack(">I" ,w) + struct.pack(">I" ,h)+b"\x08\x02\x00\x00\x00" if crc == binascii.crc32(ihdr): data = data[:12 ]+ihdr+data[29 :] break with open("out2.png" ,"wb" ) as f: f.write(data) f.close()
Scan Wireshark打开,发现开头是个icmp,推测每次扫描之前都要用icmp测试一下,然后过滤icmp 从后往前一个个试,最后发现为155989这个
1 2 3 echo -n 155989|openssl dgst -sha256
远程登录协议 过滤telnet追踪TCP流,发现 FLAG:f69dd04e38ef85e38b2f148475ce32bc
shell流量分析 追踪TCP流发现一个python脚本
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 __author__ = 'Aklis' from Crypto import Randomfrom Crypto.Cipher import AESimport sysimport base64def decrypt (encrypted, passphrase) : IV = encrypted[:16 ] aes = AES.new(passphrase, AES.MODE_CBC, IV) return aes.decrypt(encrypted[16 :]) def encrypt (message, passphrase) : IV = message[:16 ] length = 16 count = len(message) padding = length - (count % length) message = message + '\0' * padding aes = AES.new(passphrase, AES.MODE_CBC, IV) return aes.encrypt(message) IV = 'YUFHJKVWEASDGQDH' message = IV + 'flag is hctf{xxxxxxxxxxxxxxx}' print len(message)example = encrypt(message, 'Qq4wdrhhyEWe4qBF' ) print exampleexample = decrypt(example, 'Qq4wdrhhyEWe4qBF' ) print example
后边发现密文:
将脚本改一下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import sysimport base64from Crypto import Randomfrom Crypto.Cipher import AESdef decrypt (encrypted, passphrase) : IV = encrypted[:16 ] aes = AES.new(passphrase, AES.MODE_CBC, IV) return aes.decrypt(encrypted[16 :]) IV = 'YUFHJKVWEASDGQDH' message = "mbZoEMrhAO0WWeugNjqNw3U6Tt2C+rwpgpbdWRZgfQI3MAh0sZ9qjnziUKkV90XhAOkIs/OXoYVw5uQDjVvgNA==" .decode("base64" ) example = decrypt(message, 'Qq4wdrhhyEWe4qBF' ) print example
webshell分析 分析流量发现一个访问了一个ironshell.php的文件,猜测这就是webshell 。用如下规则过滤出来
1 ip.addr == 115.28.102.80 && http.request.uri matches "ironshell.php"
发现最后一个包的url里有个flag猜测这个包里就有要的关键数据,跟踪TCP流将其数据dump出来保存到一个html里 发现疑似flag的东西,解base64发现是个url访问是张二维码,扫码可得flag
1 2 3 ➜ findwebshell echo "aHR0cHM6Ly9kbi5qYXJ2aXNvai5jb20vY2hhbGxlbmdlZmlsZXMvQWJUekEyWXRlRmpHaFBXQ2Z0cmFvdVZEM0I2ODRhOUEuanBn" |base64 -D https://dn.jarvisoj.com/challengefiles/AbTzA2YteFjGhPWCftraouVD3B684a9A.jpg
flag binwalk分析下发现有个压缩包
猜测LSB隐写,stegsolve打开发现一个zip
Dump发现打不开,再来binwalk一下,解出来一个elf文件。。。 ida打开
misc100 下来看看是个apk,直接用dex2jar转诊jar然后jd-gui打开
1 ➜ easy100 d2j-dex2jar.sh easy100.apk
直接就看到这个,猜测这应该就是加密之后的,继续看
这里调用了MainActivity.a,两个参数,一个是MainActiviry.a(this.a)的返回值,一个是输入的字符串 然后看看c.a()都干了啥,c这个类里有2个叫a的方法,应该是重写的,先看2个参数的那个
New了一个a类,
所以当初调用的时候第一个参数是key,第二个参数就是明文然而我并不知道第一iv是啥,一度以为是空字符串的md5…本垃圾不懂java,不太懂,,研究了一下,貌似这个MaivAvtive.p()没人调用,就猜第一个参数应该是这个v。 然后将v的每两位换一下。写个脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 from Crypto.Cipher import AESfrom struct import pack as pwith open("./easy100/assets/url.png" ,"rb" ) as f: change_key = f.read()[144 :144 +16 ] f.close() key = bytearray() for _ in range(0 ,16 ,2 ): key.append(change_key[_+1 ]) key.append(change_key[_]) a = [21 , -93 , -68 , -94 , 86 , 117 , -19 , -68 , -92 , 33 , 50 , 118 , 16 , 13 , 1 , -15 , -13 , 3 , 4 , 103 , -18 , 81 , 30 , 68 , 54 , -93 , 44 , -23 , 93 , 98 , 5 , 59 ] b = b"" for _ in a: b+=p("b" ,_ ) c = AES.new(bytes(key),AES.MODE_ECB) m = c.decrypt(b) print(m)
you_need_python 解压一看是个脚本和一个乱码文件,文件名根据提示rfc4042知道那个文件是utf9编码的解码后是个字符串加加减减的,然后flag.py里的是python的字节码,写个脚本将其转成pyc
1 2 3 4 5 6 7 8 9 10 def to_pyc (code,filename) : data = bytearray(imp.get_magic()) data += struct.pack("<L" ,int(time.time())) data += code with open(filename,"wb" ) as f: f.write(data) f.close() code = zlib.decompress(base64.b64decode('eJxtVP9r21YQvyd/ieWm66Cd03QM1B8C3pggUuzYCSWstHSFQijyoJBhhGq9OXJl2ZFeqAMOK6Q/94f9Ofvn1s+d7Lgtk/3O997du/vc584a0eqpYP2GVfwDEeOrKCU6g2LRRyiK4oooFsVVUSqkqxTX6J1F+SfSNYrrdKPorC76luhbpOEGCZNFZw2KG3Rmk26QtuXi3xTb7ND6/aVu0g2RuvhEcZNut5lAGbTvAFbyH57TkYLKy8J6xpDvQxiiiaIlcdqJxVcHbXY6bXNlZgviPCrO0+StqfKd88gzNh/qRZyMdWHE29TZZvIkG7eZFRGGRcBmsXJaUoKCQ9fWKHwSqNeKFnsM5PnwJ7q2aKk4AFhcWtQCh+ChB5+Lu/RmyYUxmtOEYxas7i/2iuR7Ti14OEOSmU0RADd4+dQzbM1FJhukAUeQ+kZROuLyioagrau76kc1slY1NNaY/y3LAxDQBrAICJisV2hMdF2lxQcyFuMoqcX3+TCl6xotqzSpkqmxYVmjXVjAXiwBsEfBrd1VvTvLCj2EXRnhoryAKdpxcIgJcowUB68yAx/tlCAuPHqDuZo0CN3CUGHwkPhGMA7aXMfphjbmQLhLhJcHa0a+mpgB191c1U1lnHJQbgkHx+WGxeJbejnpkzSavo2jkxZ7i725npGAaTc8FXmUjbUETHUmkxXN5zqL5WiWxwE7Bc11yyYzNJpN02jerq+DzNNodfxOX8kE4FcmYKscDdYD1oPGGucXYNmgs1F+NTf3GOt3Mg7b+NTVruqoQyX1hOEUacKw+AGbP38ZOq9THRXaSbL5pXGQ8bho/Z/lrzQaHxdoCrlev+t6nZ7re57r+57rHXag93Deh37k+vuw9zorO/Qj/B50cAf2oyOsvut3D+ADWxdxfN/1Drqu39mHzvcRswv/Hvz7sHeg9w8Qzy99DzuFwxhPhs6zWTbOI3OZRiaZZcVj5wVwOklx7OwVxR47PR46r/SVM8ulBJic9zku/eqY/MqJxiDj+Gd55wS3f35pbLCzHoEwzKKpDkN5i+TR+1AYCWTo5IV0Z0P9H3phDDd6lMzPdS5bbo9eJGbTsW9nbDqLL1N9Iq+rRxDbll2x67a9Lf27hw5uK1s1rZr6DOPF+FI=' )) to_pyc(code,"dump.pyc" )
然后使用 uncompyle6 将pyc反编译乘py文件:
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 ➜ you_need_python uncompyle6 ./dump.pyc >source.py ➜ you_need_python cat ./source.py import hashlibdef sha1 (string) : return hashlib.sha1(string).hexdigest() def calc (strSHA1) : r = 0 for i in strSHA1: r += int('0x%s' % i, 16 ) return r def encrypt (plain, key) : keySHA1 = sha1(key) intSHA1 = calc(keySHA1) r = [] for i in range(len(plain)): r.append(ord(plain[i]) + int('0x%s' % keySHA1[i % 40 ], 16 ) - intSHA1) intSHA1 = calc(sha1(plain[:i + 1 ])[:20 ] + sha1(str(intSHA1))[:20 ]) return ('' ).join(map(lambda x: str(x), r)) if __name__ == '__main__' : key = raw_input('[*] Please input key:' ) plain = raw_input('[*] Please input flag:' ) encryptText = encrypt(plain, key) cipherText = '-185-147-211-221-164-217-188-169-205-174-211-225-191-234-148-199-198-253-175-157-222-135-240-229-201-154-178-187-244-183-212-222-164' if encryptText == cipherText: print '[>] Congratulations! Flag is: %s' % plain exit() else : print '[!] Key or flag is wrong, try again:)' exit()
我们可以看到key为utf9解出的那串字符串,然后sha1算hash再每一个字符按16进制加起来,那么我们现在知道keySHA和intSHA1,那么flag的第一位就是
1 x + int(keySHA1[0],16) - intSHA1 = -185
解方程就能求得flag了,所以现在的关键就是解出key
1 2 3 4 5 6 7 8 import utf9def getkey () : with open('./key_is_here_but_do_you_know_rfc4042' ,'rb' ) as f: data = utf9.utf9decode(f.read()) f.close() print(data)
一开始以为是xxfuck之类的、、最后查了一下发现就是单纯的下划线的算式,
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 import utf9import hashlibdef sha1 (string) : return hashlib.sha1(string).hexdigest() def calc (strSHA1) : r = 0 for i in strSHA1: r += int('0x%s' % i, 16 ) return r def getkey () : with open('./key_is_here_but_do_you_know_rfc4042' ,'rb' ) as f: data = utf9.utf9decode(f.read()) f.close() _ = 1 __ = 2 ___ = 3 ____ = 4 _____ = 5 ______ = 6 _______ = 7 ________ = 8 _________ = 9 __________ = 0 key = eval(data) return hex(key)[2 :].decode('hex' ) def decrypt (key) : c = '-185-147-211-221-164-217-188-169-205-174-211-225-191-234-148-199-198-253-175-157-222-135-240-229-201-154-178-187-244-183-212-222-164' c = [int(c[x:x+4 ]) for x in xrange(0 ,len(c),4 )] keySHA1 = sha1(key) intSHA1 = calc(keySHA1) m = '' for _ in xrange(len(c)): m += chr(c[_] + intSHA1 - int('0x%s' % keySHA1[_ % 40 ], 16 )) intSHA1 = calc(sha1(m[:_+1 ])[:20 ] + sha1(str(intSHA1))[:20 ]) return m key = getkey() print keym = decrypt(key) print m
Struts2漏洞 一说structs2就想到反序列化,但是本垃圾并不懂java,更别说structs2了,查了一下原理,看到这个https://blog.csdn.net/wpydaguan/article/details/45220025
于是猜测,url里有action关键字,用wireshark的正则匹配一下
1 http and !(http.request.uri matches "http://.*\.jpg.*" or http.request.uri matches "http://.*\.gif.*" ) and http.request.uri matches ".*action.*"
不多一个个看:
FLAG:E3274BE5C857FB42AB72D786E281B4B8
WPA2 首先nc连上去看看:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ➜ ~ nc pwn.jarvisoj.com 9893 Welcome to HuWang Bei WPA2 Simulation System.. Initilizing Parameters.. SSID = HuWang PSK = eygqW2NkTrmXfV94 AP_MAC = E2:73:76:65:9A:F0 AP_Nonce = fa2e6fbd9c1248451fba5f112773528f52907c795d89ba32102e00f60074922e STA_MAC = E9:88:69:8F:26:06 STA_Nonce = 85dd88520e836988028459c710284424a15af2b2884be36623d9d9b8c90cf2ab CCMP Encrypted Packet = 88423a01e988698f2606e27376659af0e27376659af060920000319c00200f00000023102cb86f5f401b2333e536a9148311f13b4d31e3c6556b3f0c7f6a3c4d058ce7d0ea87e2131d46a3 Input decrypted challenge value in Packet:
google一下,研究了半天懂了一点,WPA2是通过SSID与PSK生成一个PMK,然后通过PMK, AP nonce, STA nonce (SNonce), AP MAC address , and STA MAC address生成PTK,PTK又分为若干部分: EAPOL-Key Confirm Key、EAPOL-Key Encrypt Key用于EAPOL-Key的四次握手, (TKIP|CCMP) Temporal Key 参与报文加密解密 TKIP MIC Key(for Authenticator Tx)、TKIP MIC Key(for Supplicant Tx)用于TKIP协议。 看到题目给的信息、我估计就是要算那个(TKIP|CCMP) Temporal Key
了。 首先是通过SSID与PSK计算PMK,这里可以用WPA key calculation: From passphrase to hex 也可以自己写个脚本具体的算法可以看 rfc2898 的PBKDF2那一节… 然后我写了一半发现python3有自带的。。。。
1 PMK = hashlib.pbkdf2_hmac("sha1" , PSK.encode(), SSID.encode(), 4096 , 256 )
PTK的算法见IEEE 802.11-04/0123r1 46页
1 2 802.11i-PRF(K, A, B, Len) R ← “” for i ← 0 to ((Len+159)/160) – 1) do R ← R || HMAC-SHA1(K, A || B || i) return Truncate-to-len(R, Len) PTK ← 802.11i-PRF(PMK, “Pairwise key expansion”, min(AP-Addr, STA-Addr) || max(AP-Addr, STA-Addr) || min(ANonce, SNonce) || max( ANonce, SNonce), 384)
写了脚本计算出了Temporal Key然后还没完的呢。 根据RFC 3610 的说法,要解密CCM加密的密文,要提供三个东西, 密钥,随机数,附加认证数据,密钥我们已经有了。然后随机数和附加认证数据去哪搞是个问题emmmm。根据IEEE 802.11-04/0123r1 33页说的
Needs one fresh 128-bit key – Same 128-bit
Temporal key used by both AP and STA
CBC-MAC IV, CTR constructions make this valid
Nonce (A0, B0) construction in CCMP’s use of CCM:
A0 = Tag0 || 0x00 || Transmit-Address || Frame-Sequence-Number
B0 = Tag1 || 0x00 || Transmit-Address || Frame-Sequence-Number
Transmit-address is 6 octets
Frame-Sequence-Number is 8 octets and includes the QoS Priority
Sequence-Number must be sequential within a single MSDU emmmmmmmmm
未完待续…