日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

REVERSE-COMPETITION-0xGame2021

發(fā)布時間:2023/12/10 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 REVERSE-COMPETITION-0xGame2021 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

REVERSE-COMPETITION-0xGame2021

    • Signin: User Friendly
    • Installer
    • Our Compilation Story
    • Packet
    • Random Chaos
    • Neverland
    • Roundabout
    • Despacito
    • Secret Base
    • Maze
    • Zero Three
    • Mirror
    • Thread_TLS
    • 茶談室
    • Junkertown

Signin: User Friendly

64位exe,ida打開,在main函數(shù)中直接看到flag

Installer

.pyc文件,用uncompyle6反編譯一下

from flag import * length = len(flag) arr = [] enc = [238, 257, 150, 137, 167, 169, 184, 193, 210, 147, 219, 128, 140, 135, 185, 242, 204, 128, 132, 159, 222, 173, 226, 159, 207, 169, 154, 156, 216, 139, 168, 187, 220, 237, 207, 187, 218, 138, 218, 178, 246, 239, 246, 241] for i in range(length):arr.append(ord(flag[i]))for i in range(0, 16):for j in range(0, length):arr[j] += enc[j]enc[j] += enc[j]enc = enc[::-1]print(arr)

直接寫逆腳本即可得到flag

res=[15728448, 16362025, 13718731, 13740602, 11425044, 13216326, 10048823, 13740603, 12757531, 12255100, 15138636, 12408061, 11228430, 10289095, 10114289, 14723575, 11272070, 9524519, 10267251, 12517282, 11796345, 13653174, 12495389, 13172636, 11468724, 9458930, 8956506, 12320680, 15291551, 11119205, 9568155, 10201663, 10398270, 14745427, 10944395, 13260012, 13194479, 11053619, 12145871, 11184688, 11359448, 11774503, 16602251, 15662990] enc=[238, 257, 150, 137, 167, 169, 184, 193, 210, 147, 219, 128, 140, 135, 185, 242, 204, 128, 132, 159, 222, 173, 226, 159, 207, 169, 154, 156, 216, 139, 168, 187, 220, 237, 207, 187, 218, 138, 218, 178, 246, 239, 246, 241] for i in range(0,16):for j in range(0,len(res)):res[j]-=enc[j]enc[j]+=enc[j]enc=enc[::-1] print("".join(chr(i) for i in res)) # 0xGame{b373edd6-2cea-11ec-8d3d-0242ac130003}

Our Compilation Story

py文件,主要邏輯相當于,res=“qwq”,res+=chr(ord(res[0])^ord(flag[0])),寫逆腳本即可得到flag

res=[21,44,45,104,31,30,26,121,65,125,23,112,77,46,47,126,89,112,7,109,7,88,10,105,104,59,54,91,83,98,32,54,15,65,113,119,113] res=res[::-1] flag=[] for i in range(0,len(res)-3):flag.append(res[i]^res[i+3]) print("".join(chr(i) for i in flag)) # 0xGame{Th3_10ng_w4y_w3_901ng_fr33}

Packet

32位exe,upx脫殼,ida打開
main函數(shù)中,驗證輸入長度是否為40,對輸入進行變換,最后與enc數(shù)據(jù)比較

寫爆破腳本可得到flag

enc=[0x91,0x77,0xfb,0xe,0xb7,0xcc,0xe4,0x38,0x11,0x94,0xfd,0x85,0x5c,0x91,0x84,0x5c,0x7d,0x67,0x27,0x134,0x135,0xa,0xd8,0x23,0xd,0x30,0x65,0x3e,0x13,0x45,0x54,0x52,0x51,0x3e,0xb0,0xd9,0x13,0x33,0xc3,0xff] check=[0xa1,0xf,0xbc,0x6f,0xda,0xa9,0x9f,0x5e,0x29,0xf6,0xc5,0xe4,0x6e,0xf2,0xb1,0x38,0x1b,0x1,0x11,0x100,0x100,0x32,0xe9,0x41,0x68,0x2,0x4,0x6,0x2a,0x70,0x37,0x6b,0x30,0x5d,0x82,0xe8,0x25,0x57,0xf2,0x82] flag=[0]*len(enc) for i in range(len(flag)):for j in range(48,128):if check[i] & ~j | j & ~check[i]==enc[i]:flag[i]=jbreak print("".join(chr(i) for i in flag)) # 0xGame{f8b8a2c5dff64581be2a895c9ac216d1}

