summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2014-11-30 01:55:46 -0800
committeriximeow <me@iximeow.net>2014-11-30 01:55:46 -0800
commit077b1df51f501ed44c7e9a421301174ac7efeaeb (patch)
tree79be5741f65fc94edded677bae7d272a481f3034
parent01515fe2c82fb0b05a17bd792f4e45b88f31f235 (diff)
Progress! last block still improperly reversed.
-rw-r--r--src/utils/CryptoUtils.scala77
1 files changed, 66 insertions, 11 deletions
diff --git a/src/utils/CryptoUtils.scala b/src/utils/CryptoUtils.scala
index fc33220..6fe6b19 100644
--- a/src/utils/CryptoUtils.scala
+++ b/src/utils/CryptoUtils.scala
@@ -59,6 +59,8 @@ object CryptoUtils {
def extractUnknownViaEcbOracle(encrypt: Seq[Byte] => Seq[Byte]) = {
val blockSize = detectEcbBlockSize(encrypt)
+ def blocksIn(xs: Seq[Byte]) = xs.length / blockSize
+ val baseBlockCount = blocksIn(encrypt(Seq()))
def rainbow(prefix: Seq[Byte]): Map[Seq[Byte], Byte] = {
(0 to 255)
@@ -71,6 +73,17 @@ object CryptoUtils {
.toMap
}
+ def postfixRainbow(prefix: Seq[Byte]): Map[Seq[Byte], Byte] = {
+ (0 to 255)
+ .map(_.toByte)
+ .map(_ +: prefix)
+ .map(encrypt)
+ .map(_.take(16).toSeq)
+ .zipWithIndex
+ .map(_ :-> { _.toByte } )
+ .toMap
+ }
+
def probeFirstBlockAndPaddings: (Seq[Byte], Map[Int, Seq[Byte]]) = {
def prefix(known: Seq[Byte]) = (" " * (blockSize - 1 - known.length)).asBytes
def genRainbow(known: Seq[Byte]) = rainbow(prefix(known) ++ known)
@@ -82,18 +95,19 @@ object CryptoUtils {
}
def probeLastBlockSize: Int = {
- val baseBlockCount = encrypt(Seq[Byte]()).length
val firstLargerCiphertext = (0 until blockSize)
.map(" " * _).map(_.asBytes).map(encrypt)
.zipWithIndex
- .find(_._1.length != baseBlockCount)
+ .find(x => blocksIn(x._1) != baseBlockCount)
// this will always be Some(_) because
// somewhere between 0..blockSize WILL grow the text.
firstLargerCiphertext.get._2
}
- println("Last block is " + probeLastBlockSize + " bytes")
+ val lastBlockSize = probeLastBlockSize
+
+ println("Last block is " + lastBlockSize + " bytes")
val (firstBlock, ciphertexts) = probeFirstBlockAndPaddings
/*
@@ -102,19 +116,45 @@ object CryptoUtils {
* rot0b1, rot1b1, rot2b1, ...
*
*/
- val transposed = ciphertexts.toSeq.sortBy(_._1).map(_ :-> { x =>
- val y = x.grouped(16).toSeq
- println(y.length)
- y
+ val cipherBlocks: Seq[(Int, Seq[Seq[Byte]])] = ciphertexts.toSeq.sortBy(_._1).map(_ :-> { x =>
+ x.grouped(16).toSeq
})
+ val (middleBlocks, lastBlocks) =
+ cipherBlocks.foldLeft((Seq[Seq[Seq[Byte]]](), Seq[Option[Seq[Byte]]]()))( (ac, curr) => {
+ val maybeLastBlock =
+ if (curr._2.length > baseBlockCount) Some(curr._2.last)
+ else None
+
+ val middleBlocks = curr._2.take(baseBlockCount).tail
+
+ (ac._1 :+ middleBlocks, ac._2 :+ maybeLastBlock)
+ }) :-> { _.flatten }
+
+ println(lastBlocks.mkString("\n"))
+
+ def breakLastBlock(blocks: Seq[Seq[Byte]]) = {
+ /*
+ * plaintext looks something like...
+ * X 15 15 15 15 15 ... 15
+ * Y X 14 14 14 14 ... 14
+ * ... pkcs7
+ */
+ blocks.foldLeft(Seq[Byte]()) { (bytes, block) => {
+ val postfix = pkcs7pad("?".asBytes ++ bytes, blockSize).tail
+ val b = postfixRainbow(postfix)(block)
+ println("Got " + b)
+ bytes :+ b
+ }}
+ }
+ // val lastBlockBytes = crackLastBlock(lastBlocks)
// println("Also...")
-// println(rainbow(firstBlock.tail)(transposed(1)(0)))
+// println(rainbow(firstBlock.tail)(middleBlocks(1)(0)))
val prefix = firstBlock.tail
val currRainbow = rainbow(prefix)
- println(ciphertexts(0).drop(16).take(16))
- val next = currRainbow(ciphertexts(0).drop(16).take(16).toSeq)
+ println(middleBlocks(0)(0))//ciphertexts(0).drop(16).take(16))
+ val next = currRainbow(middleBlocks(0)(0))
println("Next: " + new String(Array(next.toByte)))
val nowPrefix = (prefix.tail :+ next)
val r2 = rainbow(nowPrefix)
@@ -125,7 +165,22 @@ object CryptoUtils {
val next3 = r3(ciphertexts(2).drop(16).take(16).toSeq)
println("Next: " + new String(Array(next3.toByte)))
- firstBlock
+ def breakBlock(plaintext: Seq[Byte], padded: Seq[Seq[Byte]]): Seq[Byte] =
+ padded.foldLeft(Seq[Byte]()) { (blockText: Seq[Byte], block: Seq[Byte]) => {
+ val prefix = (plaintext ++ blockText).takeRight(blockSize - 1)
+ val b = rainbow(prefix)(block)
+ blockText :+ b
+ }}
+
+ val middleBytes =
+ middleBlocks.transpose.init.foldLeft(firstBlock) { (plaintext, padded: Seq[Seq[Byte]]) =>
+ println("Block " + padded(0))
+ val bytes = breakBlock(plaintext, padded)
+ println(".... Done!")
+ plaintext ++ bytes
+ }
+
+ middleBytes ++ breakLastBlock(lastBlocks)
}
}