MIsc:流量分析
這道題,在比賽的時候就差個key了,但是沒想到要改高度,后來群里師傅說了下,就再試試,
導出來改高度。
導出來,把
把%5c(4)前面的hex刪掉,改成png,就直接拿去那個img-add_info里面出現的,就ok了
轉acsii就出來了
web:滴~~~~~~
這道題是我朋友教我的。看到這里就有個文件讀取,
然后,看了下源代碼,發現都是flag.jpg是用base64讀出來的。
那有沒可能讀取其他的文件,然后用這種方法將文件直接讀出來,再用base64解碼呢。現在除了index.php (和flag.txt 腦海里幻想 希望就有這文件而且直接能讀吧,打臉了),直接讀index.php,發現和之前的一道百度杯很像,但是這里將config 換成了!,
就找到了indexphp的源碼了,但是這個和百度杯的那個似乎不一樣,怎么試都找不到那個.base文件。就問了下我朋友,他說上面的博客會有提示,whta_the—fuc!!!一開始我還以為是出題人為了宣傳自己的博客而放在那里了呢。結果我想多了。
就是這篇文章,說的vim異常退出時產生的文件
這里借一下這位師傅的圖
然后就每個都試試,還真的能行。
?> <?php include('config.php'); $k = 'hello'; extract($_GET); if(isset($uid)) { $content=trim(file_get_contents($k)); if($uid==$content) { echo $flag; } else { echo'hello'; } } ?>
就讀出了這個,這個我記得bugku
也這樣的題,就是變量覆蓋
https://www.jianshu.com/p/a4d782e91852 這篇文章講得不錯。
2、re
這兩道re都是挺基礎的,有耐心一點點分析就肯定能出來,一開始以為自己沒做個re的題,新手,不敢嘗試想留着賽后慢慢復現的,結果就留到了最后一天,結果做到半夜3點。。可憐弱雞的我
這兩道都是差不多題的目,只是殼不同了,之前沒脫過殼,后來找了下esp定律,真香。
第一道題 把殼脫完,就出flag,直接跟下去
我沒xp,和win7 脫殼失敗,師傅說win10有內存保護機制,我就直接魯了
跟下去
關鍵call。跟進去
輸入code,跟進第一個call
我猜想這個會處理前面輸入的數據,也就是code
這個eax就是code是數據長度了
call 完了 棧內的數據
這個就很有意思了。這個怎么來的?
前面有個地方
用eax作為一個index在哪個地址取值,
000F2FF8 0000 add byte ptr ds:[eax],al
000F2FFA 0000 add byte ptr ds:[eax],al
000F2FFC 0000 add byte ptr ds:[eax],al
000F2FFE 0000 add byte ptr ds:[eax],al
000F3000 1BA7 133BE458 sbb esp,dword ptr ds:[edi+0x58E43B13]
000F3006 ec in al,dx
000F3007 c4ff les edi,edi
000F3009 ff db ff
000F300A ff db ff
000F300B ff db ff
000F300C ff db ff
000F300D ff db ff
000F300E ff db ff
000F300F ff db ff
000F3010 fe db fe
000F3011 ff db ff
000F3012 ff db ff
000F3013 FF01 inc dword ptr ds:[ecx]
000F3015 0000 add byte ptr ds:[eax],al
000F3017 007E 7D add byte ptr ds:[esi+0x7D],bh
000F301A 7C 7B jl short reverse1.000F3097
000F301C 7A 79 jpe short reverse1.000F3097
000F301E 78 77 js short reverse1.000F3097
000F3020 76 75 jbe short reverse1.000F3097
000F3022 74 73 je short reverse1.000F3097
000F3024 72 71 jb short reverse1.000F3097
000F3026 70 6F jo short reverse1.000F3097
000F3028 6e outs dx,byte ptr ds:[esi]
000F3029 6d ins dword ptr es:[edi],dx
000F302A 6c ins byte ptr es:[edi],dx
000F302B 6B6A 69 68 imul ebp,dword ptr ds:[edx+0x69],0x68
000F302F 67 addrsize:
000F3030 66 datasize:
000F3031 65 gs:
000F3032 64:6362 61 arpl word ptr fs:[edx+0x61],sp
000F3036 60 pushad
000F3037 5F pop edi ; reverse1.000F33D4
000F3038 5E pop esi
000F3039 5D pop ebp
000F303A 5C pop esp
000F303B 5B pop ebx
000F303C 5A pop edx
000F303D 59 pop ecx
000F303E 58 pop eax
000F303F 57 push edi ; reverse1.000F33D4
000F3040 56 push esi
000F3041 55 push ebp
000F3042 54 push esp
000F3043 53 push ebx
000F3044 52 push edx
000F3045 51 push ecx
000F3046 50 push eax
000F3047 4F dec edi ; reverse1.000F33D4
000F3048 4E dec esi
000F3049 4D dec ebp
000F304A 4c dec esp
000F304B 4B dec ebx
000F304C 4A dec edx
000F304D 49 dec ecx
000F304E 48 dec eax
000F304F 47 inc edi ; reverse1.000F33D4
000F3050 46 inc esi
000F3051 45 inc ebp
000F3052 44 inc esp
000F3053 43 inc ebx
000F3054 42 inc edx
000F3055 41 inc ecx
000F3056 40 inc eax
000F3057 3F aas
000F3058 3e:3d 3c3b3a39 cmp eax,0x393a3b3c
000F305E 3837 cmp byte ptr ds:[edi],dh
000F3060 36:35 34333231 xor eax,0x31323334
000F3066 302F xor byte ptr ds:[edi],ch
000F3068 2e:2d 2c2b2a29 sub eax,0x292a2b2c
000F306E 2827 sub byte ptr ds:[edi],ah
000F3070 26:25 24232221 and eax,0x21222324
000F3076 2000 and byte ptr ds:[eax],al
000F3078 0100 add dword ptr ds:[eax],eax
000F307A 0000 add byte ptr ds:[eax],al
000F307C A8 1B test al,0x1B
000F307E 42 inc edx
000F307F 0070 10 add byte ptr ds:[eax+0x10],dh
000F3082 42 inc edx
就可以看到這些了,而eax呢
通過我們們輸入的字符的16進制作為,從0xf2ff8開始找,最后和DDCTF{reverseME}對比一下就ok了,這個就是這道題的解法。
第二道是ASP的殼,一樣用esp定律,這里也有像第一道re一樣的處理方法,
一樣關鍵call,但是這個call首先判斷輸入是否合法
012511F0 8BC6 mov eax,esi #esi 指向 字符串 012511F2 8D50 01 lea edx,dword ptr ds:[eax+0x1] 012511F5 8A08 mov cl,byte ptr ds:[eax] 012511F7 40 inc eax 012511F8 84C9 test cl,cl 012511FA ^ 75 F9 jnz short reverse2.012511F5 012511FC 2BC2 sub eax,edx//eax為字符數 012511FE 8BD0 mov edx,eax//edx也為字符數 01251200 74 39 je short reverse2.0125123B 01251202 25 01000080 and eax,0x80000001// eax 為1 就是說eax的最后一位不能為1即 flag的數目為0x10 01251207 79 05 jns short reverse2.0125120E 01251209 48 dec eax 0125120A 83C8 FE or eax,-0x2 0125120D 40 inc eax 0125120E 83F8 01 cmp eax,0x1 01251211 74 28 je short reverse2.0125123B//就是說eax的最后一位不能為1即 flag的數目為0x10 01251213 33C9 xor ecx,ecx 01251215 85D2 test edx,edx 01251217 7E 1F jle short reverse2.01251238 01251219 8DA424 00000000 lea esp,dword ptr ss:[esp] 01251220 8A0431 mov al,byte ptr ds:[ecx+esi] 01251223 3C 30 cmp al,0x30// 0 01251225 7C 04 jl short reverse2.0125122B 01251227 3C 39 cmp al,0x39//9 01251229 7E 08 jle short reverse2.01251233 0125122B 3C 41 cmp al,0x41 0125122D 7C 0C jl short reverse2.0125123B//全部大於0x41 0125122F 3C 46 cmp al,0x46 01251231 7F 08 jg short reverse2.0125123B//且小於0x46 'F' 01251233 41 inc ecx 01251234 3BCA cmp ecx,edx 01251236 ^ 7C E8 jl short reverse2.01251220 01251238 B0 01 mov al,0x1 0125123A C3 retn 0125123B 32C0 xor al,al 0125123D C3 retn //0-9 A-F
然后往下走
然后這個就是關鍵的判斷函數了。
0125125F 8D50 01 lea edx,dword ptr ds:[eax+0x1] 01251262 8A08 mov cl,byte ptr ds:[eax] 01251264 40 inc eax 01251265 84C9 test cl,cl 01251267 ^ 75 F9 jnz short reverse2.01251262 01251269 2BC2 sub eax,edx// eax 就是字符數 0125126B 68 FF030000 push 0x3FF 01251270 8BF8 mov edi,eax 01251272 8D4424 11 lea eax,dword ptr ss:[esp+0x11] 01251276 6A 00 push 0x0 01251278 50 push eax 01251279 884C24 18 mov byte ptr ss:[esp+0x18],cl 0125127D E8 E8090000 call reverse2.01251C6A ; jmp 到 msvcr90.memset 01251282 83C4 0C add esp,0xC 01251285 33D2 xor edx,edx 01251287 85FF test edi,edi ; msvcr90.printf 01251289 7E 61 jle short reverse2.012512EC 0125128B 53 push ebx 0125128C 8A5C24 0F mov bl,byte ptr ss:[esp+0xF] 01251290 8A0416 mov al,byte ptr ds:[esi+edx] 01251293 8AC8 mov cl,al 01251295 80E9 30 sub cl,0x30 01251298 80F9 09 cmp cl,0x9 //跟0x39比(0-9) 0125129B 77 06 ja short reverse2.012512A3 如果小與9 就直接把給esp+0xf//大於了就給下面字符的處理 0125129D 884C24 0F mov byte ptr ss:[esp+0xF],cl 012512A1 EB 10 jmp short reverse2.012512B3 012512A3 8AC8 mov cl,al 012512A5 80E9 41 sub cl,0x41 012512A8 80F9 05 cmp cl,0x5 //(A-F) 012512AB 77 06 ja short reverse2.012512B3 012512AD 2C 37 sub al,0x37 //不大的話就直接減0x37,然后給esp+0xf 012512AF 884424 0F mov byte ptr ss:[esp+0xF],al 012512B3 8A4416 01 mov al,byte ptr ds:[esi+edx+0x1] //下一位是否為數字 012512B7 8AC8 mov cl,al 012512B9 80E9 30 sub cl,0x30 012512BC 80F9 09 cmp cl,0x9 012512BF 77 04 ja short reverse2.012512C5//如果是數字就將cl給bl,不然就交給下面,下面判斷字符 012512C1 8AD9 mov bl,cl 012512C3 EB 0E jmp short reverse2.012512D3 012512C5 8AC8 mov cl,al //是否是字符 012512C7 80E9 41 sub cl,0x41 012512CA 80F9 05 cmp cl,0x5 012512CD 77 04 ja short reverse2.012512D3 012512CF 2C 37 sub al,0x37 //如果是字符就將al減去0x37,然后再給bl 012512D1 8AD8 mov bl,al 上的結論。是數字就直接給bl,字符的漸趨0x37再給bl 012512D3 8A4424 0F mov al,byte ptr ss:[esp+0xF]//將esp+0xf的值給al,這里是第一次處理的數據 012512D7 C0E0 04 shl al,0x4 //然后al左移四位 012512DA 8BCA mov ecx,edx 012512DC 0AC3 or al,bl //al or bl ,然后賦予給al 012512DE D1E9 shr ecx,1 //ecx右移1位,就相當於除於二 012512E0 83C2 02 add edx,0x2 //edx就相當於index 012512E3 3BD7 cmp edx,edi edi是字符數 ; msvcr90.printf 012512E5 88440C 10 mov byte ptr ss:[esp+ecx+0x10],al 012512E9 ^ 7C A5 jl short reverse2.01251290 012512EB 5B pop ebx ; msvcr90.printf 012512EC 8BC7 mov eax,edi ; msvcr90.printf 012512EE 99 cdq// 將eax的32bit 復制到edx的每一個bit上去 012512EF 2BC2 sub eax,edx 012512F1 D1F8 sar eax,1// eax 除以二 012512F3 55 push ebp 012512F4 50 push eax 012512F5 8D4C24 14 lea ecx,dword ptr ss:[esp+0x14] ecx指向那個前面弄的數組里面就是esp+ecx+0x10 012512F9 E8 02FDFFFF call reverse2.01251000 012512FE 8B8C24 14040000 mov ecx,dword ptr ss:[esp+0x414] 01251305 83C4 08 add esp,0x8 01251308 5F pop edi ; msvcr90.printf 01251309 5D pop ebp ; msvcr90.printf 0125130A 33CC xor ecx,esp 0125130C E8 4D010000 call reverse2.0125145E 01251311 81C4 08040000 add esp,0x408 01251317 C3 retn
下面這個是最關鍵的了。
01251072 8A4424 14 mov al,byte ptr ss:[esp+0x14]#1 第一次調用 01251076 8AD0 mov dl,al 01251078 C0EA 02 shr dl,0x2 0125107B 24 03 and al,0x3 0125107D C0E0 04 shl al,0x4 01251080 885424 18 mov byte ptr ss:[esp+0x18],dl# 第一次賦值 bl是第二次就是中間的值 01251084 8ACB mov cl,bl 01251086 C0E9 04 shr cl,0x4 01251089 02C1 add al,cl 0125108B 884424 19 mov byte ptr ss:[esp+0x19],al #第二次賦值 0125108F 8A4424 16 mov al,byte ptr ss:[esp+0x16]#2 第san次調用 01251093 8AD3 mov dl,bl 01251095 80E2 0F and dl,0xF 01251098 02D2 add dl,dl 0125109A 8AC8 mov cl,al 0125109C 02D2 add dl,dl 0125109E C0E9 06 shr cl,0x6 012510A1 02D1 add dl,cl 012510A3 24 3F and al,0x3F 012510A5 885424 1A mov byte ptr ss:[esp+0x1A],dl#第三次賦值 012510A9 884424 1B mov byte ptr ss:[esp+0x1B],al#第四次賦值 012510AD 33F6 xor esi,esi 012510AF 90 nop 012510B0 0FB65434 18 movzx edx,byte ptr ss:[esp+esi+0x18] 012510B5 8A82 20302501 mov al,byte ptr ds:[edx+0x1253020] 012510BB 34 76 xor al,0x76 012510BD 0FB6C8 movzx ecx,al 012510C0 51 push ecx 012510C1 8D4C24 24 lea ecx,dword ptr ss:[esp+0x24] // 012510F7 8A5C24 21 mov bl,byte ptr ss:[esp+0x21] bl也是AA 012510FB 83C4 0C add esp,0xC 012510FE 8A4424 14 mov al,byte ptr ss:[esp+0x14] 這里又恢復到0x38指向的位置 01251102 8AC8 mov cl,al 01251104 8AD3 mov dl,bl 01251106 24 03 and al,0x3 01251108 C0E0 04 shl al,0x4 0125110B C0EA 04 shr dl,0x4 0125110E 02C2 add al,dl 01251110 C0E9 02 shr cl,0x2 01251113 80E3 0F and bl,0xF 01251116 884424 19 mov byte ptr ss:[esp+0x19],al 0125111A 8A4424 16 mov al,byte ptr ss:[esp+0x16] 0125111E 02DB add bl,bl 01251120 884C24 18 mov byte ptr ss:[esp+0x18],cl 01251124 8AC8 mov cl,al 01251126 02DB add bl,bl 01251128 C0E9 06 shr cl,0x6 0125112B 02D9 add bl,cl 0125112D 885C24 1A mov byte ptr ss:[esp+0x1A],bl 01251131 24 3F and al,0x3F 01251133 8D5E 01 lea ebx,dword ptr ds:[esi+0x1] 01251136 33FF xor edi,edi 01251138 884424 1B mov byte ptr ss:[esp+0x1B],al 0125113C 85DB test ebx,ebx 0125113E 7E 20 jle short reverse2.01251160 01251140 0FB6543C 18 movzx edx,byte ptr ss:[esp+edi+0x18] 01251145 8A82 20302501 mov al,byte ptr ds:[edx+0x1253020] 0125114B 34 76 xor al,0x76 0125114D 0FB6C8 movzx ecx,al 01251150 51 push ecx 01251151 8D4C24 24 lea ecx,dword ptr ss:[esp+0x24]
就是這個搞了我好幾個小時,
關鍵的就是
這就個add ,這里通過前面的幾個運算,然后四個bit一起,往棧寫8個bit 這8個bit是用前面算好的 放在[esp + 0x14] 到[esp +0x 16] 的這個值,然后通運算在
01253014 0100 add dword ptr ds:[eax],eax 01253016 0000 add byte ptr ds:[eax],al 01253018 14 21 adc al,0x21 0125301A 25 01000000 and eax,0x1 0125301F 0037 add byte ptr ds:[edi],dh 01253021 34 35 xor al,0x35 01253023 3233 xor dh,byte ptr ds:[ebx] 01253025 3031 xor byte ptr ds:[ecx],dh 01253027 3e:3f aas 01253029 3C 3D cmp al,0x3D 0125302B 3A3B cmp bh,byte ptr ds:[ebx] 0125302D 3839 cmp byte ptr ds:[ecx],bh 0125302F 26:27 daa 01253031 24 25 and al,0x25 01253033 2223 and ah,byte ptr ds:[ebx] 01253035 2021 and byte ptr ds:[ecx],ah 01253037 2e:2f das 01253039 2C 17 sub al,0x17 0125303B 14 15 adc al,0x15 0125303D 1213 adc dl,byte ptr ds:[ebx] 0125303F 1011 adc byte ptr ds:[ecx],dl 01253041 1E push ds 01253042 1f pop ds 01253043 1C 1D sbb al,0x1D 01253045 1A1B sbb bl,byte ptr ds:[ebx] 01253047 1819 sbb byte ptr ds:[ecx],bl 01253049 06 push es 0125304A 07 pop es 0125304B 04 05 add al,0x5 0125304D 0203 add al,byte ptr ds:[ebx] 0125304F 0001 add byte ptr ds:[ecx],al 01253051 0E push cs 01253052 0f db 0f 01253053 0C 46 or al,0x46 01253055 47 inc edi 01253056 44 inc esp 01253057 45 inc ebp // 01253058 42 inc edx 01253059 43 inc ebx 0125305A 40 inc eax 0125305B 41 inc ecx 0125305C 4E dec esi 0125305D 4F dec edi 0125305E 5D pop ebp 0125305F 59 pop ecx 01253060 0100 add dword ptr ds:[eax],eax 01253062 0000 add byte ptr ds:[eax],al 01253064 A8 1B test al,0x1B 01253066 B6 00 mov dh,0x0 01253068 70 10 jo short reverse2.0125307A 0125306A B6 00 mov dh,0x0
這個表里面找出數據最后和0x76 XOR 最后結果是 DDCTF{reverse+}括號里面的內容就ok,前面也有個地方判斷,字符串的長度的最后一位不能是1,還有要滿足6的倍數,不然最后一個會加上'=' 這就不可能匹配了。
經過了這次的比賽后,發現re還是得多練,一步不跟進,慢慢分析里面的算法,小心出題的人留下的坑。。。。。
有哪里寫的不對的請大家多多包涵,可以的希望能給我指出來。