Random Chaos

64位exe,ida打開
main函數(shù)中,設(shè)置隨機數(shù)種子為固定的8225,驗證輸入長度是否為40,輸入與隨機數(shù)異或后與enc數(shù)據(jù)比較

寫c代碼得到固定隨機數(shù)種子生成的隨機數(shù)

#include<stdio.h> #include<stdlib.h> int main() {srand(8225);unsigned __int8 rand_num;for (int i = 0; i < 40; i++){rand_num = rand();printf("%d,", rand_num);}return 0; } //18,178,64,120,149,158,83,249,40,227,205,240,83,117,33,22,186,246,183,68,161,45,143,136,175,180,40,120,242,240,160,198,36,70,28,21,45,140,106,11

寫enc數(shù)據(jù)與隨機數(shù)異或腳本即可得到flag

arr=[0x22, 0xCA, 0x07, 0x19, 0xF8, 0xFB, 0x28, 0x9D, 0x1E, 0x80,0xAC, 0xC9, 0x60, 0x46, 0x18, 0x21, 0xDF, 0x95, 0xD5, 0x70,0xC5, 0x19, 0xEA, 0xB0, 0x9C, 0x83, 0x11, 0x4A, 0x93, 0xC7,0x91, 0xF6, 0x14, 0x71, 0x2F, 0x22, 0x14, 0xBF, 0x58, 0x76] rand_num=[18,178,64,120,149,158,83,249,40,227,205,240,83,117,33,22,186,246,183,68,161,45,143,136,175,180,40,120,242,240,160,198,36,70,28,21,45,140,106,11] for i in range(len(arr)):arr[i]^=rand_num[i] print("".join(chr(i) for i in arr)) # 0xGame{d6ca93397ecb4d4e83792a7100737932}

Neverland

64位exe,運行后會自動打印部分flag,ida打開
main函數(shù),for循環(huán)中,i為下標,idx[i]作為參數(shù)傳入func函數(shù),返回值存入v3,然后v3與enc數(shù)據(jù)的最低字節(jié)異或,異或的結(jié)果即為打印出的flag

主要是得到每次循環(huán)中v3的值,進入func函數(shù),發(fā)現(xiàn)是遞歸調(diào)用
idx中的前10個數(shù)傳入func,都能很快返回到v3,打印出"0xGame{1e6"
后面的數(shù)傳入func,需要一段時間才能返回

動態(tài)調(diào)試一下,觀察每次循環(huán)中v3的值,是否存在某種規(guī)律
斷點下在xor運算前,此時eax為enc中的數(shù)據(jù),為0xBFFCC,只看最低字節(jié),為0xCC
ecx為func返回的值,即v3,v3是個char類型的變量,所以我們只看ecx最低字節(jié)即可,此時為0xFC

多進行幾次循環(huán),依次記錄下前10組eax和ecx的最低字節(jié),可找到某種規(guī)律
比如,v3的值大多是0xFC,0x04等
enc中以0xC,0x8,0x9開頭的數(shù)都對應(yīng)v3為0xFC
enc中以0x4,0x6,0x3開頭的數(shù)都對應(yīng)v3為0x04
enc中其他沒有規(guī)律的數(shù)找對應(yīng)的特定v3即可

于是可以按上述規(guī)律手動填充完整v3,與enc異或即可得到flag

