1
1
using System ;
2
2
using System . Diagnostics ;
3
3
using System . Security . Cryptography ;
4
+ using System . Text ;
4
5
using Mono . Options ;
5
6
6
7
namespace Padding_Oracle_Attack
@@ -9,21 +10,22 @@ class PaddingOracleAttack
9
10
{
10
11
// change the padding used by the oracle below (decryptor uses the same as the server/oracle)
11
12
private const PaddingMode paddingMode = PaddingMode . PKCS7 ;
12
- private static RemoteServerMock server = new RemoteServerMock ( paddingMode ) ;
13
- private static PaddingOracleDecryptor decryptor = new PaddingOracleDecryptor ( server ) ;
13
+ private static RemoteServerMock oracle = new RemoteServerMock ( paddingMode ) ;
14
+ private static PaddingOracleDecryptor decryptor = new PaddingOracleDecryptor ( oracle ) ;
15
+ private static bool removePadding = true ; // can be set to false by HandleConfigurationArguments
14
16
15
17
public static void Main ( String [ ] args )
16
18
{
17
19
Console . WriteLine ( "~~ Padding Oracle Attack Demo ~~" ) ;
18
20
19
21
HandleConfigurationArguments ( args ) ;
20
22
21
- Console . WriteLine ( "Oracle response delay set to {0} ms." , server . OracleDelayMilliseconds ) ;
23
+ Console . WriteLine ( "Oracle response delay set to {0} ms." , oracle . OracleDelayMilliseconds ) ;
22
24
23
25
Console . WriteLine ( "\n Enter plaintext:" ) ;
24
26
string plaintext = Console . ReadLine ( ) ;
25
27
26
- byte [ ] encrypted = server . Encrypt ( plaintext ) ;
28
+ byte [ ] encrypted = oracle . Encrypt ( plaintext ) ;
27
29
var blocks = ByteUtils . SliceIntoBlocks ( encrypted ) ;
28
30
29
31
Console . WriteLine ( "\n Ciphertext blocks (base64):\n {0}" , String . Join ( "\n " , blocks . ConvertAll ( block => Convert . ToBase64String ( block ) ) ) ) ;
@@ -33,15 +35,22 @@ public static void Main(String[] args)
33
35
34
36
var stopwatch = new Stopwatch ( ) ;
35
37
36
- for ( int blockIndex = 1 ; blockIndex < blocks . Count ; ++ blockIndex )
38
+ var lastBlockIndex = blocks . Count - 1 ;
39
+ for ( int blockIndex = 1 ; blockIndex <= lastBlockIndex ; ++ blockIndex )
37
40
{
38
41
stopwatch . Start ( ) ;
39
42
40
- string decryptedPlaintext = decryptor . DecryptBlock ( blocks [ blockIndex ] , blocks [ blockIndex - 1 ] ) ;
43
+ var decrypted = decryptor . DecryptBlock ( blocks [ blockIndex ] , blocks [ blockIndex - 1 ] ) ;
41
44
42
45
stopwatch . Stop ( ) ;
43
46
44
- Console . WriteLine ( decryptedPlaintext [ 0 ] != 16 ? decryptedPlaintext : "(padding-only block)" ) ;
47
+ if ( removePadding && blockIndex == lastBlockIndex )
48
+ {
49
+ decrypted = PaddingUtils . GetPaddingRemoverFromMode ( oracle . Padding ) . Invoke ( decrypted ) ;
50
+ }
51
+
52
+ var decryptedPlaintext = Encoding . UTF8 . GetString ( decrypted , 0 , decrypted . Length ) ;
53
+ Console . WriteLine ( decryptedPlaintext . Length > 0 ? decryptedPlaintext : "(padding-only block)" ) ;
45
54
}
46
55
47
56
var decodedBlocksCount = blocks . Count - 1 ;
@@ -57,7 +66,8 @@ public static void Main(String[] args)
57
66
private static void HandleConfigurationArguments ( String [ ] args )
58
67
{
59
68
OptionSet arguments = new OptionSet ( ) ;
60
- arguments . Add ( "d|delay=" , "oracle delay in milliseconds for each padding request" , ( uint d ) => server . OracleDelayMilliseconds = d ) ;
69
+ arguments . Add ( "d|delay=" , "oracle delay in milliseconds for each padding request" , ( uint d ) => oracle . OracleDelayMilliseconds = d ) ;
70
+ arguments . Add ( "p|preserve-padding" , "don't remove padding from decoded string" , _ => removePadding = false ) ;
61
71
arguments . Add ( "h|help" , "displays this message" , _ =>
62
72
{
63
73
arguments . WriteOptionDescriptions ( Console . Out ) ;
0 commit comments