[ACTF新生赛2020]SoulLike
64位elf
关键在这个函数,太长反编译器炸了,运行发现
会告诉那个位置错了,逐个爆破
from itertools import * import subprocess flag="" t="" for i in range(12): for j in range(32,126): flag ="actf{"+t+chr(j)+"}" p = subprocess.Popen(["./SoulLike"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) p.stdin.write(flag) p.stdin.close() out=p.stdout.read() #print(out) p.stdout.close() if "#"+str(i) not in out: t+=chr(j) print(t) break print(flag)
[NPUCTF2020]芜湖🛫
64elf,有点无聊的题
数组解密为base64密文,再解密为明文,base64密文放到堆上了,找的麻烦了点
眼前重复的风景, 程序中 55y85YmN6YeN5aSN55qE6aOO5pmvLG== 正常加密 55y85YmN6YeN5aSN55qE6aOO5pmvLA==
有一点不同,base64隐写,参考:ZJPCCTF:我未见过的base64隐写
#脚本来自上文 def get_base64_diff_value(s1, s2): base64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' res = 0
for i in xrange(len(s2)): if s1[i] != s2[i]: return abs(base64chars.index(s1[i]) - base64chars.index(s2[i])) return res def solve_stego(): with open('a.txt', 'rb') as f: file_lines = f.readlines() bin_str = ''
for line in file_lines: steg_line = line.replace('\n', '') norm_line = line.replace('\n', '').decode('base64').encode('base64').replace('\n', '') diff = get_base64_diff_value(steg_line, norm_line) print diff pads_num = steg_line.count('=') if diff: bin_str += bin(diff)[2:].zfill(pads_num * 2) else: bin_str += '0' * pads_num * 2 print goflag(bin_str) def goflag(bin_str): res_str = ''
for i in xrange(0, len(bin_str), 8): res_str += chr(int(bin_str[i:i + 8], 2)) return res_str if __name__ == '__main__': solve_stego()
[NPUCTF2020]BasicASM
简单的汇编阅读,没啥可说的
a="662e61257b26301d7972751d6b2c6f355f3a38742d74341d61776d7d7d" b=[] for i in range(0,len(a)-1,2): b.append(eval("0x"+a[i:i+2])) for i in range(len(b)): if(i%2!=0): b[i]=b[i]^0x42 print(chr(b[i]),end="")
[NPUCTF2020]你好sao啊
逻辑很简单,但我没想到怎么逆,直接爆破了
table="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234{}789+/=" c="9E9B9C B5FE70 D30FB2 D14F9C 027FAB DE5965 63E740 9DCDFA" c=c.split() for i in range(len(c)): c[i]=eval("0x"+c[i]) print(c) for x in c: t=0 for i in range(len(table)): for j in range(len(table)): for k in range(len(table)): for l in range(len(table)): t=(0<<6)|i t=(t<<6)|j t=(t<<6)|k t=(t<<6)|l if(t==x): print(table[i]+table[j]+table[k]+table[l])
跑出来有几位重复,手动去除
[SCTF2019]Who is he
unity,dnspy打开Assembly-CSharp.dll
private string Decrypt(string str) { string result; try { byte[] bytes = Encoding.Unicode.GetBytes(TestClick.encryptKey); byte[] array = Convert.FromBase64String(str); DESCryptoServiceProvider descryptoServiceProvider = new DESCryptoServiceProvider(); MemoryStream memoryStream = new MemoryStream(); CryptoStream cryptoStream = new CryptoStream(memoryStream, descryptoServiceProvider.CreateDecryptor(bytes, bytes), CryptoStreamMode.Write); cryptoStream.Write(array, 0, array.Length); cryptoStream.FlushFinalBlock(); byte[] bytes2 = memoryStream.ToArray(); cryptoStream.Close(); memoryStream.Close(); result = Encoding.Unicode.GetString(bytes2); } catch { result = str; } return result; } public void OnClick() { Debug.Log("Button Clicked. TestClick."); Debug.Log(this.Name.text); bool flag = this.Name.text.Equals(this.Decrypt(this.EncryptData)); if (flag) { Debug.Log("Right"); TestClick.Messagebox.MessageBox(IntPtr.Zero, "Haha, same as you!", "Info:", 0); } else { Debug.Log("Wrong"); TestClick.Messagebox.MessageBox(IntPtr.Zero, "Emmmmm,I don't think so.", "Info:", 0); } } private static string encryptKey = "1234"; // Token: 0x04000004 RID: 4 private string EncryptData = "1Tsy0ZGotyMinSpxqYzVBWnfMdUcqCMLu0MA+22Jnp+MNwLHvYuFToxRQr0c+ONZc6Q7L0EAmzbycqobZHh4H23U4WDTNmmXwusW4E+SZjygsntGkO2sGA==";
先解base64,再解des,但这里有坑,这个dll并不是程序真正用到的dll,真正的dll可能藏在某处(或者是在运行中被修改了,我没明白是怎么做到的,不过修改这个dll并不会产生什么影响,所以我猜是加密后藏在程序中的某处)
找这种内存ce最好用了,
找到两处,其中base64密文都不一样,des密钥也不一样,都试一试
from Crypto.Cipher import DES import base64 a="71 00 2B 00 77 00 38 00 39 00 59 00 32 00 32 00 72 00 4F 00 62 00 66 00 7A 00 78 00 67 00 73 00 71 00 75 00 63 00 35 00 51 00 78 00 62 00 62 00 68 00 39 00 5A 00 49 00 41 00 48 00 45 00 54 00 2F 00 4E 00 6E 00 63 00 6D 00 69 00 71 00 45 00 6F 00 36 00 37 00 52 00 72 00 44 00 76 00 7A 00 33 00 34 00 63 00 64 00 41 00 6B 00 30 00 42 00 61 00 6C 00 4B 00 57 00 68 00 4A 00 47 00 6C 00 32 00 43 00 42 00 59 00 4D 00 6C 00 72 00 38 00 70 00 50 00 41 00 3D" a=a.split(" 00 ") b="78 00 5A 00 57 00 44 00 5A 00 61 00 4B 00 45 00 68 00 57 00 4E 00 4D 00 43 00 62 00 69 00 47 00 59 00 50 00 42 00 49 00 6C 00 59 00 33 00 2B 00 61 00 72 00 6F 00 7A 00 4F 00 39 00 7A 00 6F 00 6E 00 77 00 72 00 59 00 4C 00 69 00 56 00 4C 00 34 00 6E 00 6A 00 53 00 65 00 7A 00 32 00 52 00 59 00 4D 00 32 00 57 00 77 00 73 00 47 00 6E 00 73 00 6E 00 6A 00 43 00 44 00 6E 00 48 00 73 00 37 00 4E 00 34 00 33 00 61 00 46 00 76 00 4E 00 45 00 35 00 34 00 6E 00 6F 00 53 00 61 00 64 00 50 00 39 00 46 00 38 00 65 00 45 00 70 00 76 00 54 00 73 00 35 00 51 00 50 00 47 00 2B 00 4B 00 4C 00 30 00 54 00 44 00 45 00 2F 00 34 00 30 00 6E 00 62 00 55 00 3D" b=b.split(" 00 ") str_a="" str_b="" key1=b"1\x002\x003\x004\x00" key2=b"t\x00e\x00s\x00t\x00"
for i in a: str_a+=chr(eval("0x"+i)) for i in b: str_b+=chr(eval("0x"+i)) key = key1 mode = DES.MODE_CBC text=base64.b64decode(str_a) cryptor = DES.new(key, mode,key) plain_text = cryptor.decrypt(text) print(plain_text.decode()) key = key2 mode = DES.MODE_CBC text=base64.b64decode(str_b) cryptor = DES.new(key, mode,key) plain_text = cryptor.decrypt(text) print(plain_text.decode()) #Oh no!This is a trick!!! #She_P1ay_Black_Hole_Very_Wel1!LOL!XD!
[NPUCTF2020]Baby Obfuscation
64exe,拖进ida
真正加密只用到这三条
AOX=[780,780,850,590,800,640,1150,460,980,960,1170,530,970,1080,1250] a=[i+1 for i in range(65)] v=[2,3,4,5] def gcd(a,b): if b!=0: result=gcd(b,a%b) else: result=a return a for i in range(len(AOX)): v24=gcd(a[i], a[i]) AOX[i]//= 8+pow(2,v24//a[i])
AOX[i]^= v[i%4] AOX[i]+= v[i%4] for i in range(len(AOX)): print(chr(AOX[i]),end="")
[ACTF新生赛2020]Splendid_MineCraft
32exe,主要考点是smc
长度26,三个strtok,可以猜到格式ACTF{??????_??????_??????}
之后有两部分smc,第一个对前六位判断,在前六位正确后解密第二部分,第一部分直接明文判断,第二部分是表的置换,第三部分明文
b=[0x30,0x4,0x4,0x3,0x30,0x63] a="F6 A3 5B 9D E0 95 98 68 8C 65 BB 76 89 D4 09 FD F3 5C 3C 4C 36 8E 4D C4 80 44 D6 A9 01 32 77 29 90 BC C0 A8 D8 F9 E1 1D E4 67 7D 2A 2C 59 9E 3D 7A 34 11 43 74 D1 62 60 02 4B AE 99 57 C6 73 B0 33 18 2B FE B9 85 B6 D9 DE 7B CF 4F B3 D5 08 7C 0A 71 12 06 37 FF 7F B7 46 42 25 C9 D0 50 52 CE BD 6C E5 6F A5 15 ED 64 F0 23 35 E7 0C 61 A4 D7 51 75 9A F2 1E EB 58 F1 94 C3 2F 56 F7 E6 86 47 FB 83 5E CC 21 4A 24 07 1C 8A 5A 17 1B DA EC 38 0E 7E B4 48 88 F4 B8 27 91 00 13 97 BE 53 C2 E8 EA 1A E9 2D 14 0B BF B5 40 79 D2 3E 19 5D F8 69 39 5F DB FA B2 8B 6E A2 DF 16 E2 63 B1 20 CB BA EE 8D AA C8 C7 C5 05 66 6D 3A 45 72 0D CA 84 4E F5 31 6B 92 DC DD 9C 3F 55 96 A1 9F CD 9B E3 A0 A7 FC C1 78 10 2E 82 8F 30 54 04 AC 41 93 D3 3B EF 03 81 70 A6 1F 22 26 28 6A AB 87 AD 49 0F AF" a=a.split() for i in range(len(a)): a[i]=eval("0x"+a[i]) for i in range(6): print(chr((0x83+i)^a.index(b[i])),end="")
[GWCTF 2019]babyvm
这题有坑,就给了vm的实现,opcode和flag以及check函数都是假的
真正的opcode在
flag在
函数在
直接用angr会跑出假flag:This_is_not_flag_233
直接分析vm也可以,但是我懒。。。
patch一下程序
import angr
def main():
p=angr.Project("attachment",auto_load_libs=False)
sm=p.factory.simulation_manager(p.factory.entry_state())
sm.explore(find=0x401081)
return sm.found[0].posix.dumps(0)
if __name__=='__main__':
print(main())
[WUSTCTF2020]level4
二叉树,给了中序和后序结果,由此得到前序结果即为flag
[NPUCTF2020]EzObfus-Chapter2
a=[0x21,0x3f,0xa3,0xe9,0x8f,0x0] c="6E 10 EC 13 C1 CB F0 2D C6 32 FD 86 EE CB 89 92 3C 46 49 71 62 57" c=c.split() for i in range(len(c)): c[i]=eval("0x"+c[i]) ''' for j in range(1,22): for i in range(256): f=i f+=(a[j%6]>>6)^(a[(j-1)%6]<<4) f=((f&0xff)>>3)|((f&0xff)<<5) if((f&0xff)==c[j]): print(chr(i),end="") break
''' flag="npue|nYD^]DwNZaOBJ{!" #npuctf{WDNMDoEZ_OBFU!} print("n",end="") for i in range(1,22): print(chr((ord(flag[i])^i)-i),end="")
跑出来oEZ处是不对的,这几位加密不太一样,爆破一下
from itertools import * import subprocess for i in range(1): for j in range(32,127): for k in range(32,127): flag ="npuctf{WDNMD_"+chr(j)+chr(k)+"_OBFU!}" p = subprocess.Popen([r"attachment.exe"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) p.stdin.write(flag) p.stdin.close() out=p.stdout.read() p.stdout.close() if "E" not in out: print(flag) exit()