enc=[0xcc,0x84,0x43,0xdd,0x59,0x61,0x87,0x35,0x99,0x32,0x36,0xc9,0x98,0x30,0x9f,0xcc,0xc8,0x62,0x99,0x30,0xc8,0x9a,0xc5,0x9e,0x32,0xc4,0xc8,0x60,0x3d,0x35,0x3d,0xcb,0x34,0x3c,0x9f,0x65,0x65,0x33,0x66,0x79] v3_=[0xfc,0xfc,0x04,0xbc,0x34,0x04,0xfc,0x04,0xfc,0x04,0x04,0xfc,0xfc,0x04,0xfc,0xfc,0xfc,0x04,0xfc,0x04,0xfc,0xfc,0xfc,0xfc,0x04,0xfc,0xfc,0x04,0x04,0x04,0x04,0xfc,0x04,0x04,0xfc,0x04,0x04,0x04,0x04,0x04] #idx=[0x9,0xf,0xc,0x3,0x2,0x10,0xb,0xe,0x7,0xa,0x2e,0x2d,0x2b,0x2e,0x2f,0x2d,0x2f,0x28,0x31,0x3a,0x31,0x33,0x33,0x2b,0x32,0x37,0x37,0x38,0x3c,0x30,0xffffffce,0xffffff93,0xffffffd8,0xfffffff2,0xffffffdf,0xffffff70,0xffffff72,0xffffffd0,0xffffffa6,0xffffff9a] flag=[] for i in range(len(v3_)):flag.append(enc[i]^v3_[i]) print("".join(chr(i) for i in flag)) # 0xGame{1e625d4c04fe44f9b684d919708caa7b}

Roundabout

32位exe,upx脫殼,ida打開
main函數(shù)中,驗證輸入的長度是否為42,然后是簡單的異或運算

取出str和res,寫逆運算腳本即可得到flag

s="this_is_not_flag" res=[0x44,0x10,0x2e,0x12,0x32,0xc,0x8,0x3d,0x56,0xa,0x10,0x67,0x0,0x41,0x0,0x1,0x46,0x5a,0x44,0x42,0x6e,0xc,0x44,0x72,0xc,0xd,0x40,0x3e,0x4b,0x5f,0x2,0x1,0x4c,0x5e,0x5b,0x17,0x6e,0xc,0x16,0x68,0x5b,0x12] flag="" for i in range(len(res)):flag+=chr(ord(s[i%16])^res[i]) print(flag) # 0xGame{b8ed8f-af22-11e7-bb4a-3cf862d1ee75}

Despacito

64位exe,ida打開
從main函數(shù)中得知,主要邏輯為,將cipher.txt的數(shù)據(jù)作為密文,"0xgame21"作為密鑰,解密DES,得到明文plain,對明文進行md5散列即為flag

寫DES解密腳本并對明文進行md5散列即可得到flag

from Crypto.Cipher import DES from Crypto.Util.number import long_to_bytes import hashlib cipher_hex=0x16806B89C3CEF86C4F62207B9B20D95820769C2A978A15D7EEEDE0B15E3318595E11BC840D5DA7971CB27C7EBA0BE155D1F0FB878227E959B5CD740DB9E56BE69F88B0B2BF27F83DE8B3C46EAD999A5B76E37D98418DEFE5D1A416DF4BB88D92 cipher_str=long_to_bytes(cipher_hex) key_str="0xgame21" des=DES.new(key_str,DES.MODE_ECB) m=des.decrypt(cipher_str) print(m) # m==wLpGWGNJYVvBwLBCVzgatsuGZaAzbBUHPXjoUqdahnPzeLdZrKntUcYwPHFHxtrVgzyWwdUtYvgiQuLyqwQPFVaWQLaGuupA h=hashlib.md5() h.update(m.encode(encoding='utf-8')) print("0xGame{"+h.hexdigest()+"}") # 0xGame{83b9879f334340ef42dbb9f40468fc84}

Secret Base

32位exe,ida打開
main函數(shù),encrypt對輸入進行變表base64變換,結(jié)果放入res中,最后res和enc比較

直接解變表base64字符串即可得到flag

Maze

64位exe,ida打開
main函數(shù)中,先輸入兩個數(shù),確定起始點為"S",再輸入迷宮路線,終點為"E",只能沿著"."走,wsad分別為上下左右

maze為24*16大小的迷宮,起始點"S"下標為(2,4),按規(guī)則走完迷宮即可

# ************************ # **********..........**** # ****S......********.**** # *******************.**** # *******************.**** # ****E***********....**** # ****.****........******* # ****.****.************** # ****.****.************** # ****.****........******* # ****.***********.******* # ****.***********.******* # ****.***********...***** # ****.*************.***** # ****...............***** # ************************ # # route: # ddddddwdddddddddssssaaasaaaaaaasssdddddddsssddssaaaaaaaaaaaaaawwwwwwwww

再次運行exe,先輸入2和4,再輸入route,即可得到flag

