Symmetric Cryptography means this encryption algorithm use the same key for encryption and decryption. Although I am a web dog, encryption algorithm in some web question recently let me broken heart.
1. Some Symmetric Encryption Algorithm
DES、3DES、TDEA、Blowfish、RC2、RC4、RC5、IDEA、SKIPJACK
Here is another blog for S-DES which i wrote before.
2. Symmetric Cryptography in CTF-WEB
here are some crypto in ctf.which i know most is Padding Oracle or Cbc Flipped Ciphertext Bits. for example CBC in NJCTF or shiyanba easy login question and so on . some i want introduce some Padding Oracle Tricks in ctf_web.
3. Some Encryption mode
Symmetric encryption has two types of encryption modes, namely block encryption and stream encryption.but in AES algorithm has five modes.if you want to find a aes decrypto/encrypto online mabey you need choice which mode you want use. for example
As we can see,we just need block the plaintext.Encryto every piece,than split joint every ciphertext.this is ECB encryption mode.
3.2. Cipher Block Chaining (CBC)
In this mode, the plaintext is first divided into several segments, and then each segment is XOR with the initial block(first segments) or the ciphertext segment of the previous segment, and then encrypted with the key.
Explain this encryption flow chart: • Ciphertext-0 = Encrypt(Plaintext XOR IV)—for first plaintext segment • Ciphertext-N= Encrypt(Plaintext XOR Ciphertext-N-1)—othere plaintext segments Decyption as same.
Purpose of CBC Byte Flipping Attack:To change a byte in the plaintext by corrupting a byte in the ciphertext.
4.1.Working Principle
Note: The Ciphertext-N-1 is used to generate the plaintext of the next block; this is where the byte flipping attack comes into play. If we change one byte of the Ciphertext-N-1 then, by XORing with the net decrypted block, we will get a different plaintext! You got it? Do not worry, we will see a detailed example below. Meanwhile, below is a nice diagram explaining this attack
And this is we know in math
1 2 3 4 5
Now_Plantext(A) = Now_Ciphertext(B) ^ Last_Ciphertext(C) A = B ^ C A ^ A = 0; 0 ^ A = A C = A ^ A ^ C = B ^ C ^ A ^ C = A ^ B ascii('a') ^ C ^ A ^ B = ascii('a') ^ A ^ B ^ A ^ B = ascii('a') ^ 0 = ascii('a')
so if we want let answer become “a”,we just need Last_Ciphertext ^ Now_Plantext ^ Now_Ciphertext ^ "A"
4.2.For example if we can change iv
1 2 3
KEY = 'mHAxsLYz' vi = "qwerasdf" admin->bdmin
This env len(vi==Key),so we just need new_cipher=bytes([ord(chr(cipher[0]))^ord('a')^ord('b')])+cipher[1:]
from pyDes import des, CBC, PAD_PKCS5 import binascii
KEY = 'mHAxsLYz' vi = "qwerasdf" defdes_encrypt(s): secret_key = KEY iv = vi k = des(secret_key, CBC, iv, pad=None, padmode=PAD_PKCS5) en = k.encrypt(s, padmode=PAD_PKCS5) return binascii.b2a_hex(en)
defdes_descrypt(s,iv): secret_key = KEY iv = iv k = des(secret_key, CBC, iv, pad=None, padmode=PAD_PKCS5) de = k.decrypt(binascii.a2b_hex(s), padmode=PAD_PKCS5) return de
if(!isset($_SESSION['id'])) get_identity(); else { is_admin(); if ($_SESSION["isadmin"]){ echo"You are admin!\n"; die($flag); }else echo"You are not admin!\n"; } ?>
''' This server is a modified version of the previous one. This server will send you some data encrypted in CBC mode. You can request decryptions of ciphertexts. The server will tell you if your ciphertext decrypts to something with valid padding, but you won't get the plaintext back. This is one of those obscure crypto implementation details that you can use to completely defeat the cryptosystem. The Secret is in the decrypted ciphertext. Good luck! Ciphertexts are sent back and forth as ASCII Encoded Hex Strings. 0xFF will be sent as "FF" (2 Bytes), not as "\xff" (1 Byte). You can use python's string.encode('hex') and string.decode('hex') to quickly convert between raw data and string representation if you need/want to. Email biernp@rpi.edu with questions/comments :) -Patrick Biernat '''
from twisted.internet import reactor, protocol from Crypto.Cipher import AES import os import random
defvalid_padding(instr): ''' Determine if valid PKCS#7 Padding is present in instr. ''' #Grab the last byte of instr. length = instr[-1] # print length.encode('hex') test = instr[-1 * int(length.encode('hex'),16):] test = test.replace(length,"") if (test != ""): returnFalse returnTrue
defxor_block(first,second): ''' Return a string containing a XOR of bytes in first with second ''' if(len(first) != len(second)): print"Blocks need to be the same length!" return -1
first = list(first) second = list(second) for i inrange(0,len(first)): first[i] = chr(ord(first[i]) ^ ord(second[i])) return''.join(first)
defencrypt_cbc(key,IV, plaintext): ''' High Level Function to encrypt things in AES CBC Mode. 1: Pad plaintext if necessary. 2: Split plaintext into blocks of length <keysize> 3: XOR Block 1 w/ IV 4: Encrypt Blocks, XOR-ing them w/ the previous block. ''' if(len(plaintext) % len(key) != 0): plaintext = pad(plaintext,len(key)) blocks = [plaintext[x:x+len(key)] for x inrange(0,len(plaintext),len(key))] for i inrange(0,len(blocks)): if (i == 0): ctxt = xor_block(blocks[i],"\x00"* 16) ctxt = encrypt_block(key,ctxt) else: tmp = xor_block(blocks[i],ctxt[-1 * (len(key) * 2):].decode('hex')) #len(key) * 2 because ctxt is an ASCII string that we convert to "raw" binary.
ctxt = ctxt + encrypt_block(key,tmp) return ctxt
defdecrypt_cbc(key,IV,ctxt): '''High Level function to decrypt thins in AES CBC mode. 1: Split Ciphertext into blocks of len(Key) 2: Decrypt block. 3: For the first block, xor w/ IV. For the others, xor with last ciphertext block. ''' ctxt = ctxt.decode('hex') if(len(ctxt) % len(key) != 0): print"Invalid Key." return -1 blocks = [ctxt[x:x+len(key)] for x inrange(0,len(ctxt),len(key))] for i inrange(0,len(blocks)): if (i == 0): ptxt = decrypt_block(key,blocks[i]) ptxt = xor_block(ptxt.decode('hex'),IV) else: tmp = decrypt_block(key,blocks[i]) tmp = xor_block(tmp.decode('hex'),blocks[i-1]) ptxt = ptxt + tmp return ptxt
defpadding_check(data): print"DATA:" print data print decrypt_cbc(KEY,IV,data) return valid_padding(decrypt_cbc(KEY,IV,data))
defget_your_ctxt(): ''' This will return the Secret String that you need to decrypt. ''' return encrypt_cbc(KEY,IV,pad(SECRET,len(KEY)))
classMyServer(protocol.Protocol): defdataReceived(self,data): if(len(data) > 512): self.transport.write("Data too long.\n") self.transport.loseConnection() return #Make Profile From "Email" if(data.startswith("get:")): resp = get_your_ctxt() if (resp == -1): self.transport.write("No Cheating!\n") else: self.transport.write(resp)
#Decrypt Ciphertext and "parse" into Profile elif(data.startswith("parse:")): print"PARSING" data = data[6:] if (len(data) % KEYSIZE != 0): print"BAD CIPHERTEXT" self.transport.write("Invalid Ciphertext <length>\n") self.transport.loseConnection() return if(padding_check(data) == True): self.transport.write("VALID PADDING") else: self.transport.write("INVALID PADDING") else: self.transport.write("Syntax Error") self.transport.loseConnection()
defstr2num(s): returnint(s.encode('hex'),16) defnum2str(n): d = ('%x' % n) iflen(d) % 2 == 1: d = '0' + d return d
deffunc(j,z): x = "00" for i inrange(255): y = "parse:"+"00"*j + x + z+"ef2c6db9d0bc134f752a119899160b72" client.send(y) data = client.recv(1024) if data == "VALID PADDING": # print i, hex(i) return i x = int(x, 16) + 1 x = num2str(x)
client.send("get:AAAAAAA") data = client.recv(1024) print data
client.send("parse:f9b6e7556dd0fa9038ac346e849cc5c1ef2c6db9d0bc134f752a119899160b7217a36290f3ed054ca48f1b052578b644") data = client.recv(1024) print data
sum = 16 j = 15 k = 1 tmp = "01"# from 1 to \x10 string_s = "" string_mid = "" z = "" while(sum): confir = num2str(func(j,z)) # print confir string_s = str(confir) #print "string_s:"+string_s #print "string_mid:"+string_mid #print tmp*k string_mid = str(hex(int(string_s,16)^int(tmp,16)))+string_mid
z = str(hex(int(string_mid,16)^int(tmp*k,16))) z = z[2:].replace('L','') if temp == len(str(hex(int(string_mid,16)^int(tmp*k,16)))): z = "00" + z iflen(z)%2 !=0: z = "0"+z #print "z:"+z j = j-1 k = k+1 sum = sum-1 #func(j,z)