BUUCTF Re部分wp(六)
[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()