Zero Three

64位exe,ida打開
main函數(shù)中,驗證輸入的長度是否為32,將輸入每四個字節(jié)為一組,組成一個32位的unsigned int數(shù)
例如,輸入為"abcdefgh",則得到的兩個32位數(shù)為0xdcba和0xhgfe

輸入的32字節(jié)分成8個unsigned int數(shù)存入num,然后用方程組來驗證輸入是否正確

利用python的z3庫解方程組,得到正確的8個unsigned int數(shù),再轉(zhuǎn)為字符串形式即為正確的輸入,包上"0xGame{}"即為flag
需要注意的是,方程組等式右邊的值需要在ida中按h化成有符號十進制數(shù)再用z3計算

from z3 import * num=[Int("num[%d]"%i) for i in range(8)] s=Solver() s.add(-22827 * num[4] + 21984 * num[1] + -38534 * num[5] - 32344 * num[0] == -98460819657603) s.add(-38215 * num[2] + -37324 * num[4] + -8436 * num[5] + 15405 * num[0] == -131665436206262) s.add(10926 * num[7] + -28942 * num[1] + -34572 * num[3] - 10538 * num[5] == -121891239772992) s.add(-30117 * num[6] + -22990 * num[2] + -20471 * num[5] + 34494 * num[7] == -57089882568260) s.add(-33112 * num[5] + -19335 * num[4] + 34348 * num[1] + 31445 * num[2] == 56335531538050) s.add(-13566 * num[5] + 14758 * num[0] + -19814 * num[2] - 26447 * num[4] == -81105980248303) s.add(25898 * num[5] + -15817 * num[1] + 20463 * num[7] - 33578 * num[0] == -28860618440412) s.add(-35429 * num[7] + 36594 * num[2] + -28801 * num[6] - 14952 * num[3] == -45384029412201) flag="" if s.check()==sat:m=s.model()for i in range(8):res=eval(str(m.eval(num[i])))res=hex(res)[2:]for j in range(len(res)-2,-2,-2):flag+=chr(int(res[j:j+2],16)) print("0xGame{"+flag+"}") # 0xGame{udydYCBxUB6vqsAt5VCs6LKDRqXLUhSW}

Mirror

64位exe,upx脫殼,ida打開
main函數(shù),signin和encrypt都須返回1才能調(diào)用checkflag驗證

跟進signin函數(shù),輸入兩個整型的數(shù)input_0和input_1,調(diào)用兩次calc,參數(shù)分別為0和1
一次calc相當于一個方程,兩次calc則為兩個方程
兩個方程(兩次calc),兩個未知數(shù)(input_0和input_1,其他都可通過調(diào)試得到),可求解input_0和input_1

利用python的z3庫解方程組,得到input_0和input_1

from z3 import * input_0=Int("input_0") input_1=Int("input_1") s=Solver() s.add(0x7563560E*0x7563560E+0x6C81E68B==0x136*(0x136*0x136+input_0)+input_1) s.add(0xB0A47B8D*0xB0A47B8D+0x6681A442==0x2C0*(0x2C0*0x2C0+input_0)+input_1) if s.check()==sat:print(s.model()) # [input_0 = 12446785179114514, input_1 = 20207707034304107]

跟進encrypt函數(shù),flag長度為44,for循環(huán)中,flag與v2異或,調(diào)試得到每次循環(huán)時v2的值

寫逆腳本即可得到flag

enc=[0x30, 0x78, 0x47, 0x61, 0x6D, 0x65, 0x7B, 0x5F, 0x5F, 0x5B,0x1F, 0x1C, 0x36, 0x25, 0x35, 0x51, 0x5D, 0x19, 0x74, 0x34,0x34, 0x19, 0x14, 0x2D, 0x76, 0x30, 0x64, 0x1F, 0x1C, 0x65,0x7F, 0x68, 0x51, 0x0A, 0x1A, 0x33, 0x69, 0x7F, 0x19, 0x44,0x6C, 0x1A, 0x34, 0x7D] v2=[0xC,0x2C,0x43,0x55,0x11,0x5B,0xE,0x33,0x2A,0x2,0x7,0x46,0x46,0x22,0x1E,0x29,0x7] for i in range(0,16+1):enc[i+9]^=v2[i]enc[i+26]^=v2[i] print("".join(chr(i) for i in enc)) # 0xGame{__W3_c4n_n3v3r_63_7h3_0n3_901n9_fr33}

