BUUCTF Re部分wp(八)


[MRCTF2020]Shit

有三處反調,一處在1640主函數中,一處在1270,直接patch就行

還有一處不會給提示,但是不斷循環,跳過方式為在獲取輸入函數后下個斷點,運行程序后attach上(斷點設在加密函數處斷不下來,不知為啥)

判斷函數在

 

1460中會對一些用到的數據進行修改,所以必須動調(不過分析1460也可以,可以跳過反調部分,就是太麻煩)

 邏輯很簡單,這幾個函數都有一些簡單的花,不太影響

c=[0x8C2C133A, 0x0F74CB3F6, 0x0FEDFA6F2, 0x0AB293E3B, 0x26CF8A2A, 0x88A1F279] k=[3, 16, 13, 4, 19, 11] t=[] p=[] t.append(0x8C2C133A) for i in range(5): t.append(c[i]^c[i+1]) print(t) for i in range(6): temp=t[i]^(1<<k[i]) temp=(temp>>16)&0xffff|(~(temp<<16)&0xffff0000) temp=((temp<<k[i])|(temp>>(32-k[i])))&0xffffffff p.append(str(hex(temp))) print(p) for i in p: print(chr(eval("0x"+i[2:4]))+chr(eval("0x"+i[4:6]))+chr(eval("0x"+i[6:8]))+chr(eval("0x"+i[8:10])),end="")

[b01lers2020]chugga_chugga

go寫的,沒去符號,找到main_main,根據條件解flag就行了

[b01lers2020]little_engine

感覺和上題都是看上去復雜,邏輯都很簡單

第一個函數會獲取一個輸入,沒具體分析,輸個換行就過了

第二個函數會獲取flag,第三個函數進行加密,最后一個比對

 

這里比對的數據地址每次加4

a="E1 E6 D0 4A F2 C3 7E AA E6 FC 42 B2 F2 B5 01 B4 EC 7D 39 20 EF C0 4E 13 C8 2F 67 AA 95 79 6B F5 F2 06 41 79 D8 35 F9 C8 8E DE 88 51 AC 4C F0 81 E0 F4 EE 14 AD F1 25 BD 82 7C 62 30 A5 F8 80 2B 79 85 2A F8 6E 5A AE CB 18 3A A2 D0 09 C5 8C 5D 3D 34 6B F9 3B 72 4B 0E 4A C3 71 53 E1 E9 07 BB C1 1A E7 07 8F 1B 75 74 B9 8E 5D 2E C2 F6 17 3B 52 ED D7 BD 5E E9 76 63 72 E2 EA 89 51 D7 4F 34 DC 39 D5 58 92 D9 D2 D2 AA 69 F1 BF 90 76 E1 9C 39 0D 0C B3 40 06 48 DA 27 D5 1E B8 4A 94 4C 98 C4 8A 68 A8 97 5E 64 F9 C0 58 F7 02 72 8D 3B 88 18 14 EC 8F 42 70 0C 0B 96 66 22 8E F7 58 01 2E C5 DC 4B C0 71 F4 DA E6 3D 73 88 7D E4 91 1F 75 90 70 D6 0C A7 09 7C F2 5A 4E A1 09 0C 51 3C BA A8 64 38 2D 8C 00 88 E3 6F EA 77 90 74 39 AA 56 F1 A8 6E 80 CA 3D 9E 69 A4 69 48 F2 0A 2C F7 33 17 0F 5C F2 8A E5 2F 55 A5 9F 8B 65 54 76 E0 64 EE 9D 9B 2D 9B 5F 72 7F 3B D9 DF 05 69 F0 9F F0 A3 8C E6 CD EF B4 BC 44 54 3E E3 44"
a=a.split()
c=[]
for i in range(len(a)):
if i%4==0:
c.append(a[i])
print(chr(0xe1^0x91),end="")
t=0x91
for i in range(1,len(c)):
t=(t+i-1)%0xff
print(chr(eval("0x"+c[i])^t),end="")

[watevrCTF 2019]esreveR

沒什么難度的題,直接動調得到比對的數

