C#逆向常见题型

做题

[强网杯 2022]GameMaster

DIE查壳为.NET,用dnSpy-x86打开,发现gamemessage被传入memory中。Ctrl+Shift+R查引用,在goldFunc中发现可疑函数。genCode()中为AES-PKCS7加密,发现没什么实质作用。

捋清思路:把gamemessage文件先$\oplus34$再AES-ECB

exp:

1
2
3
4
5
6
7
8
9
10
from Crypto.Cipher import AES
key=b'Brainstorming!!!'
block_size=16
cipher=AES.new(key,AES.MODE_ECB)
with open('D://CTF-Workbench//gamemessage','rb') as f:
ciphertext=f.read()
ciphertext=bytes([byte^34 for byte in ciphertext])
plaintext=cipher.decrypt(ciphertext)
with open('D://CTF-Workbench//data','wb') as f:
f.write(plaintext)

得解密后gamemessage,010Editor打开,找MZ文件头,前面全删掉,DIE查壳为.NET,改名.dll,丢dnSpy-x86,发现他很复杂…

第一步尝试z3爆破:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from z3 import *
x,y,z=BitVecs('x y z',64)
s=Solver()
KeyStream=[0]*40
key1=[101,5,80,213,163,26,59,38,19,6,173,189,198,166,140,183,42,247,223,24,106,20,145,37,24,7,22,191,110,179,227,5,62,9,13,17,65,22,37,5]
num=-1
for i in range(320):
x=(((x>>29^x>>28^x>>25^x>>23)&1)|x<<1)
y=(((y>>30^y>>27)&1)|y<<1)
z=(((z>>31^z>>30^z>>29^z>>28^z>>26^z>>24)&1)|z<<1)
if i%8==0:
if i!=0:
s.add(KeyStream[num]==key1[num])
num+=1
KeyStream[num]=(KeyStream[num]<<1)|(((z>>32&1&(x>>30&1))^(((z>>32&1)^1)&(y>>31&1))))
print(s.check())
print(s.model())

第二部照猫画虎:

1
2
3
4
5
6
7
8
l=[156324965,868387187,3131229747]
arr=[0]*12
for i in range(3):
for j in range(4):
arr[i*4+j]=(l[i]>>j*8)&0xff
enc=[60,100,36,86,51,251,167,108,116,245,207,223,40,103,34,62,22,251,227]
for i in range(len(enc)):
print(chr(enc[i]^arr[i%len(arr)]),end='')

[BJDCTF 2020]BJD hamburger competition

Unity做的汉堡制作游戏,主程序在DLL里。给出了SHA1值,查一下原文,再MD5加密。发现MD5被自定义类拦截,算法为第20位截断,即得flag。

[SWPUCTF 2023 秋季新生赛]Funny CSharp

学到个冷门知识点:

1
byte[] array3 = array;

这语句竟然是array3与array共用同一个地址,没想到C#没有指针还这么变态。

1
2
3
4
5
6
7
enc=[116,94,80,127,49,71,101,106,115,97,57,83,94,109,58,98,75,86,40,100,61,123,110,57,123,89,86,121,123,104,97,60,86,74,86,112,103,103,124,111,86,99,107,56,93,71,96,106,69,49,112,59,103,124,90,65,71,114,79,93,74,90,90,71]
s=[]
for i in range(len(enc)):
s.append(chr(enc[i]^9))
s=s[::-1]
flag="".join(s)
print(flag)

[HGAME 2023 week3]kunmusic

找资源节“data”,发现异或后解析:

1
2
3
4
Activator.CreateInstance(Assembly.Load(data).GetType("WinFormsLibrary1.Class1"), new object[]{
Program.form1
});
Application.Run(Program.form1);

直接dump出来:

1
2
3
4
5
6
7
f1=open("data","rb")
arr1=f1.read()
arr2=[0]*len(arr1)
for i in range(len(arr1)):
arr2[i]=arr1[i]^104
f2=open("output","wb")
f2.write(bytes(arr2))

