Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Password Protection Using a dynamic keyboard


  • Please log in to reply
13 replies to this topic
1991
  • Members
  • 29 posts
  • Last active: Jun 04 2007 03:05 AM
  • Joined: 20 Jan 2006
I came up with a problem. Situation:You have a computer with a touch screen monitor, (or a regular computer with keyloggers) and want to enter information without it being found physically or in the computer, what do you do?

Problem solved. (Except if you have the NSA after you.)

On an online game they implement a similar, but much waeker method to protect your pin.


The Effect:
1. You lock your computer using the ahk code
2. You wake your computer
3. A 4x4 array of buttons pop up (or symbols)
4. The program takes a few milliseconds to scrample the board, putting the numbers in random spots.
5. Four times a second, a random character is selected and moved to a new spot.

For someone to effectively to hack this, a hacker must do one of the following:
1. get in to your system memory, search the whole ram for your password. (Password changing helps hackers here, and AutoHotkey isn't very effecive at hiding values in the memory)

2. take a picture of your screen twice a second, time each mouse click/release and location, store matches and somehow do this without freezing your computer or having a video camera in plain sight.

If someone were to find a way to encrypt each keystroke, they'd be awesome.

Below here Ill post each version leading up to the one described above.

1991
  • Members
  • 29 posts
  • Last active: Jun 04 2007 03:05 AM
  • Joined: 20 Jan 2006
>Outdated version<

1991
  • Members
  • 29 posts
  • Last active: Jun 04 2007 03:05 AM
  • Joined: 20 Jan 2006
Page simplification in process...
I made a mistke posting eash version, Sorry moderators

1991
  • Members
  • 29 posts
  • Last active: Jun 04 2007 03:05 AM
  • Joined: 20 Jan 2006
Code Below

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
Nice idea!

You could simplify the code a little, though. Below is a version of your first script, which is easier to use. At first, after the keypad is shown, 16 random pairs of key names are swapped. When the user presses a button, it is stored, and the keys are randomized again.

If you use a CRT monitor, detecting the EM radiation allows the screen content to be reconstructed in real time (with the mouse pointer), even on the other side of a wall. In this case fast changing keys don't help, but finding the one you need to press next is a challenge. Flat panel displays are not known to be vulnerable to this kind of side channel leakage, so only when you have one, trust this key entry. (If you want continuously changing key names, let the loop run infinitely, with Sleep 500 in it, and make the xx: subroutine only store the key: "o = %o%%A_GuiControl%".)

Another little improvement could be to hash the digits as they arrive, and only store the hash value (to be compared to the hash of the password et the end). Occasional memory inspections leak less. However, if an attacker is able to see the memory periodically, he might as well patch the code in memory to accept any password as valid, so we gain not much. To prevent that we need a background code integrity check, memory protection, etc. They can only be done reliably with extra HW. One component of this is the TPM chip found in many new laptops.
SetFormat Integer, HEX        ; for hex keypad
Loop 16 {
   i := A_Index - 1
   StringReplace j,i,0x
   Gui Add, Button, % "x" 8+(i&3)*40 " y" 7 + (i>>2)*40 " w30 h30 gxx", %j%
}
Gui Add, Button, x8  y167 w70 h30, ENTER
Gui Add, Button, x88 y167 w70 h30, CLEAR
Gui Show, h204 w166, pwd

xx:
   o = %o%%A_GuiControl%      ; store selected digit
   Loop 16 {
      i := A_Index - 1
      Random j, 0, 15         ; random hex digit = keypad key
      StringReplace i, i, 0x
      StringReplace j, j, 0x
      GuiControl,,%i%,x
      GuiControl,,%j%,%i%     ; swap key names i and j
      GuiControl,,x,%j%
   }
Return

ButtonClear:
   o =
Return

ButtonEnter:
   MsgBox %o%                 ; <-- add here code to process the password
GuiEscape:
GuiClose:
   Gui Destroy
ExitApp


1991
  • Members
  • 29 posts
  • Last active: Jun 04 2007 03:05 AM
  • Joined: 20 Jan 2006
Nice simplification, Laszlo.

Im going to put many different types of my code online in one final master version beacuse of simple differences in opinion which I dont want to argue.

http://stokes91.goog....com/autohotkey

Please feel free to post updates to a code to make it smaller, simpler, or better.

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005

differences in opinion which I dont want to argue

Why not? We may all learn something from arguments. Btw, if you like short code, you could save a few more lines. This version handles any number of keys, like the whole alphabet:
keys = 0123456789ABCDEFGHIJKLMNOP

Loop Parse, keys

   Gui Add,Button,% "x" 8+Mod(A_Index-1,4)*40 " y" 7+(A_Index-1)//4*40 " h30 w30 gxx",%A_LoopField%

Gui Add, Button, x8 w70 h30, ENTER

Gui Add, Button, x88 yp wp hp, CLEAR

Gui Show,,pwd



xx:

   o = %o%%A_GuiControl%      ; store selected key

   Loop Parse, keys

   {

      Random r,1,StrLen(keys) ; random keypad key

      StringMid r, keys, r, 1

      GuiControl,,%A_LoopField%,x

      GuiControl,,%r%,%A_LoopField%

      GuiControl,,x,%r%       ; swap key names

   }

Return



ButtonClear:

   o =

Return



ButtonEnter:

   MsgBox %o%                 ; <-- add here code to process the password

GuiEscape:

GuiClose:

   Gui Destroy

ExitApp


1991 - not logged in
  • Guests
  • Last active:
  • Joined: --
Oh, I just think that having the numbers change would make it more secure because there's a way to easily steal the passwords.

heres a text version: (not code)

wait until password dialog opens.
loop until window is closed:
wait for 200milliseconds -for board to scramble
take a screenshot, save to file
wait until mouse click
save coordinates pressed in file
process image and extract key pressed

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
Good point! This attack can be programmed in AHK, but needs a little improvement, because you cannot save a screenshot to a file 5 times a second. You probably want to capture just the keypad image, and save it only if it has changed.

On the other hand, the attacker can trigger a hotkey at mouse clicks (~LButton), in the keypad window. It is easy to get the screen pixels around the pointer, even the text of the active control, so the password can be directly sniffed. It does not help, if the button texts change constantly.

For improved security we have to hide the keypad window from the attacker. How about giving it a name and class of existing windows, like the Program Manager? (The attacker can still find our keypad, because he can save the ID of the real program manager, and compares this with the ID's of other similarly named windows.) We can do random clicks all over the keypad, so fast that the user is not disturbed, and the password sniffer is overwhelmed with the large number of fake clicks? (The sniffer could distinguish between physical and generated clicks, unless we do it in the device driver level). We need more ideas!

1991
  • Members
  • 29 posts
  • Last active: Jun 04 2007 03:05 AM
  • Joined: 20 Jan 2006
wow. You gave a lot to reply to. ill try to respond.

This attack can be programmed in AHK, but needs a little improvement, because you cannot save a screenshot to a file 5 times a second.


Nor can the average user enter numbers. :wink:

Note: I put "wait until mouse click" to stop that from happening.

--

Good ideas abot the naming, yet wouldn't windows have a problem with me naming the window something like "Windows Task Manager"? I might be wrong, but I'm not too excited about going to court at age 14.

--

Oh, maybe I could put in a code that checks for other open programs and tells the user of the potential problem ex:
[inside a msgbox]

Enigma has detected you have 3 open program(s).
Their process names are:
MSWORD.EXE
firefox.exe
PWsniffr.exe
Please terminate theese programs before reloading Enigma.
Once theese are closed, you can add/allow safe programs.
[OK]


Because windows has many processes that are valid, It could be possible to make a hashed safe list, that a user could see and edit from a settings window, sort of like Windows firewall.

But, how would you stop a malicious program from adding itself to the safe list? Aha! I could not modify the settings because it would be stopped by the above dialog! (Unless if it were to use the same name or something)

Another fix! Somehow find how much disk space the exe has or some of its properties. And make sure there is only one file with that name (using a periodic search of the hd) - would be difficult and time consuming, so maybe find a way to get the exact location of a running exe.

so for a hacker to get in they might need to make a file named firefox.exe with a size of 6.84mb and also remove or replace the old one!

a good solution?
--
english version of hypothetical code:

get all names of running proccesses
hash names and check angainst goodexes.txt
(if possible)get locations of running processes
hash full paths and check anginst goodpaths.txt
(again if possible)get file sizes
hash, check if hash is included in a file
if there are files that do not match a hash,
alert user
close program

--

{update}
Thanks Laszlo for the great simplification of my gui, It made it possible for me to put 3 different layouts (10[numeric] 16[hex] 36[alpha numeric]) all into ~40 lines.

Gui- COMPLETE
changing methods- ALMOST
Settings mgr- NOT STARTED
Hacker/Spyware detection- NOT STARTED- more ideas?

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005

Nor can the average user enter numbers

This was the reason I suggested to freeze the keypad after a shuffle. Otherwise, when I find the next digit to be entered, it moves, what drives me crazy. And making a screenshot at a mouse click defeats the constant shuffling, so why bother?

There are different ways to proceed. We can try to hide our password entry keypad from a possible sniffer, or we can try to catch it in action. For hiding:

wouldn't windows have a problem with me naming the window something like "Windows Task Manager"?

Most of these window titles are not trademarked. E.g. "Program Manager" is safe, like "ahk_class Progman". However, you have a good point with the process name: the sniffer can find the name and size of the executable having opened the keypad window, so it has to be named accordingly. The size of the executable is easy to be adjusted (append some junk).

The location of the executable still blows our cover. It gets complicated:
- Rename the Windows program manager to something else
- Copy the keypad program to the Windows directory, named progman.exe
- Execute it
- Rename the keypad program
- Give the Windows program manager its original name back.

Renaming running programs might not be easy, but we hid our keypad a little better.

Another alternative to think about is to generate a random window name and the filename of the executable of the keypad function, with setting the file creation time to a fake random date in the past. The sniffer will not know, what to look for.

However, if the sniffer monitors disk activities, both of these methods can be broken. Freshly created new files and new windows appearing soon after, tell tale.

Without hardware support all what we can hope for is making life harder for the bad guys.

I am not sure I understand your points about the safe list. Do you want the password entry program to check if a password sniffer is running and scream if an unknown process is found?

But, how would you stop a malicious program from adding itself to the safe list?

Use digital signatures. To be secure, we need a TPM chip on the motherboard (or some other HW).

There are many processes running. In my laptop Task Manager reports 77 of them. I have no idea what most of them do. But we can still create a task monitor, and pop up a warning, when an unknown task appears. At this point the user can allow it to run this time only, add to the safe list or terminate it. Writing this is a lot of work. Do you want to give it a try?

If we can control what is executed, we still miss buffer over-runs, when, for example, a too long email subject line overwrites some executable part of an email program. It is on the safe list, but does now really bad things. There are similar other vulnerabilities, like pictures containing code (meant for image rendering, but misused as virus), Word documents containing malicious macros, etc. When they get executed no new process is started (the browser showing the picture or the macro interpreter of Word are already allowed to run). We can find many of these suspicious programs, but it is an arms race: the bad guys constantly figure new ways to smuggle in malicious code to my PC.

1991
  • Members
  • 29 posts
  • Last active: Jun 04 2007 03:05 AM
  • Joined: 20 Jan 2006

I am not sure I understand your points about the safe list. Do you want the password entry program to check if a password sniffer is running and scream if an unknown process is found?


sorry if I was vague but, basically it would do an initial check (first run- after installation) of all processes running and ask the user which ones are safe to be open during password entry, (just in case if Eve's programs are running). Once a list is made of running process properties (static ex. name, location, size, modification?, created?, makers), the list is hashed a bit, and put into a text document.

Any loads after that (during password entry or setting modification) , the code will check the processes again hash and compare to the older hash.

What if Eve's process gained control of Bob's computer? Would it be safe?
Maybe. Eve would need to find a way to let Bob open the code without the her unapproved process apperaring open. Many ways to do this, but the easiest would be as you said in a different direction, change the names and size.

Btw, that might be useful for a moderate hacker. And unbreakable to a new hacker who doesnt know the limits of non-hardware upgraded computers. (They might not know how it [their software] is found.)

Preliminary Code:
gosub,GetProcessInfo
msgbox,%allnames%
return

GetProcessInfo:
	allnames=
	DllCall( "advapi32.dll\LookupPrivilegeValueA", "uint", 0, "str", "SeDebugPrivilege", "int64*", luid_SeDebugPrivilege )
	Process, Exist
	pid_this := ErrorLevel
	DllCall( "OpenProcess", "uint", 0x400, "int", false, "uint", pid_this )
	DllCall( "advapi32.dll\OpenProcessToken", "uint", hp_this, "uint", 0x20, "uint*", ht_this )
	VarSetCapacity( token_info, 4+( 8+4 ), 0 )
	EncodeInteger( 1, 4, &token_info, 0 )
	EncodeInteger( luid_SeDebugPrivilege, 8, &token_info, 4 )
	EncodeInteger( 2, 4, &token_info, 12 )
	DllCall( "advapi32.dll\AdjustTokenPrivileges", "uint", ht_this, "int", false, "uint", &token_info, "uint", 0, "uint", 0, "uint", 0 )
	if A_OSVersion in WIN_95,WIN_98,WIN_ME
	{
		MsgBox, This Windows version (%A_OSVersion%) is not supported.
	}
	pid_list_size := 4*1000
	VarSetCapacity( pid_list, pid_list_size )
	status := DllCall( "psapi.dll\EnumProcesses", "uint", &pid_list, "uint", pid_list_size, "uint*", pid_list_actual )
	;if ( ErrorLevel or !status )
	;	return
	total := pid_list_actual//4
	r_pid_list=
	address := &pid_list
	loop, %total%
	{
		p_pid := ( *( address )+( *( address+1 ) << 8 )+( *( address+2 ) << 16 )+( *( address+3 ) << 24 ) )
		h_process := DllCall( "OpenProcess", "uint", 0x10|0x400, "int", false, "uint", p_pid )
		name_size = 255
		VarSetCapacity( name, name_size )
		result := DllCall( "psapi.dll\GetModuleFileNameExA", "uint", h_process, "uint", 0, "str", name, "uint", name_size )
		DllCall( "CloseHandle", h_process )
		if name !=
			allnames=%allnames%`n%name%
		address += 4
	}
	DllCall( "CloseHandle", "uint", ht_this )
	DllCall( "CloseHandle", "uint", hp_this )
return

EncodeInteger( p_value, p_size, p_address, p_offset )
{
	loop, %p_size%
	DllCall( "RtlFillMemory", "uint", p_address+p_offset+A_Index-1, "uint", 1, "uchar", p_value >> ( 8*( A_Index-1 ) ) )
}

Try and see if you can get a program to hide from this program, *yawn* its 2:00 (night) right now, but ill keep trying different methods.

I found this code on this forum somewhere, and I tried simplifiying it, but you might have better luck.

And making a screenshot at a mouse click defeats the constant shuffling, so why bother?

I found this problem too, so therefore im trying to make sure the processes open are 'clean' and won't pose a threat.

EDIT: Oh I see, what you mean, good question. Ill fix that now. (by making the buttons blank during a click\hover and until (maybe) the shuffling is done.) (don't be scared, I'm making it customizable per person/machine so you could choose to not have the numbers hide or shuffle during entry.

(ONE PROBLEM: What if a program is opened by the user or a 'approved' process?)[Make a periodic check after shuffling?]

EDIT:Another true statement Laszlo, (about the macros and coded imgs), but here I'd hope to trust the user into not allowing email clients, browsers, etc. open.

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005

an initial check (first run- after installation) of all processes running and ask the user which ones are safe to be open during password entry

I see. There are difficulties with this, though.
- Macro interpreters, like VB, AHK, even MS Office must not be active, because they take text files (scripts), and execute them. The process name does not tell, what code they run. It is too much to ask: "please close all instances of these dangerous processes". It takes minutes, so users will just ignore your request.
- I cannot tell which of the 77 active processes are safe in my laptop. Most users would not be able to select the bad ones.
- Many viruses, worms attach themselves to safe looking processes. If they were already infected when you created the safe list, you might allow them to do harm. This is the typical case: an infection occurs once, and from then on, all your passwords could be sniffed.
- With root-kits or similar tools, malware can be hidden. The user does not know if anything suspicious is running already.

Because of these, I would rely on antivirus programs, instead. They do a pretty good job finding malware. However, a custom made sniffer, distributed in a local area network, will not be detected, so it still makes sense to protect yourself from your colleagues (or the IT guys at your work/school).

making the buttons blank during a click\hover

This is a good idea, maybe with random shuffled keys shown (the user has to remember the last "real" key names when he clicks, and ignoring the ones on screen). If the sniffer makes a screenshot at a mouse click, it will not see anything useful, and an attack becomes much harder. Accordingly, how about this:

- The keypad keys are continuously changing at random time intervals.
- The user waits a little, and picks the key with the next password digit (in his mind).
- He starts moving his mouse toward that keypad key. At this moment the script memorizes the current key names, change them on screen (and might keep them changing).
- The user ignores the new key names, knowing that while the mouse is moving the changes are only fake. He clicks on the keypad key he picked before he started to move the mouse.
- The script saves the memorized key name as the next password digit.

If these are combined with randomized process names, the sniffer has to make screenshots very frequently, always while the mouse is stationary. At a mouse click, it uses the last saved key names to discover the password, but the identification of the right window is also complicated (need to use the number of controls, their position, etc). This is a lot of work, and there is a chance that the increased processor load reveals the presence of the password sniffer.

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
Here is a password entry keypad script, for testing. It shuffles the key names in every 5 seconds. When the user sees the key to be entered next, he moves the mouse there to click. The mouse movement is detected by the Windows massage WM_MOUSEMOVE. If the previous message was shortly before, the mouse is assumed to be on the move, so we don't do anything. If there was no mouse move event for a long time, we save the current key names, and re-shuffle them. When the user clicks on a button he picked before starting to move the mouse, the previously saved key name is used for the password (not the currently shown one).

This is not a finished script, it is only for experimenting:
- The mouse should not leave the current window, because its movement outside is not detected.
- If the user leaves the mouse on a button, and clicks again, he gets the last saved key name, not the one shown, unless the mouse moves slightly.
keys = 12345678*90#
Loop Parse, keys
   Gui Add,Button,% "x" 8+Mod(A_Index-1,4)*40 " y" 7+(A_Index-1)//4*40 " h30 w30 gxx",%A_LoopField%
Gui Add, Button, x8 w70 h30, ENTER
Gui Add, Button, x88 yp wp hp, CLEAR
Gui Show,,pwd

T1 = 0xFFFFFFFF               ; 1st mouse move to be detected
OnMessage(0x200,"Mouse")      ; react to 0x200 = WM_MOUSEMOVE
SetTimer Shuffle, 5000        ; start key shuffling
GoSub Shuffle                 ; shuffle now
MouseMove 85,120              ; mouse into GUI window

RETURN                        ; end of autoexecute section

Shuffle:                      ; assign random names to buttons
   Loop Parse, keys
   {
      Random r,1,StrLen(keys) ; random keypad key
      StringMid r, keys, r, 1
      GuiControl,,%A_LoopField%,zz
      GuiControl,,%r%,%A_LoopField%
      GuiControl,,zz,%r%      ; swap key names
   }
Return

Mouse() {                     ; called at mouse move within GUI
   Global
   T0:= T1 + 499
   T1 = %A_TickCount%
   IfLess T1,%T0%, Return     ; return if mouse is moving
   SetTimer Shuffle, OFF
   Loop % StrLen(keys)        ; save keynames
      GuiControlGet Button%A_Index%,,Button%A_Index%
   GoSub Shuffle              ; shuffle now
   SetTimer Shuffle, ON       ; restart shuffling
}

xx:
   GuiControlGet x, Focus     ; class of GuiControl (Button1, 2..)
   x := %x%                   ; get saved keyname
   o = %o%%x%                 ; store selected key
Return

ButtonClear:
   o =
Return

ButtonEnter:
   MsgBox %o%                 ; <-- add here code to process the password
GuiEscape:
GuiClose:
   Gui Destroy
ExitApp