a=[0x77,0x61,0x74,0x65,0x76,0x72,0x7b,0x65,0x73,0x72,0x65,0x76,0x65,0x72,0x5f,0x72,0x65,0x76,0x65,0x72,0x73,0x65,0x64,0x5f,0x79,0x6f,0x75,0x74,0x75,0x62,0x65,0x2e,0x63,0x6f,0x6d,0x2f,0x77,0x61,0x74,0x63,0x68,0x3f,0x76,0x3d,0x49,0x38,0x69,0x6a,0x62,0x34,0x5a,0x65,0x65,0x35,0x45] for i in a: print(chr(i),end="")

[XMAN2018排位賽]Dragon Quest

64位elf,有混淆,主要分析的函數是

使用f5,里面有大量

這些y和x在bss段上,調試發現並沒有寫的操作,一直為默認的0

所以這些判斷第一條小於10則為真,大於等於10為假

匯編發現主要用了eax,ecx,edx,esi,和edi,還有的用了其他的寄存器,但因為判斷是有多個&&和||,所以不用全改也行

addr=
while(addr<): next_addr = NextHead(addr) if "eax, ds:" in GetDisasm(addr): PatchByte(addr,0xb8) PatchByte(addr+1,0x00) PatchByte(addr+2,0x00) PatchByte(addr+3,0x00) PatchByte(addr+4,0x00) PatchByte(addr+5,0x90) PatchByte(addr+6,0x90) if "ecx, ds:" in GetDisasm(addr): PatchByte(addr,0xb9) PatchByte(addr+1,0x00) PatchByte(addr+2,0x00) PatchByte(addr+3,0x00) PatchByte(addr+4,0x00) PatchByte(addr+5,0x90) PatchByte(addr+6,0x90) if "edx, ds:" in GetDisasm(addr): PatchByte(addr,0xba) PatchByte(addr+1,0x00) PatchByte(addr+2,0x00) PatchByte(addr+3,0x00) PatchByte(addr+4,0x00) PatchByte(addr+5,0x90) PatchByte(addr+6,0x90) if "esi, ds:" in GetDisasm(addr): PatchByte(addr,0xbe) PatchByte(addr+1,0x00) PatchByte(addr+2,0x00) PatchByte(addr+3,0x00) PatchByte(addr+4,0x00) PatchByte(addr+5,0x90) PatchByte(addr+6,0x90) if "edi, ds:" in GetDisasm(addr): PatchByte(addr,0xbf) PatchByte(addr+1,0x00) PatchByte(addr+2,0x00) PatchByte(addr+3,0x00) PatchByte(addr+4,0x00) PatchByte(addr+5,0x90) PatchByte(addr+6,0x90) addr = next_addr

去完混淆邏輯就好懂多了

a=[100,214,266,369,417,527,622,733,847,942,1054,1106,1222,1336,1441,1540,1589,1686,1796,1891,1996,2112,2165,2260,2336,2412,2498,2575] print(chr(a[0]),end="") for i in range(1,len(a)): print(chr(a[i]-a[i-1]),end="")  

[QCTF2018]babyre

rust逆向,拖進ida,主函數是main函數上面的那個函數

看着挺復雜,有很多感覺沒啥用的函數,不過程序本身邏輯比較簡單,可以靠動調解決

將32長度的字符串每四個一組交換位置,之后減去一個值,在將高位和低位轉換

c="DA D8 3D 4C E3 63 97 3D C1 91 97 0E E3 5C 8D 7E 5B 91 6F FE DB D0 17 FE D3 21 99 4B 73 D0 AB FE" c=c.split() for i in range(len(c)): c[i]=eval("0x"+c[i]) flag=[] for i in range(len(c)): if i%4==0: t=(c[i]<<5|c[i]>>3)&0xff t-=7
    if i%4==1: t=(c[i]>>6|c[i]<<2)&0xff t-=0x12
    if i%4==2: t=(c[i]<<7|c[i]>>1)&0xff t-=0x58
    if i%4==3: t=(c[i]<<4|c[i]>>4)&0xff t-=0x81 flag.append(t) for i in range(len(flag)): if i%4==0: print(chr(flag[i+1]),end="") if i%4==1: print(chr(flag[i+2]),end="") if i%4==2: print(chr(flag[i-2]),end="") if i%4==3: print(chr(flag[i-1]),end="")

