iT邦幫忙

0

資安學習路上-picoCTF 解題(crypto)1

Cryptography

1. rot 13(rotate by 13 places)

  • 英文網路論壇用作隐藏八卦(spoiler)、妙句、谜题解答以及某些髒話的工具,目的是逃過版主或管理员的匆匆一瞥,也是過去在古羅馬開發的凱撒加密的一種變體。
  • 套用ROT13到一段文字上僅僅只需要檢查字元字母順序並取代它在13位之後的對應字母,有需要超過時則重新繞回26英文字母開 頭即可。
  • 對任何字元x:ROT13(ROT13(x))=ROT26(x)=x。
  • 兩個連續的ROT13應用函式會回復原始文字(在數學上,這有時稱之為對合(involution);在密碼學上,這叫做對等加密(reciprocalcipher)

2. Easy Peasy

這類題目通常可以會給一個網頁連結(可用nc連線)跟伺服器的原始碼,主要就是要根據原始碼去找答案

one-time pad 一次性密碼本,只用一次就丟換另一組密碼

netcat後得到訊息如下:

程式碼如后:

#!/usr/bin/python3 -u
import os.path

KEY_FILE = "key"
KEY_LEN = 50000
FLAG_FILE = "flag"


def startup(key_location):
	flag = open(FLAG_FILE).read()
	kf = open(KEY_FILE, "rb").read()

	start = key_location
	stop = key_location + len(flag)

	key = kf[start:stop]
	key_location = stop

	result = list(map(lambda p, k: "{:02x}".format(ord(p) ^ k), flag, key)) 
	#將flag跟key,分別取代p,k後,做XOR,再存成list
	print("This is the encrypted flag!\n{}\n".format("".join(result))) 		
	#把加密後的key吐出來

	return key_location

def encrypt(key_location):
	ui = input("What data would you like to encrypt? ").rstrip()
	if len(ui) == 0 or len(ui) > KEY_LEN:    
	#當輸入字串長度為0(沒輸入),或者長度大於5000,結束並return -1
		return -1  							

	start = key_location
	stop = key_location + len(ui)

	kf = open(KEY_FILE, "rb").read()

	if stop >= KEY_LEN:
		stop = stop % KEY_LEN			
		#如果輸入的字串長度超過KEY_LEN(50000),會重頭開始運算
		key = kf[start:] + kf[:stop]
	else:
		key = kf[start:stop]
	key_location = stop

	result = list(map(lambda p, k: "{:02x}".format(ord(p) ^ k), ui, key)) #獎輸入ui跟key在做XOR

	print("Here ya go!\n{}\n".format("".join(result)))

	return key_location


print("******************Welcome to our OTP implementation!******************")
c = startup(0)

while c >= 0:
	c = encrypt(c)

這題是會把輸入字串進行跟key做XOR運算,可直行很多次,會一直累積,當長度超過50000時,會重複執行,寫程式執行

from pwn import *

r = remote("mercury.picoctf.net", 41934) #創一個connection
r.recvline()  #從connection接收一行指令
r.recvline()
flag_enc = bytes.fromhex(r.recvline().decode()) 
#接收下來的bytes 變 str後,這邊收到十六進位制值引數
#'0345376e1e5406691d5c076c4050046e4000036a1a005c6b1904531d3941055d\n'
#再用bytes.fromhex把16進位引述數轉成位元組字串,變下面這樣
# b'\x03E7n\x1eT\x06i\x1d\\\x07l@P\x04n@\x00\x03j\x1a\x00\\k\x19\x04S\x1d9A\x05]'
fl = len(flag_enc)

def enc(m):
    r.recvline()
    r.sendline(m.encode())
    r.recvline()								  #從tube一次接收一行
    return bytes.fromhex(r.recvline().decode())   #返回位元組字串


enc("a" * (50000 - fl))  #將字元a乘以多次
keyxor = enc("a" * fl)

def xor(x, y):
    return bytes(a ^ b for a, b in zip(x, y))

key = xor(keyxor, b"a" * fl)
flag = xor(flag_enc, key)
print(flag.decode())


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言