output是个I386的.NET,再分析为z3:

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
from z3 import *
key=[132,47,180,7,216,45,68,6,39,246,124,2,243,137,58,172,53,200,99,91,83,13,171,80,108,235,179,58,176,28,216,36,11,80,39,162,97,58,236,130,123,176,24,212,56,89,72]
s=Solver()
num=[BitVec('num%d'%i,9)for i in range(13)]
s.add(num[0]+52296+num[1]-26211+num[2]-11754+(num[3]^41236)+num[4]*63747+num[5]-52714+num[6]-10512+num[7]*12972+num[8]+45505+num[9]-21713+num[10]-59122+num[11]-12840+(num[12]^21087)==12702282)
s.add(num[0]-25228+(num[1]^20699)+(num[2]^8158)+num[3]-65307+num[4]*30701+num[5]*47555+num[6]-2557+(num[7]^49055)+num[8]-7992+(num[9]^57465)+(num[10]^57426)+num[11]+13299+num[12]-50966==9946829)
s.add(num[0]-64801+num[1]-60698+num[2]-40853+num[3]-54907+num[4]+29882+(num[5]^13574)+(num[6]^21310)+num[7]+47366+num[8]+41784+(num[9]^53690)+num[10]*58436+num[11]*15590+num[12]+58225==2372055)
s.add(num[0]+61538+num[1]-17121+num[2]-58124+num[3]+8186+num[4]+21253+num[5]-38524+num[6]-48323+num[7]-20556+num[8]*56056+num[9]+18568+num[10]+12995+(num[11]^39260)+num[12]+25329==6732474)
s.add(num[0]-42567+num[1]-17743+num[2]*47827+num[3]-10246+(num[4]^16284)+num[5]+39390+num[6]*11803+num[7]*60332+(num[8]^18491)+(num[9]^4795)+num[10]-25636+num[11]-16780+num[12]-62345==14020739)
s.add(num[0]-10968+num[1]-31780+(num[2]^31857)+num[3]-61983+num[4]*31048+num[5]*20189+num[6]+12337+num[7]*25945+(num[8]^7064)+num[9]-25369+num[10]-54893+num[11]*59949+(num[12]^12441)==14434062)
s.add(num[0]+16689+num[1]-10279+num[2]-32918+num[3]-57155+num[4]*26571+num[5]*15086+(num[6]^22986)+(num[7]^23349)+(num[8]^16381)+(num[9]^23173)+num[10]-40224+num[11]+31751+num[12]*8421==7433598)
s.add(num[0]+28740+num[1]-64696+num[2]+60470+num[3]-14752+(num[4]^1287)+(num[5]^35272)+num[6]+49467+num[7]-33788+num[8]+20606+(num[9]^44874)+num[10]*19764+num[11]+48342+num[12]*56511==7989404)
s.add((num[0]^28978)+num[1]+23120+num[2]+22802+num[3]*31533+(num[4]^39287)+num[5]-48576+(num[6]^28542)+num[7]-43265+num[8]+22365+num[9]+61108+num[10]*2823+num[11]-30343+num[12]+14780==3504803)
s.add(num[0]*22466+(num[1]^55999)+num[2]-53658+(num[3]^47160)+(num[4]^12511)+num[5]*59807+num[6]+46242+num[7]+3052+(num[8]^25279)+num[9]+30202+num[10]*22698+num[11]+33480+(num[12]^16757)==11003580)
s.add(num[0]*57492+(num[1]^13421)+num[2]-13941+(num[3]^48092)+num[4]*38310+num[5]+9884+num[6]-45500+num[7]-19233+num[8]+58274+num[9]+36175+(num[10]^18568)+num[11]*49694+(num[12]^9473)==25546210)
s.add(num[0]-23355+num[1]*50164+(num[2]^34618)+num[3]+52703+num[4]+36245+num[5]*46648+(num[6]^4858)+(num[7]^41846)+num[8]*27122+(num[9]^42058)+num[10]*15676+num[11]-31863+num[12]+62510==11333836)
s.add(num[0]*30523+(num[1]^7990)+num[2]+39058+num[3]*57549+(num[4]^53440)+num[5]*4275+num[6]-48863+(num[7]^55436)+(num[8]^2624)+(num[9]^13652)+num[10]+62231+num[11]+19456+num[12]-13195==13863722)
assert s.check()==sat
res=s.model()
tmp=[0]*13
for i in range(0,13):
tmp[i]=res[num[i]].as_long()
print(tmp)
for i in range(len(key)):
print(chr((key[i]^tmp[i%len(tmp)])&0x7f),end='')

垃圾z3多解不能全报,而且每个版本的z3_solver报的都不一样…BitVec的位深改为9才报正确的…