CTFHub題解-歷年真題-Crypto-2020BJDCTF【編碼與調制、base??】


 CTFHub題解-歷年真題-Crypto篇

 

  2020-BJDCTF-Crypto

 

(一)編碼與調制

 

 
 
本題要點:binascii進制轉換、曼徹斯特編碼
 
 
下載附件看一下:
 
有一張圖,I· m hint,上面有一串二進制01001100011,暫時還不知道是什么意義......
 
先了解一下曼徹斯特編碼和差分曼徹斯特編碼
 
  曼徹斯特編碼:每一位的中間有一跳變,位中間的跳變既作時鍾信號,又作數據信號;從高到低跳變表示"1",從低到高跳變表示"0"。
 
 
  差分曼徹斯特編碼:每位中間的跳變僅提供時鍾定時,而用每位開始時有無跳變表示"0"或"1",有跳變為"0",無跳變為"1"。 
 
 
 
 
 
  一:標准曼徹斯特編碼波形圖1代表從高到低,0代表從低到高
  二:差分曼徹斯特編碼波形圖1代表沒有跳變(也就是說上一個波形圖在高現在繼續在高開始,上一波形圖在低繼續在低開始)開始畫0代表有跳變(也就是說上一個波形圖在高位現在必須改在低開始,上一波形圖在高位必須改在從低開始)
  注:第一個是0的從低到高,第一個是1的從高到低,后面的就看有沒有跳變來決定了(差分曼徹斯特編碼) 
 
emmmm,看懂了兩種編碼的原理,感覺那一串二進制好像沒什么解題思路呢....還是先看看密文吧.....
 
    密文:2559659965656A9A65656996696965A6695669A9695A699569666A5A6A6569666A59695A69AA696569666AA6 
 
 
密文看起來像是16進制,但是解轉字符串出來是亂碼....
 
參考了一些大佬的wp,發現還有這個16進制轉2進制和曼徹斯特編碼的轉碼工具~
 
 
 
 
 
 
 
為什么選標准曼徹斯特,因為筆者用小工具試了一下 802.3曼徹斯特和差分曼徹斯特,轉出來的16進制轉字符都是亂碼(捂臉)...
 
曼徹斯特解碼之后的16進制我們再轉一下字符串~
 
  16進制:024A447B4469664D616E63686573746572636F64657D 
 
 
  咦,第一位沒有顯示出來誒........當然,比賽的時候,猜的話肯定能猜到是BJD{}......
 
 
  試試用python轉一下呢~
 
 
  補充一點py的語法~
  
python內置函數:
  hex():
  #把10進制轉整形換成16進制
  #內置函數hex和binascii.hexlify()的區別就在於,
  #hex只能接受整形不能接受字符串

 

import binascii 
x=0x024A447B4469664D616E63686573746572636F64657D 
x=binascii.unhexlify(hex(x)[2:]) print(x)

 

 
   binascii模塊是python的一個用於進制轉換的模塊,關於binascii.unhexlify感興趣的小伙伴可以參考這篇博客:
 
   python binascii 二進制轉換實例【b2a_hex、a2b_hex、hexlify、unhexlify】
 
 
  由於筆者的py學的比較差,好多語法都還不會,起初沒太明白這個地方的hex(x)[2:]是什么意思.....網上找了半天資料,也沒有解釋...
  后來筆者經過測試和猜測:
  x=binascii.unhexlify(hex(x)[2:]) 此處的[2:]應該是讀取x的0x這兩個字節,因為我發現當把[2:]中的2改成4的時候,輸出結果就變成了JD{DifManchestercode};依次變成6/8/10的時候,輸出的字符串的開頭就會少一位。
  因為如果刪去[2:],運行會報錯binascii.Error: Non-hexadecimal digit found,不識別十六進制數。
 
 
啊哦,發現報錯~
 
 
 
 
因為hexstr必須包含偶數個十六進制數字,所以奇數長度會報錯。
 
參考很多大佬的wp都是讓添加‘0’,而且我也沒有懂為什么要加‘0’,其實只要補一個字節就可以了。
而且之所以會變成奇數長度,主要是因為hex在轉換16進制的時候,把x=0x024A...36F64657D開頭的024A直接轉換成了24A;
所以你其實在x=0x ?24A...36F64657D這里改成任何一個非零的數字就可以。
 
import binascii
x=0x024A447B4469664D616E63686573746572636F64657D
x=binascii.unhexlify('0'+hex(x)[2:])
print(x)

 

 
運行是正常了,但是結果似乎不太對呢~
 
 
難道是轉碼轉錯了?但是其他的轉出來就更離譜.....
 