Thread_TLS

32位exe,ida打開
main函數(shù),驗證輸入的長度是否為33,對輸入進行異或運算,然后啟動一個新線程,調(diào)用StartAddress函數(shù)

跟進StartAddress函數(shù),input和enc比較,驗證輸入
對input按x進行交叉引用,發(fā)現(xiàn)在TlsCallback_1_0函數(shù)中對input有讀寫(r/w)

來到TlsCallback_1_0函數(shù),發(fā)現(xiàn)是典型的RC4算法,input在第48行被加密了

現(xiàn)在知道RC4的密文為StartAddress函數(shù)中的enc,但是不知道密鑰
繼續(xù)對TlsCallback_1_0交叉引用,發(fā)現(xiàn)在TlsCallback_0_0函數(shù)中,對字符串"0xgame2021"進行變表base64變換,放入Source,而Source就是在TlsCallback_1_0函數(shù)中充當RC4密鑰的作用

于是逆向思路為:調(diào)試得到經(jīng)變表base64變換后的Source,也即RC4密鑰,對enc解密RC4,再異或main函數(shù)中的byte_41B221即可得到flag
筆者記得當時按照上述逆向思路沒有解出來,好像是RC4有點問題
我們知道RC4加密過程實際上就是讓明文去異或一個值,而去異或的那個值是由密鑰決定的
于是我們可以構(gòu)造一個長度為33的任意字符串作為輸入,讓程序?qū)@個字符串進行RC4加密,通過調(diào)試取出密文,讓明文與密文異或,即可得到明文在RC4過程中去異或的那些值
然后讓真正的密文enc與那些值異或,即可得到flag
例如,調(diào)試時的輸入為"abcdefghijklmnopqrstuvwxyz0123456",在經(jīng)過程序的RC4加密后得到密文

按照上述思路將真正的密文enc解RC4后,再對enc進行main函數(shù)中異或的逆運算,即可得到flag

# coding:utf-8 -*- #s,任意字符串作為輸入 s="abcdefghijklmnopqrstuvwxyz0123456" arr=[ord(c) for c in s] for i in range(len(arr)-1):arr[i]^=arr[i+1] #arr_res,s經(jīng)程序RC4后的密文 arr_res=[0x82, 0x40, 0xB8, 0x16, 0x84, 0x6F, 0xAE, 0x19, 0x77, 0x2C,0x0E, 0x6C, 0x9D, 0xA0, 0xE9, 0x1E, 0x2F, 0xE8, 0x2D, 0x52,0x32, 0x8F, 0x17, 0xBA, 0xB2, 0x71, 0x8E, 0x83, 0x6F, 0xB1,0x37, 0x53, 0x0A] #xor_num,s在程序RC4過程中去異或的那些值 xor_num=[] for i in range(len(arr)):xor_num.append(arr[i]^arr_res[i]) #enc,真正的密文 enc=[0xC9, 0x7E, 0x99, 0x1B, 0x8F, 0x70, 0xAE, 0x04, 0x2D, 0x6F,0x25, 0x03, 0xDC, 0x8D, 0xC8, 0x21, 0x40, 0xEE, 0x6D, 0x59,0x17, 0xA5, 0x00, 0xA4, 0x9D, 0x16, 0xCC, 0xD6, 0x61, 0xAA,0x7D, 0x12, 0x41] #解密RC4 for i in range(len(enc)):enc[i]^=xor_num[i] #main函數(shù)中的異或的逆運算 for i in range(len(enc)-2,-1,-1):enc[i]^=enc[i+1] print("".join(chr(i) for i in enc)) # 0xGame{th1s_1s_a_34sy_tls_r1ght?}

茶談室

apk文件,jadx-jui打開,MainActivity中,典型的TEA加密算法,iArr為密文,iArr2為密鑰

解密TEA即可得到flag

