XNUCA2020-re

unravelmfc

(主要是學(xué)弟出的,我就打個(gè)下手
flag長(zhǎng)度66(輸入66長(zhǎng)度字符才能點(diǎn)擊確定)點(diǎn)確定沒(méi)反應(yīng),只有flag正確才會(huì)彈框
首先使用下面的mfc的sig文件:
http://s.wjk.moe/bt/tmp/unravelmfc/afx140d.sig
在CCmdTarget::OnCmdMsg函數(shù)內(nèi)部, 調(diào)用_AfxDispatchCmdMsg的call指令下斷點(diǎn),再點(diǎn)確定,即可在棧參數(shù)中找到對(duì)應(yīng)的處理函數(shù)指針
MFC逆向
0x00CB1080 點(diǎn)確定后的處理函數(shù) (程序基址我rebase到了0x00b10000)
00CB127C 是flag正確

直接看最下面的if,里面調(diào)用的兩個(gè)函數(shù)。前33字符和后33字符分開(kāi)判斷檢測(cè)。

if ( (unsigned __int8)j_check1((int)v14, v13) && (unsigned __int8)j_check2((int)v14 + v13, v13) )

前33字節(jié)首先RC4,再base64

flag{dsdafasdfasdsddddddddddddddddddddddddddddddddddddddddddddddd}
異或后:
00ACE9F4  26 44 D7 3B A8 E0 2F 7E 81 7E 9C 4C 39 A8 97 C8  &D×;¨à/~.~.L9¨.è  
00ACEA04  59 35 27 E6 1E CD 38 87 80 2C 99 C1 DD 5D 1F B0  Y5'?.í8..,.áY].°  
00ACEA14  9A 00 

base64是改了字符表的,在一個(gè)rc4加密的代碼段里,x64dbg里將內(nèi)存dump出來(lái)放到ida里用f5還勉強(qiáng)能看吧

enc_real = "B=.NI;&3JBZ;$;?(I72'0&4GLZDS2V6&%AF.!5#+J[F^"
import base64
def decoder(local_base64):
    import string
    real_base64_charset = string.ascii_uppercase + string.ascii_lowercase + string.digits + '+/'
    tmp_charset = "#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ab"
    b64_str = ''
    for i in local_base64:
        t = real_base64_charset[tmp_charset.find(i)]
        b64_str += t
    return (base64.decodebytes(b64_str.encode()))

def test1():
    orig = b"&D\xd7;\xa8\xe0/~\x81~\x9cL9\xa8\x97\xc8Y5'\xe6\x1e\xcd8\x87\x80,\x99\xc1\xdd]\x1f\xb0\x9a"
    encoded = ",G6:1]FC.Z]$BLT/1=E:U(GX,a;AV6E*C%U<S@X@*^%="
    assert decoder(encoded) == orig

test1()

def derc4(inp):
    moder_b =b'@(\xb6\\\xd3\x84\\\x1a\xe0\x18\xfd?]\xce\xf6\xbb=FC\x82z\xa9\\\xe3\xe4H\xfd\xa5\xb99{\xd4\xfe'
    res = []
    for i,j in zip(inp, moder_b):
        res.append(i^j)
    return bytes(res)

def test2():
    orig = b'flag{dsdafasdfasdsddddddddddddddd'

    out = b"\x26\x44\xD7\x3B\xA8\xE0\x2F\x7E\x81\x7E\x9C\x4C\x39\xA8\x97\xC8\x59\x35\x27\xE6\x1E\xCD\x38\x87\x80\x2C\x99\xC1\xDD\x5D\x1F\xB0\x9A"

    assert derc4(out) == orig

test2()

前半部分flag就出來(lái)了。。。

后33字符:第一個(gè)字符是f,后面三十二個(gè)字符單獨(dú)加密
是tea算法,只改了delta。
需要解一個(gè)方程解出來(lái)是[0x2d46347f5e79f6f4, 0xDF3634AE2F9970FF, 0x6cacebd512c2fc6d, 0xe8e95dc6c558d3ec]

import ctypes
def encipher(v, k):
    y, z = [ctypes.c_uint32(x)
            for x in v]
    sum = ctypes.c_uint32(0)
    # delta = 0x9E3779B9
    delta = 0x2433b95a

    for n in range(32, 0, -1):
        sum.value += delta
        # z -- v8
        # y -- v6
        # y.value += ((z.value << 4) + k[0]) ^ (z.value + sum.value) ^ ((z.value >> 5) + k[1])
        # z.value += ((y.value << 4)) + k[2] ^ y.value + sum.value ^ (y.value >> 5) + k[3]
        y.value += (z.value << 4) + k[0] ^ z.value + sum.value ^ (z.value >> 5) + k[1]
        z.value += (y.value << 4) + k[2] ^ y.value + sum.value ^ (y.value >> 5) + k[3]
    # print(hex(sum.value))
    return [y.value, z.value]


def decipher(v, k):
    y, z = [ctypes.c_uint32(x)
            for x in v]
    # sum = ctypes.c_uint32(0xC6EF3720)
    sum = ctypes.c_uint32(0x86772b40)
    # delta = 0x9E3779B9
    delta = 0x2433b95a

    for n in range(32, 0, -1):
        z.value -= (y.value << 4) + k[2] ^ y.value + sum.value ^ (y.value >> 5) + k[3]
        y.value -= (z.value << 4) + k[0] ^ z.value + sum.value ^ (z.value >> 5) + k[1]
        sum.value -= delta

    return [y.value, z.value]

keys = [3647016194, 716023165, 2742368241, 3265149203, 3583257832, 1619840614, 1834562594, 568710898, 3980038709, 2645385924, 945185819, 1912036253, 3705592552, 3939684768, 3133470052, 3662115500]

vv = [0x5e79f6f4, 0x2d46347f, 0x2F9970FF, 0xDF3634AE , 0x12c2fc6d, 0x6cacebd5, 0xc558d3ec, 0xe8e95dc6]

data = []
for i in range(4):
    v = vv[2*i: 2*(i+1)]
    v = v[::-1]
    k = keys[4*i:4*(i+1)]
    enc = decipher(v, k)
    data.append(enc[0])
    data.append(enc[1])

flag = ""
for d in data:
    flag = flag + (hex(d).replace("0x", "")[:-1]).decode('hex')[::-1]
print('f'+flag)

hellowasm

需要用node起一下直接點(diǎn)開(kāi)不行

npm install http-server -g
http-server -p 8080

長(zhǎng)度是42
這里可以直接用瀏覽器調(diào)試,還比較方便。
然后做了個(gè)base64, 每四個(gè)字符一組,異或[0xa, 0xb, 0xc, 0xd]
最后check的部分是個(gè)vm,算法是簡(jiǎn)單異或。
一點(diǎn)點(diǎn)分析的過(guò)程,分析了一點(diǎn)以后直接在異或和比較的函數(shù)下了斷點(diǎn)發(fā)現(xiàn)算法其實(shí)比較簡(jiǎn)單。

+4; -> IP
+32 -> source
+16 -> str_index
+8 -> source[str_index]
+24 -> 

初始IP: 2128
202 -> IP + 5
203 -> IP + 5
204 -> IP + 1, load source
207 -> ^ +12  save in 12, IP + 1
201 -> next IP, save in 8, IP + 5

opcode
2128: 202
2129: 0
2130: 0
2131: 0
2132: 0
2133: 203
2134: 0
2135: 0
2136: 0
2137: 0
2138: 204
2139: 207
2140: 201
2141: 238
2142: 0
2143: 0
2144: 0
2145: 207 -> // source[0] ^ 238
2146: 209 -> 2160[index] == source[0] ^ 238
import base64
result = {2160: 190, 2161: 54, 2162: 172, 2163: 39, 2164: 153, 2165: 79, 2166: 222, 2167: 68, 2168: 238, 2169: 95, 2170: 218, 2171: 11, 2172: 181, 2173: 23, 2174: 184, 2175: 104, 2176: 194, 2177: 78, 2178: 156, 2179: 74, 2180: 225, 2181: 67, 2182: 240, 2183: 34, 2184: 138, 2185: 59, 2186: 136, 2187: 91, 2188: 229, 2189: 84, 2190: 255, 2191: 104, 2192: 213, 2193: 103, 2194: 212, 2195: 6, 2196: 173, 2197: 11, 2198: 216, 2199: 80, 2200: 249, 2201: 88, 2202: 224, 2203: 111, 2204: 197, 2205: 74, 2206: 253, 2207: 47, 2208: 132, 2209: 54, 2210: 133, 2211: 82, 2212: 251, 2213: 115, 2214: 215, 2215: 13, 2216: 227}

flag = []
li = [0]
for k in result.keys():
    li.append(result[k])

for i in range(1, len(li)):
    flag.append(li[i-1] ^ li[i] ^ 238)
ti = [0xa, 0xb, 0xc, 0xd]
tar = ""
for i in range(0, len(flag)-4, 4):
    for j in range(4):
        tar = tar + chr(ti[j] ^ flag[i+j])
print(base64.decodestring(tar))

babyarm

主要驗(yàn)證部分在sub_114D8, xxtea稍微改了一點(diǎn),一次加密了16輪...長(zhǎng)度也是16

#include <stdio.h>  
#include <stdint.h>  
#define DELTA 0x9e3779b9  
#define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[(p&3)^e] ^ z)))  
  
void btea(uint32_t *v, int n, uint32_t const key[4])  
{  
    uint32_t y, z, sum;  
    unsigned p, rounds, e;  
    if (n > 1)            /* Coding Part */  
    {  
        rounds = 6 + 52/n;  
        sum = 0;  
        z = v[n-1];  
        do  
        {  
            sum += DELTA;  
            e = (sum >> 2) & 3;  
            for (p=0; p<n-1; p++)  
            {  
                y = v[p+1];  
                z = v[p] += MX;  
            }  
            y = v[0];  
            z = v[n-1] += MX;  
        }  
        while (--rounds);  
    }  
    else if (n < -1)      /* Decoding Part */  
    {  
        for(int i = 0; i < 16; i++)
        {
            n = 16;  
            rounds = 6 + 52/n;  
            sum = rounds*DELTA;  
            y = v[0];
            do  
            {  
                e = (sum >> 2) & 3;  
                for (p=n-1; p>0; p--)  
                {  
                    z = v[p-1];  
                    y = v[p] -= MX;  
                }  
                z = v[n-1];  
                y = v[0] -= MX;  
                sum -= DELTA;  
            }  
            while (--rounds);  
        }
    }  
}  
  
  
int main()  
{  
    uint32_t v[16]= {0xB061F013, 0xB3C8567E, 0x9952A3C7, 0x451C2D3F, 0x3EE32267, 0xE3E22B3E, 0x43E5A250, 0x59B28ED0, 0x0F8649DC, 0x9BF4D083, 0x8A578110, 0x8604EC4F, 0x2EB5A27F, 0x1217DDF3, 0x93C9B253, 0xDC7F8E43};  
    uint32_t const k[4]= {2,2,3,4};  
    int n= 16;
    // for(int i = 0; i < 16; i++)
    btea(v, -n, k);
    for(int i = 0; i < 16; i++)
        printf("\"%x\", ", v[i]);
    return 0;  
}

>>> s = ["67616c66", "6330447b", "37306261", "35346146", "36623241", "62376646", "41364541", "41624261", "64354635", "43336263", "43446639", "66613545", "34354665", "38434144", "30354138", "7d413339"]
>>> flag = ""
>>> for i in s:
...     flag = flag + i.decode('hex')[::-1]
...
>>> flag
'flag{D0cab07Fa45A2b6Ff7bAE6AaBbA5F5dcb3C9fDCE5afeF54DAC88A5093A}'
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,702評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,143評(píng)論 3 415
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 175,553評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 62,620評(píng)論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,416評(píng)論 6 405
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 54,940評(píng)論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,024評(píng)論 3 440
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,170評(píng)論 0 287
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,709評(píng)論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,597評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,784評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,291評(píng)論 5 357
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,029評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,407評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 35,663評(píng)論 1 280
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,403評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,746評(píng)論 2 370