[dragonsector](Reverse)Starblind


簡(jiǎn)介 :

題目地址 : https://s3.eu-central-1.amazonaws.com/dragonsector2-ctf-prod/starblind_96bbc884beb953bee0f120d0994d30d6073c53afd582f456586d7effa184dc25/starblind.html

分析 :

查看源碼發(fā)現(xiàn)有一段 base64 編碼的 js 代碼

Paste_Image.png

直接點(diǎn)開(kāi)瀏覽器會(huì)自動(dòng)解碼 :

Paste_Image.png

可以找到 , 這里是主要的密碼驗(yàn)證的地方 , 會(huì)將用戶(hù)輸入的密碼使用 CalcSha4() 這個(gè)函數(shù)計(jì)算哈希
然后再比較得到的哈希是否和已存在的哈希相同

Paste_Image.png

再來(lái)看 CalcSha4() 這個(gè)函數(shù) :

var CalcSHA4 = function(block) {
  let r = new Uint8Array(64);

  for (let i = 0; i < block.length; i++) {
    r[i] = block.charCodeAt(i); // 將用戶(hù)輸入復(fù)制到新的長(zhǎng)度 64 的數(shù)組中
  }

  for (let i = 32; i < 64; i++) {
    r[i] = i * 48271;  // 后 32 字節(jié)填充
  }

  // 定義異或函數(shù)
  let xor = function (imm) {
    for (let i = 0; i < 64; i++) {
      r[i] ^= imm[i];
    }
  };
  
  // 定義 perm 函數(shù)
  let perm = function (imm) {
    let n = new Uint8Array(64);  
    for (let i = 0; i < 512; i++) {
      const dst_bit = i%8;
      const dst_byte = i/8|0;
      const sign = Math.sgn(imm[i]);
      const idx = sign ? -imm[i] : imm[i];
      const src_bit = idx%8;
      const src_byte = idx/8|0;
      let b = (r[src_byte] >> src_bit) & 1;
      if (sign) { b ^= 1; }      
      n[dst_byte] |= b << dst_bit;
    }
    r = n;
  };

/*
 * 這里省略了 xor 函數(shù) 和 perm 函數(shù)
 */

  // 將數(shù)組轉(zhuǎn)換成 16 進(jìn)制字符串
  hexdigest = "";
  for (let i = 0; i < 64; i++) {
    let n = r[i].toString(16);        
    if (n.length < 2) {
      n = "0" + n;
    }
    hexdigest += n;
  }

  return hexdigest;
}

這里需要我們重點(diǎn)關(guān)注的函數(shù)是 perm 函數(shù) , 單獨(dú)拿出來(lái)分析 :

  let perm = function (imm) {
    let n = new Uint8Array(64);  
    for (let i = 0; i < 512; i++) { // 64字節(jié) -> 512 位 , 也就是遍歷 64 個(gè)字符的每一個(gè)位
      const dst_bit = i%8;
      const dst_byte = i/8|0;
      const sign = Math.sgn(imm[i]); // Math.sgn 返回這個(gè)數(shù)是否為負(fù)數(shù)
      // Math.sgn = function(a) { return 1/a<0; }; 
      const idx = sign ? -imm[i] : imm[i]; // 求出 imm 數(shù)組元素的絕對(duì)值
      const src_bit = idx%8;
      const src_byte = idx/8|0;
      let b = (r[src_byte] >> src_bit) & 1; // 取出 r 的第 idx/8 個(gè)元素的第 idx%8 個(gè) bit
      if (sign) { b ^= 1; } // 如果這里 imm 元素是負(fù)數(shù) , 將這個(gè) bit 與 1 異或
      n[dst_byte] |= b << dst_bit; // 將異或后的 b 放置在 n 這個(gè)數(shù)組的第 i/8 個(gè)元素的第 i%8 個(gè) bit
    }
    r = n;
  };

這里加密算法的流程是這樣 :

1. 加密之前保證明文長(zhǎng)度為 27 字節(jié)
2. 定義一個(gè) 64 字節(jié)的數(shù)組 , 初始值為 0 
3. 將明文按照順序復(fù)制到這個(gè)數(shù)組中
4. 由于明文不足 64 字節(jié) , 因此從 32 位開(kāi)始 , 對(duì)明文進(jìn)行填充 , 具體填充的做法請(qǐng)見(jiàn)上面的代碼
5. 不斷地使用 xor 和 perm 函數(shù)對(duì)函數(shù)中定義的數(shù)組進(jìn)行處理 (大約總共五百多次)
5.1. xor() : xor 的話(huà)在異或一次就可以得到明文
5.2. perm() : 將明文 r(64個(gè)字節(jié)(元素)) 和加密向量 imm(512個(gè)元素) 進(jìn)行運(yùn)算得到密文 n
  5.2.1. 循環(huán)計(jì)數(shù)器 i , 除以 8 得到目標(biāo)字節(jié)的索引
  5.2.2. 循環(huán)計(jì)數(shù)器 i , 求余 8 得到目標(biāo)字節(jié)的 bit 的索引
  5.2.3. imm的元素 , 判斷是否小于 0 , 小于 0 , 則本次循環(huán)中取得的 bit 要與 1 異或 , 大于則不進(jìn)行異或處理
  5.2.4. imm的元素 , 將其除以 8 得到 src_byte , 源字節(jié)
  5.2.5. imm的元素 , 將其求余 8 得到單個(gè)字節(jié)的 bit 數(shù)
  5.2.6. 最后將 r 的 sct_byte 的 src_bit 移動(dòng)到 n 的 dst_byte 的 dst_bit 位置
  5.2.7. 循環(huán) 512 次直到所有 bit 都被移動(dòng)