#include <stdio.h> #include <stdint.h>//加密函數(shù) void encrypt(uint32_t* v, uint32_t* k) {uint32_t v0 = v[0], v1 = v[1], sum = 0, i; /* set up */uint32_t delta = 0x9e3779b9; /* a key schedule constant */uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3]; /* cache key */for (i = 0; i < 32; i++) { /* basic cycle start */sum += delta;v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);} /* end cycle */v[0] = v0; v[1] = v1; } //解密函數(shù) void decrypt(uint32_t* v, uint32_t* k) {uint32_t v0 = v[0], v1 = v[1], sum = 0xC6EF3720, i; /* set up */uint32_t delta = 0x9e3779b9; /* a key schedule constant */uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3]; /* cache key */for (i = 0; i<32; i++) { /* basic cycle start */v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);sum -= delta;} /* end cycle */v[0] = v0; v[1] = v1; }int main() {uint32_t v[2] = { 1336390846, -560752372 };//0xGame{c//uint32_t v[2] = { 286770520, -1746160592 };//a5088de1//uint32_t v[2] = { 1494863960, 1998635107 };//0c64b61a//uint32_t v[2] = { -1598646557, 420086226 };//c1ef47a9//uint32_t v[2] = { 2098399929, 898703653 };//d5f51da}uint32_t k[4] = { 1489485296, 1094338644, -1085167593, 524527081 };int n = sizeof(v) / sizeof(uint32_t);decrypt(v, k);for (int i = 0; i < n; i++){for (int j = 3; j >= 0; j--){printf("%c", (v[i] >> (j * 8)) & 0xFF);}}printf("\n");return 0; } //0xGame{ca5088de10c64b61ac1ef47a9d5f51da}

Junkertown

32位exe,ida打開,main函數(shù)沒有被分析出來,原因是加了花指令
如圖所示,0x00401101的jz要跳轉(zhuǎn)到loc_401103+1即loc_401104處
而ida從loc_401103處開始的機器碼0xE8開始分析,反匯編成了一條call指令,從而造成ida分析main函數(shù)不成功,同時也反映出0xE8為垃圾指令,需要nop掉

main函數(shù)中其他未分析出的地方也是加了上述形式的垃圾指令,全部nop掉即可對main創(chuàng)建函數(shù)及反編譯,反編譯后的偽代碼如下所示