思索了半天,其實報錯是因為字符串是一個奇數字符串,所以要加一個字節變成偶數,B的16進制應該是42。
按理說  x=424A447B4469664D616E63686573746572636F64657D 就是正確的flag了
 
(筆者這屬於沒事干瞎想,比賽的時候,直接猜就完事了!)
 
有可能是出題人出錯了,也有可能暗含其他玄機,懂得小伙伴可以給我評論,指點一下迷津~
 
import binascii
x=0x424A447B4469664D616E63686573746572636F64657D
#此處改成0x42才能運行出正確結果
x=binascii.unhexlify(hex(x)[2:]) 
print(x)
 
 
 
 
 
  BJD{DifManchestercode} 
 
完成!
 
 

(二)base??

 
 
本題要點:base64編解碼原理、python基礎編程
 
 
 
題目是這樣:
 
 
 
 
emmm....給出了字典,給出了密文,有可能是讓我們根據base64編碼原理,解明文
 
先學習一下base64的編碼原理:
 
 
Base64是一種基於64個可打印字符來表示二進制數據的表示方法
 
Base64是一種編碼方式,提及編碼方式,必然有其對應的字符集合。在Base64編碼中,相互映射的兩個集合是:
 
二進制數據{0, 1}
{A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, +, /}
 
Base64編碼方式可使得信息在這兩種字符集表示法之間相互等價轉換。
 
因為Base64的編碼方式是公開的,所以base64也可以算是公開算法的加密方法;但是只能簡單的“加密”保護某些數據,決不能在需要安全等級較高的場景中使用,因為可以使用公開的編碼方法輕易從base64字符表示的數據解碼二進制數據。
 
 base64編碼過程
  由於base64的字符集大小為64,那么,需要6個比特的二進制數作為一個基本單元表示一個base64字符集中的字符。因為6個比特有2^6=64種排列組合。
 
  具體來說,編碼過程如下:
 
  將每三個字節作為一組,共24bit,若不足24bit在其后補充0;
  將這24個bit分為4組,每一組6個bit;
  在每組前加00擴展為8個bit,形成4個字節,每個字節表示base64字符集索引;
  擴展后的8bit表示的整數作為索引,對應base64字符集的一個字符,這就是base64編碼值;在處理最后的不足3字節時,缺一個字節索引字節取3個,最后填充一個=,;缺兩個字節取2個索引字節,最后填充==。
  解碼時將過程逆向即可。
 
 
 
 
 
# -*- coding: UTF-8 -*-
import base64
dict={0: 'J', 1: 'K', 2: 'L', 3: 'M', 4: 'N', 5: 'O', 6: 'x', 7: 'y', 8: 'U', 9: 'V', 10: 'z', 11: 'A', 12: 'B', 13: 'C', 14: 'D', 15: 'E', 16: 'F', 17: 'G', 18: 'H', 19: '7', 20: '8', 21: '9', 22: 'P', 23: 'Q', 24: 'I', 25: 'a', 26: 'b', 27: 'c', 28: 'd', 29: 'e', 30: 'f', 31: 'g', 32: 'h',33: 'i', 34: 'j', 35: 'k', 36: 'l', 37: 'm', 38: 'W', 39: 'X', 40: 'Y', 41: 'Z', 42: '0', 43: '1', 44: '2', 45: '3', 46: '4', 47: '5', 48: '6', 49: 'R', 50: 'S', 51: 'T', 52: 'n', 53: 'o', 54: 'p', 55: 'q', 56: 'r', 57: 's', 58: 't', 59: 'u', 60: 'v', 61: 'w', 62: '+', 63: '/', 64: '='}
base64_list = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P','Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f','g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v','w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/']
cipher='FlZNfnF6Qol6e9w17WwQQoGYBQCgIkGTa9w3IQKw'
res=''
for i in range(len(cipher)):
    for j in range(64):
        if(dict[j]==cipher[i]):
            res+=base64_list[j]
print(res)
flag=base64.b64decode(res)
print(flag)
 

 

 
 
在線的python環境可以運行出來:
 
 
 
 
 
 
  BJD{D0_Y0u_kNoW_Th1s_b4se_map} 
 
 
 完成!
 
 
 
 
 
 

參考資料

https://www.soinside.com/question/JpjZizLwHTBaXKVn3ZzM5g
https://www.cnblogs.com/yinsjun/p/6951588.html
https://www.cnblogs.com/hushaojun/p/7552138.html
 
 


免責聲明!

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



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