[CFI-CTF 2018]Automated Reversing

一千多個文件,核心部分為

一共有三種,sub,add,xor

for i in range(1009): File = 'binary'+str(i) with open(File,"rb") as f: f=f.read() if ord(f[0xca])==0xf2: print chr(ord(f[0xcb])^ord(f[0xce])&0xff), if ord(f[0xca])==0xea: print chr(ord(f[0xcb])+ord(f[0xce])&0xff), if ord(f[0xca])==0xc2: print chr(ord(f[0xce])-ord(f[0xcb])&0xff),

這題我做過一道類似的,可以看看DASCTF五月線上賽 BScript blink

[watevrCTF 2019]sabataD

這題要拿服務器上的flag,先看給的程序

  

程序邏輯比較簡單,輸入字符進行轉換后分為三份

其中/home/ctf/flag.txt是個過濾,可以用/home/ctf//flag.txt代替

根據規則可構造

Fw/eahttocemhve r/f-cratodfmm/ i/fnfi_ll_ae_g _.w_ti_xt_th__ __i__n__d__e__x

轉換方式可測試得到替換表,之后構造輸入

a="Fw/eahttocemhve r/f-cratodfmm/ i/fnfi_ll_ae_g _.w_ti_xt_th__ __i__n__d__e__x" t1="nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM" t2="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
for i in a: if i=="_" or i=="/" or i=="-" or i=="." or i==" ": print(i,end="") else: print(t2[t1.index(i)],end="")
Sj/rnuggbprzuir e/s-pengbqszz/ v/sasv_yy_nr_t _.j_gv_kg_gu__ __v__a__q__r__k

[GUET-CTF2019]encrypt

基本上就是個rc4

#include<stdio.h> #include<string.h>

int s[256]; char cmp[]="Z`TzzTrD|fQP[_VVL|yneURyUmFklVJgLasJroZpHRxIUlH\\vZE="; char flag[50]; int key[]={16,32,48,48,32,32,16,64}; void sub_4006B6(){ for(int i=0;i<=255;i++){ s[i] = i; } int v4 = 0,v7 = 0,v8 = 0; for ( int j = 0; j <= 255; ++j ){ v4 =s[j]; v7 = (v7 + v4 + key[v8%8]) % 256; s[j] = s[v7]; s[v7] = v4; v8++; } } void sub_4007DB(int len){ int i=0,t=0,j=0,temp=0; for(int k=0;k<len;k++){ i=(i+1)%256; j=(j+s[i])%256; temp=s[i]; s[i]=s[j]; s[j]=temp; t=(s[i]+s[j])%256; flag[k]=s[t]^flag[k]; } } void sub_4008FA(){ int j=0; for(int i=0;i<strlen(cmp);i++) cmp[i] -= 61; for(int i=0;i<strlen(cmp);i++){ if(i%4==0){ flag[j]=cmp[i]<<2|cmp[i+1]>>4; j++; } else if(i%4==1){ flag[j]=cmp[i]<<4|cmp[i+1]>>2; j++; } else if(i%4==2){ flag[j]=cmp[i]<<6|cmp[i+1]; j++; } } } int main(void){ sub_4006B6(); sub_4008FA(); sub_4007DB(strlen(flag)); printf("%s",flag); return 0; }

[CFI-CTF 2018]powerPacked

upx,ppc指令

這題看得有點懵,還不能動調,好在加密簡單,猜出來的

脫殼后查找字符串

這里有一串特殊的字符串,main中有strcmp,猜測是用來比較的字符串

加密屬實沒看明白,但加密部分似乎只有addi,所以猜測是加了某個值

字符串減2可得到CFI{i_love_powerpc,加個}就是flag

不過依然顯示密碼錯誤,不知為啥。。。

[SCTF2019]creakme

die看一下,

 .rdata有殼,調試發現有反調,並且是在開頭的smc里

懶得管,直接attach到程序,發現數據變了,出來了一個base64的密文

在die中還發現

aes,順着這個角度很容易找到密鑰和iv,解得flag


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM