昨天小夥伴發來一個逆向題目讓幫忙做一下,拿到程序是個elf文件,先放到kali裡面運行一下,題目提示要輸入一個key

可以看到程序一共有6關,通過這6關拿到flag
先來看下第一關
size_t__fastcallcheck1(constchar*a1){size_tresult;//rax@3size_tv2;//[sp+18h][bp-8h]@1puts("===關卡1===");v2=strlen(a1);if(a1[v2-1]==10)a1[v2-1]=0;result=strlen(a1);if(result!=34){puts("--通關失敗");exit(1);}returnresult;}簡單分析一下,第一關只是對長度進行檢查,長度應該為34才對,輸入一個長度為34的字符串試試。

第一關通關成功,再來看看第二關。
int__fastcallcheck2(constchar*a1){intresult;//eax@1puts("===關卡2===");result=strncmp(a1,"flag{",5uLL);if(result){puts("--通關失敗");exit(1);}returnresult;}第二關是對輸入字符串的前5個字符進行校驗,如果前5個字符為flag{就會通關
來試一下

第二關通關成功,來看下第三關
__int64__fastcallcheck3(constchar*a1){__int64result;//rax@1puts("===關卡3===");result=a1[strlen(a1)-1];if((_BYTE)result!=125){puts("--通關失敗");exit(1);}returnresult;}第三關是取最後一位字符串和125進行比較,125是}的ascii碼,所以第三關是判斷最後一位字符串是不是}
來試一下

第三關通關成功,繼續看下第四關
void__fastcallcheck4(constchar*a1){constcharv1;//[sp+16h][bp-2Ah]@2constcharv2;//[sp+17h][bp-29h]@8unsigned__int64i;//[sp+18h][bp-28h]@1char*v4;//[sp+28h][bp-18h]@1char*s1;//[sp+38h][bp-8h]@1puts("===關卡4===");v4=(char*)(strchr(a1,95)-a1);//95==_s1=(char*)malloc(((unsigned__int64)(v4-5)>>1)+1);for(i=0LL;i<(unsigned__int64)(v4-5)>>1;++i){v1=a1[2*i+5];if(v1<=47||v1>57){if(v1>96&&v1<=102)v1-=87;}else{v1-=48;}v2=a1[2*i+6];if(v2<=47||v2>57){if(v2>96&&v2<=102)v2-=87;}else{v2-=48;}s1[i]=v2|16*v1;}s1[(unsigned__int64)(v4-5)>>1]=0;if(strcmp(s1,"olympics")){puts("--通關失敗");exit(1);}free(s1);}第四關稍微複雜一點,整體程序前三關是對輸入字符串的格式進行判斷,後三關是對輸入的字符串內容進行判斷,後三關分別對應着三串字符串,通過_連接,拼接起來得到flag
第四關就是第一個字符串,首先程序會找到字符串中_的位置,然後根據_的位置作為循環的長度進行處理,最終經過處理的字符串和olympics進行比較,如果相等就通關,如果不相等就輸出通關失敗。
對字符串處理的關鍵代碼在for循環內,簡單分析一下for循環是對字符串中第5位到第20位進行處理,s1就是要比較的字符串,分別取單數字符的ascii和雙數字符的ascii乘16再進行位運算,寫個腳本爆破一下
str='olympics'foriinstr:forv1inrange(33,127):forv2inrange(33,127):count=v1ifcount<=47orcount>57:ifcount>96andcount<=102:count-=87else:count-=48ifv2<=47orv2>57:ifv2>96andv2<=102:v2-=87else:v2-=48if(v2|16*count)==ord(i):print(i,ord(i),'v1=',chr(v1),v1,'v2=',chr(v2),v2)爆破得到符合條件的解不止一個,所以這道題目應該都多個flag,隨便找一個符合條件的解運行一下看看

可以看到已經通關,繼續看下第五關
void__fastcallcheck5(constchar*a1){char*v1;//rax@1charv2;//si@3unsigned__int64i;//[sp+18h][bp-28h]@1signed__int64v4;//[sp+20h][bp-20h]@1char*v5;//[sp+28h][bp-18h]@1char*s1;//[sp+38h][bp-8h]@1puts("===關卡5===");v1=strchr(a1,95);v4=v1+1-a1;v5=(char*)(strchr(v1+1,95)-a1);s1=(char*)malloc((size_t)&v5[-v4+1]);for(i=0LL;i<(unsigned__int64)&v5[-v4];++i){if(i&1)v2=33;elsev2=32;s1[i]=*(&a1[i]+v4)^v2;}s1[2*(_QWORD)&v5[-v4]]=0;if(strcmp(s1,"in")){puts("--通關失敗");exit(1);}free(s1);}第五關比較簡單,就是兩個字符串分別與32和33進行異或得到in,所以正確的字符串應該是IO,在這裡就出現問題了,不知道我的電腦什麼原因,輸入正確的字符串無法通關第五關

這時我以為是我做錯了,要到了別人的wp,仔細看了一下沒什麼問題,只是第四關解的方式不一樣,可是我心想第四關也和第五關沒關係啊,讓朋友在他的電腦上試一下,發現是可以的,後來我又換了Ubuntu試了一下發現是可以的,不知道為啥

那繼續第六關
__int64__fastcallcheck6(constchar*a1){char*v1;//rax@1char*v2;//rax@1char*v3;//rax@1signed__int64v4;//rax@7signed__int64v5;//rcx@8__int64v6;//rdi@8__int64v7;//rsi@8intv8;//eax@13intv9;//eax@16char*s;//[sp+8h][bp-1A8h]@1intv12;//[sp+1Ch][bp-194h]@12signed__int64v13;//[sp+20h][bp-190h]@4signed__int64v14;//[sp+28h][bp-188h]@4unsigned__int64v15;//[sp+30h][bp-180h]@11__int64v16;//[sp+38h][bp-178h]@11signed__int64v17;//[sp+40h][bp-170h]@1signed__int64v18;//[sp+48h][bp-168h]@1char*s1;//[sp+58h][bp-158h]@8intv20[82];//[sp+60h][bp-150h]@8__int64v21;//[sp+1A8h][bp-8h]@1s=(char*)a1;v21=*MK_FP(__FS__,40LL);puts("===關卡6===");v1=strchr(a1,95);v2=strchr(v1+1,95);v17=v2+1-a1;v3=strchr(v2+1,125);v18=v3-a1;if(((_BYTE)v3-(_BYTE)a1-(_BYTE)v17)&3){puts("--通關失敗");exit(1);}v13=3*((unsigned__int64)(v18-v17)>>2);v14=v18-v17;while(1){v4=v14--;if(!v4||*(&a1[v14]+v17)!=61)break;--v13;}s1=(char*)malloc(v13+1);v5=40LL;v6=(__int64)v20;v7=(__int64)">";while(v5){*(_QWORD*)v6=*(_QWORD*)v7;v7+=8LL;v6+=8LL;--v5;}v15=0LL;v16=0LL;while(v15<v13){v12=(v20[*(&s[v15]+v17)-43]<<6)|v20[*(&s[v17+1]+v15)-43];if(*(&s[v17+2]+v15)==61)v8=v12<<6;elsev8=(v12<<6)|v20[*(&s[v17+2]+v15)-43];if(*(&s[v17+3]+v15)==61)v9=v8<<6;elsev9=(v8<<6)|v20[*(&s[v17+3]+v15)-43];s1[v16]=v9>>16;if(*(&s[v17+2]+v15)!=61)s1[v16+1]=BYTE1(v9);if(*(&s[v17+3]+v15)!=61)s1[v16+2]=v9;v15+=4LL;v16+=3LL;}if(strcmp(s1,"china")){puts("--通關失敗");exit(1);}free(s1);return*MK_FP(__FS__,40LL)^v21;}第六關看到字符串china,有了前兩關的經驗猜測是處理後的字符串和china進行比較,但是看這個代碼比較複雜啊,這裡說實話一開始沒看到,看到別人的wp說這裡有左移6和等號等字符,判斷是base64的解碼(看來自己的知識儲備還是不夠,這段代碼要是猜不出來是base64解碼再去分析要浪費很多時間了),所以將china進行base64編碼後得到flag

題目到這已經得到了flag,應該已經結束了,但是看了其他人的wp發現第四關檢查的應該是olympics的十六進制6f6c796d70696373,在上邊用腳本爆破的時候就說過了第四關應該有很多個解,所以說這個題目出的很有問題,雖然不是一道很好的題目,但是還是記錄一下。

第二屆網刃杯網絡安全大賽題目
查看偽代碼,主函數中發現兩個功能函數
__int64fun1(){chars[24];//[rsp+0h][rbp-20h]BYREFunsigned__int64v2;//[rsp+18h][rbp-8h]v2=__readfsqword(0x28u);puts("WelcometoAlaska!!!");puts("pleaseinputkey:");fgets(s,20,stdin);if(4*(3*atoi(s)/9-9)!=4400)exit(0);puts("ok,level_1over!\n\n");return1LL;}__int64fun2(){chars[24];//[rsp+0h][rbp-20h]BYREFunsigned__int64v2;//[rsp+18h][rbp-8h]v2=__readfsqword(0x28u);puts("WelcometoParadiseLost!!!");puts("Thecodevalueisthesmallestdivisible");puts("pleaseinputkey:");fgets(s,20,stdin);if(2*(atoi(s)%56)!=98)exit(0);puts("ok,level_2over!");return1LL;}分析代碼得到,只是簡單的數學運算,得到fun1的值為3327,fun2的值為105
題目提示flag是md5格式,也就是3327105的md5值
flag{31a364d51abd0c8304106c16779d83b1}
0x03 Re_function第二屆網刃杯網絡安全大賽題目
題目比賽的時候沒做出來,拿到手是個壓縮吧,有密碼,一開始爆破沒成功,他這個其實是壓縮包後面跟着一串十六進制數據,裡面是壓縮包的密碼,這個也是後來看別人的wp才知道的,一開始也用十六進制編輯器打開看了,也發現了後面的十六進制數據,當時沒多想。

png的文件頭
把數據複製出來,在線解密網站

得到一半圖片,密碼為3CF8
解壓後得到一個exe和一個elf文件
先分析下exe運行一下是要輸入一個flag,看了看偽代碼,沒看明白

經過分析發現一個main函數,但是沒法反編譯,後來看了很多的wp直說是換表的base64,但是還不是很理解。
去OD進行動調看看

搜索字符串直接斷到輸入的位置,並且根據OD給出的提示發現字符串長度為28位,F8繼續調試

找到對輸入字符串進行處理的位置,這裡是每隔2位,把輸入的字符串和0x37進行xor,F8繼續調試

在這裡可以看到處理後輸入的字符串和要進行對比的28位字符串,前邊判斷是每隔2位和0x37進行xor,寫腳本還原之前的字符串
str=[0x64,0x71,0x54,0x54,0x64,0x78,0x74,0x78,0x64,0x41,0x40,0x48,0x70,0x6D,0x18,0x4A,0x41,0x78,0x66,0x72,0x41,0x78,0x5E,0x4E,0x5D,0x52,0x0E]foriinrange(0,len(str),2):str[i]^=0x37print(bytes(str))#SqcTSxCxSAwHGm/JvxQrvxiNjR9其實到這裡這個exe就已經分析完了,打開elf文件,找到換的解密表進行解密就可以了

這裡是更換的表,在線解密

也可以通過python腳本進行解密
importbase64a='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'#標準表b='FeVYKw6a0lDIOsnZQ5EAf2MvjS1GUiLWPTtH4JqRgu3dbC8hrcNo9/mxzpXBky7+'#新表c='SqcTSxCxSAwHGm/JvxQrvxiNjR9='trantab=c.maketrans(b,a)print(base64.b64decode(c.translate(trantab)))flag{we1come_t0_wrb}
0x04 眼力大考驗2022年藍貝國際創新創業大賽「數字技術+信息安全領域賽道網絡攻防大賽」
拿到程序,無殼,主函數偽代碼。
int__cdeclmain(intargc,constchar**argv,constchar**envp){constchar*v3;//eaxcharv5;//dlcharv6;//clcharv7;//bl__main();if(argc==2){v3=argv[1];if(*v3==51&&v3[1]==54&&v3[2]==byte_403005)//62h{v5=v3[3];if(v5==byte_403008&&v3[4]==50&&v3[5]==52&&v3[6]==52&&v3[7]==50){v6=v3[8];if(v6==table){v7=v3[9];if(v7==byte_403007&&v7==v3[10]&&v6==v3[11]&&v3[12]==52&&v3[13]==57&&v3[14]==49&&v3[15]==48&&v3[16]==53&&v3[17]==51&&v3[18]==48&&v3[19]==50&&v7==v3[20]&&v6==v3[21]&&v5==v3[22]&&v3[23]==56&&v5==v3[24]&&v7==v3[25]&&v3[26]==byte_403006&&v3[27]==byte_403009&&v3[28]==50&&v3[29]==49&&v6==v3[30]&&v3[31]==48){printf("flag{%s}\n",v3);}}}}}else{printf("Usage:%spass",*argv);}return0;}很簡單的代碼邏輯,v3就是flag字符串,32位,根據主函數分析出字符串內容,但是v3[10]、v3[11]、v3[20]、v3[21]、v3[22]、v3[24]、v3[25]、v3[30]的值不知道。
分析出來字符串:36be2442ad 49105302 8 cf21 0
剩下的字符串只能去內存中找了,祭出OD,動調一下

在內存中挨個找出缺少的字符串,然後拼接成flag:36be2442adda49105302dae8edcf21a0
flag{36be2442adda49105302dae8edcf21a0}
0x05 隱秘的角落DASCTF2022.07賦能賽
拿到程序還是先運行一下

程序是go寫的,找到主函數main_main
void__cdeclmain_main(){__int64v0;//rdi__int64v1;//rsi__int64v2;//r8__int64v3;//r9__int64v4;//[rsp+8h][rbp-88h]_QWORD*v5;//[rsp+8h][rbp-88h]_QWORD*v6;//[rsp+50h][rbp-40h]_QWORDv7[2];//[rsp+58h][rbp-38h]BYREF_QWORDv8[2];//[rsp+68h][rbp-28h]BYREF__int64v9[2];//[rsp+78h][rbp-18h]BYREFsync___ptr_WaitGroup__Add((__int64)&main_wg,1LL);runtime_newobject((__int64)&unk_4B0DA0,v4);v6=v5;v9[0]=(__int64)&unk_4B0DA0;v9[1]=(__int64)&off_4E9BB0;//hi,ctfer.givemeaflag:fmt_Fprintln((__int64)&go_itab__os_File_io_Writer,os_Stdout,(__int64)v9,1LL);v8[0]=&unk_4AE9C0;v8[1]=v6;fmt_Fscanf(v0,v1,(constchar*)&go_itab__os_File_io_Reader,(__int64)v8,v2,v3,(__int64)&go_itab__os_File_io_Reader,os_Stdin,(__int64)"%s",2LL,(__int64)v8,1LL,1);runtime_newproc(0x10u,(char)&checkflag,*v6);v7[0]=&unk_4B0DA0;v7[1]=&off_4E9BC0;//WhoamI?whereamI?whatamIdoing?fmt_Fprintln((__int64)&go_itab__os_File_io_Writer,os_Stdout,(__int64)v7,1LL);sync___ptr_WaitGroup__Wait((__int64)&main_wg);}針對go中的一些函數不太清楚,但是這個程序的主函數並不複雜,通過剛才運行程序時所出現的字符串加上主函數進行分析,應該關鍵點就在第36行checkflag函數中,跟進看一下
void__golangmain_checkflag(__int64a1,__int64a2){charv2;//al__int64v3;//[rsp+18h][rbp-70h]charv4;//[rsp+18h][rbp-70h]__int64v5;//[rsp+20h][rbp-68h]__int64v6;//[rsp+28h][rbp-60h]__int64v7;//[rsp+30h][rbp-58h]charv8[32];//[rsp+40h][rbp-48h]BYREF_QWORDv9[2];//[rsp+60h][rbp-28h]BYREF_QWORDv10[2];//[rsp+70h][rbp-18h]BYREFv3=runtime_stringtoslicebyte((__int64)v8,a1,a2);main_Myencode(v3);if(v5==byte_55EA78){runtime_memequal((__int64)main_enc,v3,byte_55EA78,v3);v2=v4;}else{v2=0;}if(v2){v10[0]=&unk_4B0DA0;v10[1]=&off_4E9B90;//Yes,flagis:DASCTF{md5(Input)}fmt_Fprintln((__int64)&go_itab__os_File_io_Writer,os_Stdout,(__int64)v10,1LL,1LL,v6,v7);}else{v9[0]=&unk_4B0DA0;v9[1]=&off_4E9BA0;//No,Didyoufindme?fmt_Fprintln((__int64)&go_itab__os_File_io_Writer,os_Stdout,(__int64)v9,1LL,1LL,v6,v7);}sync___ptr_WaitGroup__Add((__int64)&main_wg,-1LL);}跟進繼續分析發現,flag的值為輸入值的md5
checkflag函數的內容也比較簡單,關鍵點在於第14行main_Myencode函數,這個函數當時我在做這道題目的時候就簡單看了看,沒太注意,導致漏掉了關鍵的地方,跟進main_Myencode函數
__int64__usercallmain_Myencode@<rax>(__int64a1,__int64a2){__int64v3;//[rsp+18h][rbp-50h]__int64v4;//[rsp+20h][rbp-48h]charv5[32];//[rsp+38h][rbp-30h]BYREF__int64v6;//[rsp+58h][rbp-10h]v6=runtime_makeslice((__int64)&unk_4B0EE0,a2,a2);v3=runtime_stringtoslicebyte((__int64)v5,(__int64)main_enc_key,qword_55E898);crypto_rc4_NewCipher(v3,v4);crypto_rc4___ptr_Cipher__XORKeyStream(v3,v6,a2,a2,a1,a2);returna2;}從裡面調用的函數名可以知道這是RC4算法,那麼我們就需要找到密文和key,key在main_Myencode函數中第六行main_enc_key,找到key的值為thisiskkk

這裡有兩種方式找到密文,第一種就是通過靜態分析:
可以通過checkflag函數找到main_enc

跟進unk_54df80,但是這裡的數據還不是真正的密文,是加密前的數據

真正的密文要跟進main_inti_0函數,查看加密算法
signed__int64__usercallmain_init_0@<rax>(){_BYTE*v0;//rdxsigned__int64v1;//rbxsigned__int64result;//raxv0=main_enc;v1=*(_QWORD*)&byte_55EA78;for(result=0LL;result<v1;++result){if((unsigned__int64)result>=*(_QWORD*)&byte_55EA78)runtime_panicIndex();*((_BYTE*)main_enc+result)=v0[result]^0x23;}returnresult;}可以看到密文是和0x23進行xor後的數據,直接寫腳本xor一下得到密文。
第二種方式是直接通過動調得到密文,密文所在位置是0x54df80
可以直接用gdb,在下一條命令的位置下斷點,然後跳到0x54df80的位置查看內存信息

運行到斷點處,jump一下

得到密文

這裡知道了密文和key,網上找了個解密腳本改了改
key='thisiskkk'data=[0xFB,0xC6,0xA6,0x9D,0xC4,0xDB,0x7B,0x56,0xB6,0x46,0xA6,0xC0,0x85,0x64,0x7A,0x9A,0x37,0x4C,0x10,0x96,0xE9,0xA7,0x28,0xC4,0xB1,0x2D,0xF1,0xDE,0x47,0x3B,0xB5,0xF3,0x2C,0x7D,0x67,0x1D]s=[0]*256foriinrange(256):s[i]=iprint(s)j=0foriinrange(256):j=(j+s[i]+ord(key[i%len(key)]))%256print(j)s[i],s[j]=s[j],s[i]i=0j=0res=""forcindata:i=(i+1)%256j=(j+s[i])%256s[i],s[j]=s[j],s[i]res=res+chr(c^s[(s[i]+s[j])%256])print(res)#56e83694-f976-11eb-b343-faffc201c8e0
後開大佬給說了一下在線解密網站也可以解出

DASCTF{9e1963bbbb1285b993c862a5a6f12604}
E
N
D
關
於
我
們
Tide安全團隊正式成立於2019年1月,是新潮信息旗下以互聯網攻防技術研究為目標的安全團隊,團隊致力於分享高質量原創文章、開源安全工具、交流安全技術,研究方向覆蓋網絡攻防、系統安全、Web安全、移動終端、安全開發、物聯網/工控安全/AI安全等多個領域。
團隊作為「省級等保關鍵技術實驗室」先後與哈工大、齊魯銀行、聊城大學、交通學院等多個高校名企建立聯合技術實驗室,近三年來在網絡安全技術方面開展研發項目60餘項,獲得各類自主知識產權30餘項,省市級科技項目立項20餘項,研究成果應用於產品核心技術研究、國家重點科技項目攻關、專業安全服務等。對安全感興趣的小夥伴可以加入或關注我們。
