PVB 题目内容:parse the payload
样本估计是bvp47
https://www.pangulab.cn/files/The_Bvp47_a_top-tier_backdoor_of_us_nsa_equation_group.zh-cn.pdf
根据下面这篇文章解出payload
https://www.qianxin.com/news/detail?news_id=6484
解payload的exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 #include <bits/stdc++.h> #include "defs.h" using namespace std;unsigned char src_buf[8394 ] = { 略 }; int __cdecl _869e0233 _decode_(_BYTE *a1, int a2, char *a3, _DWORD *a4){ _BYTE *v4; unsigned int v5; char *v6; unsigned int v7; int v8; unsigned __int8 *v9; unsigned __int8 *v10; int v11; int v12; unsigned int v13; int v14; int v15; unsigned __int8 v16; int v17; unsigned __int8 *v18; int v19; int v20; int v21; int v22; int v23; int v24; int v25; char *v26; unsigned __int8 v27; int v28; unsigned __int16 v29; int v30; int v31; int v32; int v33; char *v34; unsigned __int16 v35; char *v36; int v37; unsigned __int8 v38; int result; unsigned int v40; unsigned int v41; char *v42; _BYTE *v43; unsigned int v44; unsigned int v45; v4 = a1; v43 = &a1[a2]; *a4 = 0 ; LOBYTE (v5) = *a1; v6 = a3; if ( *a1 > 0x11u ) { v7 = (unsigned __int8)*a1 - 17 ; v4 = a1 + 1 ; if ( v7 <= 3 ) goto LABEL_3; v24 = 0 ; do { a3[v24] = a1[v24 + 1 ]; ++v24; --v7; } while ( v7 ); v25 = (unsigned __int8)v5 - 17 ; v6 = &a3[v25]; v18 = &a1[v25 + 1 ]; goto LABEL_29; } LABEL_12: v5 = (unsigned __int8)v5; v10 = v4 + 1 ; if ( (unsigned __int8)v5 <= 0xFu ) { if ( !(_BYTE)v5 ) { v16 = *v10; v17 = 15 ; if ( !*v10 ) { do { ++v10; v5 += 255 ; v16 = *v10; } while ( !*v10 ); v17 = v5 + 15 ; } ++v10; v5 = v17 + v16; } v18 = v10 + 4 ; *(_DWORD *)v6 = *(_DWORD *)v10; v42 = v6 + 4 ; v45 = v5 - 1 ; if ( v5 == 1 ) { v6 += 4 ; } else { v19 = 0 ; if ( v45 <= 3 ) { do { v6[v19 + 4 ] = v10[v19 + 4 ]; ++v19; } while ( v45 != v19 ); v6 = &v42[v45]; v18 += v45; } else { v41 = (v5 - 5 ) >> 2 ; v20 = 0 ; do { *(_DWORD *)&v6[4 * v20 + 4 ] = *(_DWORD *)&v10[4 * v20 + 4 ]; ++v20; } while ( v20 != v41 + 1 ); v21 = 4 * v20; v18 += v21; v6 = &v42[v21]; v22 = v45 - 4 * v41 - 4 ; if ( v45 - 4 * v41 != 4 ) { v23 = 0 ; do { v6[v23] = v18[v23]; ++v23; } while ( v22 != v23 ); v6 += v22; v18 += v22; } } } LABEL_29: v5 = *v18; v10 = v18 + 1 ; if ( v5 <= 0xF ) { v26 = &v6[-(v5 >> 2 ) - 2049 + -4 * v18[1 ]]; v4 = v18 + 2 ; *v6 = *v26; v6[1 ] = v26[1 ]; v6[2 ] = v26[2 ]; v6 += 3 ; goto LABEL_31; } } while ( 1 ) { if ( v5 > 0x3F ) { v11 = (int )&v6[-((v5 >> 2 ) & 7 ) - 1 ]; v12 = *v10; v4 = v10 + 1 ; v13 = (v5 >> 5 ) - 1 ; v14 = v11 - 8 * v12; goto LABEL_8; } if ( v5 <= 0x1F ) break ; v13 = v5 & 0x1F ; if ( !v13 ) { v27 = *v10; v28 = 31 ; if ( !*v10 ) { do { ++v10; v13 += 255 ; v27 = *v10; } while ( !*v10 ); v28 = v13 + 31 ; } ++v10; v13 = v27 + v28; } v29 = *(_WORD *)v10; v4 = v10 + 2 ; v14 = (int )&v6[-(v29 >> 2 ) - 1 ]; LABEL_41: if ( v13 > 5 && (int )&v6[-v14] > 3 ) { *(_DWORD *)v6 = *(_DWORD *)v14; v44 = (v13 - 6 ) >> 2 ; v40 = v13 - 2 ; v30 = 0 ; do { *(_DWORD *)&v6[4 * v30 + 4 ] = *(_DWORD *)(v14 + 4 * v30 + 4 ); ++v30; } while ( v30 != v44 + 1 ); v31 = 4 * v30; v6 += v31 + 4 ; v32 = v31 + v14 + 4 ; if ( v40 - 4 * v44 != 4 ) { v33 = 0 ; do { v6[v33] = *(_BYTE *)(v32 + v33); ++v33; } while ( v33 != v40 - 4 * v44 - 4 ); v6 += v33; } LABEL_31: v7 = *(v4 - 2 ) & 3 ; if ( (*(v4 - 2 ) & 3 ) == 0 ) goto LABEL_11; goto LABEL_3; } LABEL_8: *v6 = *(_BYTE *)v14; v6[1 ] = *(_BYTE *)(v14 + 1 ); v15 = 0 ; do { v6[v15 + 2 ] = *(_BYTE *)(v14 + v15 + 2 ); ++v15; } while ( v15 != v13 ); v6 += v15 + 2 ; v7 = *(v4 - 2 ) & 3 ; if ( (*(v4 - 2 ) & 3 ) == 0 ) { LABEL_11: LOBYTE (v5) = *v4; goto LABEL_12; } LABEL_3: v8 = 0 ; do { v6[v8] = v4[v8]; ++v8; } while ( v8 != v7 ); v9 = &v4[v8]; v6 += v8; v5 = *v9; v10 = v9 + 1 ; } if ( v5 <= 0xF ) { v37 = *v10; v4 = v10 + 1 ; *v6 = v6[-(v5 >> 2 ) - 1 + -4 * v37]; v6[1 ] = v6[-(v5 >> 2 ) + -4 * v37]; v6 += 2 ; goto LABEL_31; } v34 = &v6[-2048 * (v5 & 8 )]; v13 = v5 & 7 ; if ( !v13 ) { while ( 1 ) { v38 = *v10; if ( *v10 ) break ; v13 += 255 ; ++v10; } ++v10; v13 += v38 + 7 ; } v35 = *(_WORD *)v10; v4 = v10 + 2 ; v36 = &v34[-(v35 >> 2 )]; if ( v36 != v6 ) { v14 = (int )(v36 - 0x4000 ); goto LABEL_41; } *a4 = v6 - a3; result = 0 ; if ( v4 != v43 ) return v4 < v43 ? -8 : -4 ; return result; } char *__cdecl _4743c911_xor_(char *a1, unsigned int a2){ int v2; unsigned int i; char v4; if ( a2 ) { v2 = 0 ; for ( i = 0 ; i < a2; ++i ) { v4 = v2 ^ a1[i] ^ 0x47 ; v2 += (unsigned __int8)a1[i]; a1[i] = i ^ v4; } } return a1; } char dst_buf[0x5618 ];int main () { int src_size = 0x20CA ; int dst_size = 0x5618 ; memset (dst_buf,0 ,dst_size); _4743c911_xor_((char *)src_buf,src_size); _869e0233 _decode_(src_buf,src_size,dst_buf,(uint32_t *)&dst_size); FILE * dp = fopen ("sec_0" ,"wb" ); fwrite (dst_buf,dst_size,1 ,dp); fclose (dp); }
解出来可以大概看出来是个3DES
题目里面自带了DES的加密和解密,通过mode参数1和2判断
patch把1和2都颠倒过来
就可以让原本的加密逻辑变成解密
然后这个时候输入密文即可得到明文
simple-VM 题目内容:简单的vm 最好的vm
len(input)==32
1 2 3 4 5 if ( (unsigned int )sub_7FF7DD101D30(input, _quest) ){ sub_7FF7DD1011B0("Ultimate secret box is not only the name muahahaha" ); return 0 ; }
quest是第一部分虚拟机的执行流 input是输入
1 2 3 4 5 6 7 8 9 10 11 12 0x11 : push X0x12 : pop now_char_0x13 : pop x ;pop y ;push x*y;0x14 : pop x ;pop y ;push x+y;0x15 : printf("%c" ,now_char_)0x16 : push input [index]0x17 : pop x ;pop y ;push (y >> x) & 1 ;0x18 : pop x ;pop y ;push x^y;0x19 : index++0x1A : return ( need 0 )0x1B : pop x ;pop y ;push x-y;0x1C : pop x ;pop y ;push x/y;
输错一遍会把下发的VM指令改了
如果一开始什么都不知道运行了一遍就会出现对着被改的指令嗯求求不出来的情况(*^_^*)
流程大概是把输入的每个字节的8个bit分别和0/1进行判断,相同则把一个常数加到sum中,如果8个bit计算完的结果和预期值相等,则该输入字节正确。
可以暴力遍历所有的2^8个可能性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 f = open ("quest" ,'rb' ) data = f.read() data2 = data[0x110 :] input_index = 0 number = [0 for i in range (8 )] for i in range (32 ): data = data2[i*0x43 :0x43 +i*0x43 ] index = 0 for j in range (8 ): number[j] = data[5 +j*7 ] target = (data[-3 ]) for emu in range (2 **8 -1 ): num8 = emu>>7 &1 num7 = emu>>6 &1 num6 = emu>>5 &1 num5 = emu>>4 &1 num4 = emu>>3 &1 num3 = emu>>2 &1 num2 = emu>>1 &1 num1 = emu&1 if (number[0 ]*num1 + number[1 ]*num2 + number[2 ]*num3 + number[3 ]*num4 + number[4 ]*num5 + number[5 ]*num6 + number[6 ]*num7 + number[7 ]*num8) == target: if emu < 0x7f and emu > 0x20 : print (chr (emu&0xff ),end="" ) print ("" )data = "s1mpl3_VM_us3s_link3d_l1st_st4ck" print (len (data))