6. 處理結(jié)束 , 然后將這個(gè)數(shù)組轉(zhuǎn)換成 16 進(jìn)制字符串 , 并返回 , 得到明文的哈希

那么我們現(xiàn)在可以知道的是最終的哈希 , 以及最后一次 perm 函數(shù)中使用到的加密向量 imm
那我們就可以反推出最后一次 perm 函數(shù)執(zhí)行前明文 r 的值
然后就可以一直反推回去 , 就可以得到最終的明文 , 也就是 r 的前 27 字節(jié)
將 js 代碼進(jìn)行簡(jiǎn)單修改即可
這里有一個(gè)需要注意的技巧就是 , 這里有大量的 xor 函數(shù)和 perm 函數(shù)需要逆序執(zhí)行
這里給出兩種方法 :

1. 神馬大哥的方法 : 使用 sublime : Edit->Permute Lines->Reverse
2. linux下使用 tac 命令

最終的 js 代碼如下 :

  let r = [
0x98, 0x3b, 0xb3, 0x5e, 0xd0, 0xa8, 0x00, 0xfc, 
0xc8, 0x5d, 0x12, 0x80, 0x6d, 0xf9, 0x22, 0x53, 
0x64, 0x71, 0x3b, 0xe5, 0x78, 0xba, 0x67, 0xf6, 
0x5b, 0xc5, 0x08, 0xb7, 0x7f, 0x0c, 0x54, 0x87, 
0x8e, 0xda, 0x18, 0xa5, 0xee, 0xd5, 0x0b, 0xac, 
0x70, 0x5b, 0xdc, 0x7d, 0xb2, 0x05, 0x62, 0x32, 
0x21, 0xe8, 0xff, 0xe3, 0x30, 0x48, 0x39, 0x55, 
0xa2, 0x22, 0x16, 0x96, 0x07, 0x54, 0xa1, 0x22
];

  // 定義 Math.sgn 函數(shù)
Math.sgn = function(a) { return 1/a<0; }; 

  // 定義 xor 函數(shù)
  let xor = function (imm) {
    for (let i = 0; i < 64; i++) {
      r[i] ^= imm[i];
    }
  };

  // 定義 perm 函數(shù)
  let perm = function (imm) {
    let n = new Uint8Array(64);  
    for (let i = 0; i < 512; i++) {
      const dst_bit = i%8;
      const dst_byte = i/8|0;
      const sign = Math.sgn(imm[i]);
      const idx = sign ? -imm[i] : imm[i];
      const src_bit = idx%8;
      const src_byte = idx/8|0;
      let b = (r[dst_byte] >> dst_bi) & 1; // 調(diào)換 dst 和 src
      if (sign) { b ^= 1; }      
      n[src_byte] |= b << src_bitt;
    }
    r = n;
  };

/*
 * 這里是已經(jīng)逆向排序的 xor 和 perm 函數(shù)
 */

  // 輸出 r
  for(let i = 0; i < 64; i++){
    console.log(r[i]);
  }

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末搔扁,一起剝皮案震驚了整個(gè)濱河市溶弟,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)震缭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)战虏,“玉大人拣宰,你說(shuō)我怎么就攤上這事》掣校” “怎么了巡社?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)手趣。 經(jīng)常有香客問(wèn)我晌该,道長(zhǎng),這世上最難降的妖魔是什么绿渣? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任朝群,我火速辦了婚禮,結(jié)果婚禮上中符,老公的妹妹穿的比我還像新娘姜胖。我一直安慰自己,他們只是感情好淀散,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布右莱。 她就那樣靜靜地躺著,像睡著了一般档插。 火紅的嫁衣襯著肌膚如雪慢蜓。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,031評(píng)論 1 285
  • 那天阀捅,我揣著相機(jī)與錄音胀瞪,去河邊找鬼。 笑死饲鄙,一個(gè)胖子當(dāng)著我的面吹牛凄诞,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播忍级,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼帆谍,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了轴咱?” 一聲冷哼從身側(cè)響起汛蝙,我...
    開(kāi)封第一講書(shū)人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎朴肺,沒(méi)想到半個(gè)月后窖剑,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡戈稿,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年西土,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鞍盗。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡需了,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出般甲,到底是詐尸還是另有隱情肋乍,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布敷存,位于F島的核電站墓造,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏锚烦。R本人自食惡果不足惜滔岳,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望挽牢。 院中可真熱鬧谱煤,春花似錦、人聲如沸禽拔。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)睹栖。三九已至硫惕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間野来,已是汗流浹背恼除。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人豁辉。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓令野,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親徽级。 傳聞我的和親對(duì)象是個(gè)殘疾皇子气破,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容