int __cdecl main(int argc, const char **argv, const char **envp) {int v3; // eaxsigned int v4; // kr00_4signed int i; // esisigned int v6; // eaxsigned int v7; // edxsigned int v8; // kr04_4int v9; // esiint v10; // ediconst char *base_str; // ebxint v12; // ecxint v13; // eaxconst char *v14; // esichar *v15; // ebxunsigned int v16; // ediunsigned int v17; // ecxunsigned int v18; // edxint v19; // eaxunsigned int v20; // ecxint v21; // ediint v22; // edxint j; // esiint v24; // ecxint v25; // ebxchar v27; // [esp-10h] [ebp-6Ch]char v28; // [esp-Ch] [ebp-68h]char v29; // [esp-4h] [ebp-60h]char v30; // [esp+0h] [ebp-5Ch]int v31; // [esp+Ch] [ebp-50h]const char *v32; // [esp+10h] [ebp-4Ch]char input[60]; // [esp+1Ch] [ebp-40h] BYREFmemset(input, 0, sizeof(input));sub_401040("Welcome to 0xgame2021!\n", v28);sub_401040("please input your flag:\n", v27);sub_401070("%s", (char)input);if ( &input[strlen(input) + 1] - &input[1] != 44 )goto LABEL_2;v3 = 256;do--v3;while ( v3 );v4 = strlen(input);for ( i = 0; i < v4; ++i )input[i] = 16 * input[i] + ((input[i] >> 4) & 0xF);// 輸入中每字節(jié)的高四位和低四位交換v6 = 0;v7 = v4 - 1;if ( v4 - 1 > 0 ){if ( (unsigned int)v7 >= 0x40 ){do{*(__m128i *)&input[v6] = _mm_xor_si128(*(__m128i *)&input[v6 + 1], *(__m128i *)&input[v6]);*(__m128i *)&input[v6 + 16] = _mm_xor_si128(*(__m128i *)&input[v6 + 17], *(__m128i *)&input[v6 + 16]);*(__m128i *)&input[v6 + 32] = _mm_xor_si128(*(__m128i *)&input[v6 + 33], *(__m128i *)&input[v6 + 32]);*(__m128i *)&input[v6 + 48] = _mm_xor_si128(*(__m128i *)&input[v6 + 49], *(__m128i *)&input[v6 + 48]);v6 += 64;}while ( v6 < v7 - v7 % 64 );}for ( ; v6 < v7; ++v6 )input[v6] ^= input[v6 + 1]; // 輸入前一位和后一位異或}v8 = strlen(input);v9 = 4 * (v8 / 3);v10 = v8 % 3;if ( v8 % 3 )v9 += 4;base_str = (const char *)malloc(__CFADD__(v9, 16) ? -1 : v9 + 16);v12 = v9 - 2;v32 = base_str;v13 = 0;base_str[v9] = 0;if ( v9 - 2 > 0 ){v14 = base_str + 2;v15 = &input[1];v16 = ((unsigned int)(v12 - 1) >> 2) + 1;v31 = 4 * v16;do // 輸入經(jīng)過標準base64變換{v17 = (unsigned __int8)*(v15 - 1);v15 += 3;v18 = (unsigned __int8)*(v15 - 3);v14 += 4;*((_BYTE *)v14 - 6) = byte_403110[v17 >> 2];v19 = (16 * (v17 & 3)) | (v18 >> 4);v20 = (unsigned __int8)*(v15 - 2);*((_BYTE *)v14 - 5) = byte_403110[v19];*((_BYTE *)v14 - 4) = byte_403110[(4 * (v18 & 0xF)) | (v20 >> 6)];*((_BYTE *)v14 - 3) = byte_403110[v20 & 0x3F];--v16;}while ( v16 );v10 = v8 % 3;base_str = v32;v13 = v31;}v21 = v10 - 1;if ( v21 ){if ( v21 == 1 )base_str[v13 - 1] = '=';}else{*(_WORD *)&base_str[v13 - 2] = '==';}v22 = strlen(base_str);for ( j = 0; j < v22; ++j )base_str[j] = 16 * base_str[j] + ((base_str[j] >> 4) & 0xF);// 經(jīng)標準base64變換的輸入每字節(jié)高四位和低四位交換v24 = 0;if ( v22 > 0 ){v25 = base_str - enc;while ( enc[v24 + v25] == enc[v24] ){if ( ++v24 >= v22 )goto LABEL_28;} LABEL_2:puts("Wrong flag!!");exit(0);} LABEL_28:sub_401040("Congratulation to you!!\n", v30);sub_401040("This is a right flag", v29);return 0; }

對輸入進行處理的邏輯為,輸入每字節(jié)的高四位和低四位交換,輸入前一位和后一位異或,輸入經(jīng)標準base64變換,變換后的數(shù)據(jù)每字節(jié)高四位和低四位交換
寫逆運算腳本即可得到flag

import base64 enc=[0x86, 0x05, 0xE4, 0x96, 0x77, 0x94, 0x44, 0x86, 0x76, 0x16,0x75, 0x13, 0xD4, 0x74, 0x55, 0x77, 0x77, 0xA4, 0x44, 0x24,0x87, 0x64, 0x65, 0x14, 0x15, 0xA4, 0x74, 0x25, 0x65, 0x85,0x85, 0x77, 0x15, 0x36, 0x15, 0x65, 0xB6, 0xA4, 0x44, 0x25,0xF6, 0x45, 0x24, 0x14, 0xE4, 0x16, 0x75, 0x13, 0xA5, 0x15,0x65, 0x15, 0x55, 0x84, 0x55, 0x64, 0x43, 0x46, 0x36, 0xD3] for i in range(len(enc)):enc[i]=((enc[i]&0x0f)<<4)|((enc[i]&0xf0)>>4) s="".join(chr(i) for i in enc) s=base64.b64decode(s) arr=[ord(c) for c in s] for i in range(len(arr)-2,-1,-1):arr[i]^=arr[i+1] for i in range(len(arr)):arr[i] = ((arr[i] & 0x0f) << 4) | ((arr[i] & 0xf0) >> 4) flag="".join(chr(i) for i in arr) print(flag) # 0xGame{c9ba7481-a404-4a69-a090-740c9b4dad3c}

總結(jié)

以上是生活随笔為你收集整理的REVERSE-COMPETITION-0xGame2021的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。