Home > Articles > Home & Office Computing > Microsoft Windows Desktop

Like this article? We recommend

Three Illustrations

The following examples illustrate the process that Airscanner goes through when examining a program for vulnerabilities:

  • The first example demonstrates how a password can be pulled out of a device’s memory in plain text.
  • The second example shows how a debugger can be used to bypass the password verification routine.
  • The final example explains how a password program can secure the information correctly, but ironically be used by an attacker to crack the password.

Picking the Password Out of iPassword

iPassword is a program sold as a digital locker for Windows Mobile devices. Here’s how the Creative Iye website describes its product: "iPassword is an easy to learn, simple to use password protector. It uses a strong custom encryption routine to prevent the unwanted eyes from prying. iPassword was designed to keep a variety of data, such as passwords, credit card info, bank account info, email accounts, IP addresses, PINs, TANs, and other confidential data safely and securely in a well-organized form."

Once the program has been installed and its master password is set, the user is prompted for a password each time the program is executed. Assuming that the correct password is provided, the screen shown in Figure 1 lists all the items that are protected by "128-bit encryption."

Figure 1

Figure 1 iPassword’s Master Password window.

Every program written in C++ uses a common set of functions that are stored in a core operating system file (coredll.dll for Windows Mobile). As a result, it’s fairly easy to guess what functions are probably being called to perform some action. In the case of iPassword’s password entry, we know that the info entered into the text box has to be passed to the program. Since IDA provides us with a list of all the functions called in the program, it’s fairly simple to scan that list, looking for good candidates. One of these is GetDlgItemTextW, which is used to retrieve text from a dialog box, such as the one used by iPassword (see Figure 2).

Figure 2

Figure 2 Function listing in IDA.

To test this theory, we double-click the function name, which prompts IDA to take us to the place where that function exists in the program. The function is actually in a file called coredll.dll, and this piece of code just directs the processor to the memory address of that function. Regardless, we can place a breakpoint here, which tells IDA to stop the code execution if it detects the processor attempting to execute code at the breakpoint’s address. In IDA, this is done by pressing the F2 button.

Next, we need to configure IDA to connect to the executable on the device (Debugger/Process Options), after which we can hit the F9 button. After a few seconds, the iPassword Master Password window (the one shown earlier, in Figure 1) appears on our PDA screen.

To see if GetDlgItemTextW is used, we enter a random value and click OK. As we guessed, iPassword retrieves the data from the box, using GetDlgItemTextW. This action causes the processor to access the code at the breakpoint’s address, which makes IDA pause the program.

Now we have to figure out at what point the function was called in the program. Since iPassword uses GetDlgItemTextW numerous times as it retrieves credit card information, PINs, etc. from the user, we have to work backward from the breakpoint. Fortunately, this is fairly easy.

When a subroutine is called, the processor has to be able to know where to continue after the subroutine is finished. This is accomplished by placing the return address onto the stack and storing it in memory. However, we’ve stopped the program just before it jumps into the subroutine, which means that the return address is stored in the processor’s registers (temporary storage locations in the processor). In fact, it’s stored in the link register (LR). If we right-click this register and select the "Jump in a new window" option (see Figure 3), we’ll be taken to the address of the program where this subroutine will be returning. Once here, we move the cursor down to address 0x00019C84 (the address directly after the GetDlgItemTextW function call) and press F4 , which causes IDA to execute until it hits the address under the mouse.

Figure 3

Figure 3 Using Link Register to locate the function’s return address.

Typically, immediately after a password is pulled in from a user, it will be verified against the stored password. The methods vary, but most programs either verify the password several lines down in the code, or push the verification out to its own subroutine. In this case, the verification occurs between address 0x19C98 and address 0x19CC0.

While watching the code execute, we realized that the opcode at 0x00019C84 loaded the memory address of the unencrypted password that’s stored in memory. As a result, we let this line execute, right-clicked register R4, and selected "Jump in a new window" to view this value. As Figure 4 illustrates, it’s really quite easy to pull the valid password right out of the device’s memory.

Figure 4

Figure 4 The valid password stored in memory.

The code also holds a few other security risks. Let’s look at the code directly following the GetDlgItemTextW function:

00019C80 BL   GetDlgItemTextW     ;Get entered password and store in memory
00019C84 LDR   R4, =unk_441BC      ;Set R4 equal to address of valid password
00019C88 ADD   R0, SP, #0x114+var_E4  ;Set R0 equal to address of encrypted pass
00019C8C MOV   R1, R4          ;Set R1 equal to address of valid password
00019C90 BL   sub_1113C        ;Decrypt encrypted password ??
00019C94 SUB   R2, R4, R5        ;Subtract value of R5 from R4

00019C98 loc_19C98
00019C98 LDRH  R0, [R2,R5]       ;Load character of real password
00019C9C MOV   R6, #1          ;Set R6 to 1 (counter)
00019CA0 MOV   R1, R0,LSL#16      ;Perform a shift
00019CA4 LDRH  R0, [R5],#2       ;Load character of entered password
00019CA8 MOV   R3, R1,LSR#16      ;Perform a shift
00019CAC MOV   R1, R0,LSL#16      ;Perform a shift
00019CB0 MOV   R0, R1,LSR#16      ;Perform a shift
00019CB4 CMP   R3, R0          ;Compare the two characters
00019CB8 BNE   loc_19CCC        ;Branch out if not equal
00019CBC CMP   R3, #0          ;Check for end of password
00019CC0 BNE   loc_19C98        ;Branch to 19C98 if more characters
00019CC4 MOV   R1, R9          ;Move R9 to R1
00019CC8 B    loc_19CD8        ;Jump to open program

You might not be an ARM assembly language master, but you should get the idea from reading this code. The real password is compared to the entered password character-by-character. If the characters match, good—if not, the processor is told to jump to another part of the program.

There are a few other important security issues to note:

  • The subroutine at address 0x00019C90 that decrypts the stored real encrypted password is very simple to emulate. If the device’s registry can be read by someone, the stored password could easily be decrypted by hand.
  • If the password is deleted from the registry, iPassword simply opens and decrypts the contents of the "secure" file, without any password.
  • You can use IDA to jump over the verification routine, and the "encrypted" file opens right up.

And now, the most disconcerting problem: The software supposedly uses 128-bit encryption to protect your data—but we’re not convinced. At this point, we know that there’s no link between the password and the encrypted data. Otherwise, any attempt at jumping over the password verification routine would result in corrupted output. So if the password isn’t used to encrypt the data, what is? Well, the function that’s used to decrypt this password:

(00019C90 BL   sub_1113C)

is the same function used to decrypt the data in the database. In fact, here’s that code:

00011198        LDRH  R0, [R3,R4]
0001119C        SUB   R6, R6, #1
000111A0        CMP   R6, #0
000111A4        MOV   R1, R0,LSL#16
000111A8        RSB   R2, R5, R1,LSR#16  <- 128-bit encryption???
000111AC        MOV   R0, R2,LSL#16
000111B0        MOV   R1, R0,LSR#16
000111B4        STRH  R1, [R4],#2
000111B8        BHI   loc_11198

In the middle of this function is a command that performs a reverse subtraction on two values. This isn’t 128-bit encryption. In reality, the data in the database is protected with a weak cipher that leaves the user very exposed.

Unfortunately, many programs store sensitive information in memory. All of these programs expose unsuspecting users to the risk of their data being compromised.

Picking CodeWallet’s Pocket

Thankfully, not all programs expose their secret keys in the way iPassword does. However, that doesn’t mean that these programs are any better at protecting the data. This next example demonstrates how a logic error in the programming, combined with inadequate data protection, can expose a "secure" file.

DeveloperOne describes its product this way: "CodeWallet Pro is the #1 secure personal and business information organizer for your Windows Mobile Pocket PC or Smartphone. Manage passwords, banking information, credit card details, PIN codes, travel plans, insurance policies, registration codes, gift lists, you name it, CodeWallet Pro manages it."

As with iPassword, CodeWallet promises to protect your data, but via a little reverse-engineering and debugging, it was fairly easy to nullify this protection. Fortunately, CodeWallet fixed this problem, and the most current version (6.62) is no longer vulnerable to this issue. That said, this type of problem is not isolated to CodeWallet.

When the user first opens her CodeWallet program, a password entry screen appears, similar to the one in Figure 5.

Figure 5

Figure 5 CodeWallet’s main window.

From here, the user can either type a numeric key using the pad provided by the program, or use the keyboard to enter a stronger alphanumeric key. As with iPassword, a text box is used to collect the password. However, instead of using the GetDlgItemTextW function as our entry point, we’re going to probe this program from another angle.

When a password is entered into CodeWallet, the program encrypts the entry and bumps it up against another hash stored in the data file. If the hashes match, the file is decrypted and opened for the user to view. If the hashes don’t match, the program sends a notice to the user via a message box (see Figure 6).

Figure 6

Figure 6 CodeWallet’s invalid password message.

Since we’re dealing with a program written in C++, we can deduce that this message box was created via the MessageBoxW function. So, to figure out where in the program this function is called, we open IDA, list the functions, click the item named MessageBoxW, and set a breakpoint using the F2 function (see Figure 7).

Figure 7

Figure 7 The MessageBoxW breakpoint.

Once the breakpoint is set, we choose Debugging > Process options in IDA and press F9. After a few seconds, the PPC displays the key entry window. Next, we type an invalid password and click OK. At this point, IDA monitors the code execution, detects the MessageBoxW breakpoint, and stops the program. Using the same method as we used with iPassword, we can figure out the source of the MessageBoxW function call by right-clicking the LR register field and jumping to that location in memory (in this example, 0x00045ED0).

Things get a bit tricky here. We need to back up through the program until we find out where the password is validated. Fortunately, this isn’t too difficult, because IDA provides the information we need.

When we jumped back into the address specified by the LR register, we landed in the middle of a subroutine. Chances are that this subroutine has nothing to do with the actual validation process, but instead is the piece of the program where the processor is sent if the wrong password is entered. We know this in part because of experience, but if you look at the code preceding the LR address, you won’t find any compare functions. We can further verify our guess by locating the MessageBoxW function call, which can be found buried in the BL sub_4D80C subroutine directly above the LR address.

So where did the call originate for the current code? If we go up roughly 11 lines from the current address in IDA, we see the following:

.text:00045EA4 loc_45EA4                ; CODE XREF: sub_45854+4D0

This line says that the current subroutine was called from the address 0x45854+4D0, which equals 0x00045D24. To get there quickly, we can simply click on the CODE XREF address.

At this point, we see a few lines of code indicative of something worth investigating:

.text:00045D1C BL   sub_37B44
.text:00045D20 CMP   R0, #0
.text:00045D24 BEQ   loc_45EA4     -> to the message box

Password verification often is located in a subroutine. When this routine is returned, it sets the R0 register to either 1 (pass) or 0 (fail). So if R0 is equal to #0, the "branch if equal" instruction redirects the processor to the message box alert subroutine.

We need to know how this value gets set to 0. To find out, we need to investigate the subroutine located at 0x37b44, which we access by double-clicking the BL sub_37B44 entry in IDA. Once there, we apply some simple logic to help us narrow down the part of the subroutine that we need to examine. In other words, we know that when this subroutine is finished, it will have to assign R0 a value—so we start at the bottom of the subroutine and work our way up.

At the top of the subroutine is an opcode with the following:

.text:00037B44 STMFD  SP!, {R4-R6,LR}

This opcode basically tells the processor to store the values in registers R4–R6 and the LR value onto the stack. This action is necessary because the processor most likely will need to overwrite the values in R4–R6 with its new information generated by the following subroutine. Anything in those registers will be lost, so the data is placed onto the stack for safekeeping. Incidentally, when the subroutine is complete, all of that information will have to be taken off the stack and placed back into the registers. Knowing that this trick is almost always accomplished via the opposite command (LDMFD), we only have to scroll down through the code until we get to this point:

.text:00037CDC LDMFD  SP!, {R4-R6,PC}

Now let’s look at the 10 lines preceding this point, and see if we can figure out how 0 ends up in R0 if the wrong password is entered:

.text:00037CB4 MOV   R2, #0x10
.text:00037CB8 ADD   R1, SP, #0x188+var_6C
.text:00037CBC ADD   R0, R6, #0x26C
.text:00037CC0 BL   memcmp
.text:00037CC4 CMP   R0, #0
.text:00037CC8 LDR   R0, [SP,#0x188+var_14]
.text:00037CCC BNE   loc_37CE4
.text:00037CD0 BL   sub_521AC
.text:00037CD4 MOV   R0, #1
.text:00037CD8 ADD   SP, SP, #0x178
.text:00037CDC LDMFD  SP!, {R4-R6,PC}

Address 0x00037CD8 is responsible for resetting the SP address to where it was prior to the subroutine, so we can ignore that. However, we can see that in address 0x00037CD0 the number #1 is moved (with MOV) into the R0 register. Obviously, this opcode isn’t executed if we enter the wrong password. Why not?

The only way it wouldn’t be executed is if the processor never hit that line, which means that a previous opcode must have redirected the processor away. Look at address 0x00037CCC. It contains a BNE (Branch if Not Equal) opcode. This is where the processor is diverted away. Following that branch to its code, we see that it leads to address 0x37CE4, where we find this:

.text:00037CE4 loc_37CE4                ; CODE XREF: sub_37B44+188
.text:00037CE4 BL   sub_521AC
.text:00037CE8 MOV   R0, #0
.text:00037CEC ADD   SP, SP, #0x178
.text:00037CF0 LDMFD  SP!, {R4-R6,PC}

Here we have an alternate ending that sets R0 to the value #0, and then returns to the parent routine, where another CMP opcode is waiting to determine whether the password was valid. Now that we know this, we need to figure out how the BNE condition is set.

When dealing with ARM opcodes, the conditions are almost always set via some sort of CMP (compare) function. If the comparison is true, then the EQ (equal) flags are set in the processor; if not, the NE (not equal) flags are set. If we look up a couple of lines at address 0x00037CC4, we can see a CMP R0, #0 opcode, and directly before that is function call memcmp. What are the chances that our entered password is compared to the existing one via this function? Pretty good.

To test this theory, we need to set a breakpoint on the memcmp call and allow IDA to do its job. We first press F9 to allow the current break condition to run its course. Once the screen is back to the entry windows, enter a new password and click OK. If any breakpoints are hit, just let IDA continue by pressing F9. Once you click OK, IDA breaks at the memcmp function, as expected.

Now let’s take a look at what’s being compared. To do this, we need to understand a little bit about how the memcmp function works. Thankfully, we can gain some of this information from Microsoft’s website. We learn that memcmp takes three variables: value 1, value 2, and the length to be compared. We can confirm this pattern by testing a few passwords to see what happens. To view the actual values, right-click R0 and R1 and select the "Jump in a new window" option. If you enter the correct password, both R0 and R1 should contain matching data; if not, the contents of the memory will differ, as Figure 8illustrates.

Figure 8

Figure 8 CodeWallet memcmp details.

When the function returns, it sets R0, R2, and R3 as 00000000 if the two values match, or it provides information regarding what doesn’t compare if the memory values don’t match. Knowing this, we can determine how the CMP R0, #0 is used to control the program flow. But what happens if we fudge the results? Will CodeWallet figure it out? And more importantly, will the data be left exposed?

To find out, we need to set a breakpoint at address 0x00037CC. Assuming that you enter the wrong password, the registers window should show you something similar to Figure 9.

Figure 9

Figure 9 Registers after a failed compare.

To test our theory, we only need to change the results to what the program would expect if we entered the correct password. To do this, simply click R0 and press 0 on your keyboard to update the register value. Repeat this action for R2 and R3. Finally, press F9 to let the program continue. Note that you will have to repeat this process again, because the program checks the password entry twice during execution.

A few seconds after the second memcmp manipulation is complete, CodeWallet 6.14 opens and presents full access to the data (see Figure 10). What does this mean? It appears that the encrypted file is protected by a static key embedded in the software, which means that your password has nothing to do with the security of that data.

Figure 10

Figure 10 CodeWallet’s "secure" data.

As mentioned earlier, CodeWallet was informed of this problem several times, and finally released an update that fixes this attack vector. Unfortunately, we’ve found numerous other programs that suffer from very similar bugs.

InformIT Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from InformIT and its family of brands. I can unsubscribe at any time.

Overview


Pearson Education, Inc., 221 River Street, Hoboken, New Jersey 07030, (Pearson) presents this site to provide information about products and services that can be purchased through this site.

This privacy notice provides an overview of our commitment to privacy and describes how we collect, protect, use and share personal information collected through this site. Please note that other Pearson websites and online products and services have their own separate privacy policies.

Collection and Use of Information


To conduct business and deliver products and services, Pearson collects and uses personal information in several ways in connection with this site, including:

Questions and Inquiries

For inquiries and questions, we collect the inquiry or question, together with name, contact details (email address, phone number and mailing address) and any other additional information voluntarily submitted to us through a Contact Us form or an email. We use this information to address the inquiry and respond to the question.

Online Store

For orders and purchases placed through our online store on this site, we collect order details, name, institution name and address (if applicable), email address, phone number, shipping and billing addresses, credit/debit card information, shipping options and any instructions. We use this information to complete transactions, fulfill orders, communicate with individuals placing orders or visiting the online store, and for related purposes.

Surveys

Pearson may offer opportunities to provide feedback or participate in surveys, including surveys evaluating Pearson products, services or sites. Participation is voluntary. Pearson collects information requested in the survey questions and uses the information to evaluate, support, maintain and improve products, services or sites, develop new products and services, conduct educational research and for other purposes specified in the survey.

Contests and Drawings

Occasionally, we may sponsor a contest or drawing. Participation is optional. Pearson collects name, contact information and other information specified on the entry form for the contest or drawing to conduct the contest or drawing. Pearson may collect additional personal information from the winners of a contest or drawing in order to award the prize and for tax reporting purposes, as required by law.

Newsletters

If you have elected to receive email newsletters or promotional mailings and special offers but want to unsubscribe, simply email information@informit.com.

Service Announcements

On rare occasions it is necessary to send out a strictly service related announcement. For instance, if our service is temporarily suspended for maintenance we might send users an email. Generally, users may not opt-out of these communications, though they can deactivate their account information. However, these communications are not promotional in nature.

Customer Service

We communicate with users on a regular basis to provide requested services and in regard to issues relating to their account we reply via email or phone in accordance with the users' wishes when a user submits their information through our Contact Us form.

Other Collection and Use of Information


Application and System Logs

Pearson automatically collects log data to help ensure the delivery, availability and security of this site. Log data may include technical information about how a user or visitor connected to this site, such as browser type, type of computer/device, operating system, internet service provider and IP address. We use this information for support purposes and to monitor the health of the site, identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents and appropriately scale computing resources.

Web Analytics

Pearson may use third party web trend analytical services, including Google Analytics, to collect visitor information, such as IP addresses, browser types, referring pages, pages visited and time spent on a particular site. While these analytical services collect and report information on an anonymous basis, they may use cookies to gather web trend information. The information gathered may enable Pearson (but not the third party web trend services) to link information with application and system log data. Pearson uses this information for system administration and to identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents, appropriately scale computing resources and otherwise support and deliver this site and its services.

Cookies and Related Technologies

This site uses cookies and similar technologies to personalize content, measure traffic patterns, control security, track use and access of information on this site, and provide interest-based messages and advertising. Users can manage and block the use of cookies through their browser. Disabling or blocking certain cookies may limit the functionality of this site.

Do Not Track

This site currently does not respond to Do Not Track signals.

Security


Pearson uses appropriate physical, administrative and technical security measures to protect personal information from unauthorized access, use and disclosure.

Children


This site is not directed to children under the age of 13.

Marketing


Pearson may send or direct marketing communications to users, provided that

  • Pearson will not use personal information collected or processed as a K-12 school service provider for the purpose of directed or targeted advertising.
  • Such marketing is consistent with applicable law and Pearson's legal obligations.
  • Pearson will not knowingly direct or send marketing communications to an individual who has expressed a preference not to receive marketing.
  • Where required by applicable law, express or implied consent to marketing exists and has not been withdrawn.

Pearson may provide personal information to a third party service provider on a restricted basis to provide marketing solely on behalf of Pearson or an affiliate or customer for whom Pearson is a service provider. Marketing preferences may be changed at any time.

Correcting/Updating Personal Information


If a user's personally identifiable information changes (such as your postal address or email address), we provide a way to correct or update that user's personal data provided to us. This can be done on the Account page. If a user no longer desires our service and desires to delete his or her account, please contact us at customer-service@informit.com and we will process the deletion of a user's account.

Choice/Opt-out


Users can always make an informed choice as to whether they should proceed with certain services offered by InformIT. If you choose to remove yourself from our mailing list(s) simply visit the following page and uncheck any communication you no longer want to receive: www.informit.com/u.aspx.

Sale of Personal Information


Pearson does not rent or sell personal information in exchange for any payment of money.

While Pearson does not sell personal information, as defined in Nevada law, Nevada residents may email a request for no sale of their personal information to NevadaDesignatedRequest@pearson.com.

Supplemental Privacy Statement for California Residents


California residents should read our Supplemental privacy statement for California residents in conjunction with this Privacy Notice. The Supplemental privacy statement for California residents explains Pearson's commitment to comply with California law and applies to personal information of California residents collected in connection with this site and the Services.

Sharing and Disclosure


Pearson may disclose personal information, as follows:

  • As required by law.
  • With the consent of the individual (or their parent, if the individual is a minor)
  • In response to a subpoena, court order or legal process, to the extent permitted or required by law
  • To protect the security and safety of individuals, data, assets and systems, consistent with applicable law
  • In connection the sale, joint venture or other transfer of some or all of its company or assets, subject to the provisions of this Privacy Notice
  • To investigate or address actual or suspected fraud or other illegal activities
  • To exercise its legal rights, including enforcement of the Terms of Use for this site or another contract
  • To affiliated Pearson companies and other companies and organizations who perform work for Pearson and are obligated to protect the privacy of personal information consistent with this Privacy Notice
  • To a school, organization, company or government agency, where Pearson collects or processes the personal information in a school setting or on behalf of such organization, company or government agency.

Links


This web site contains links to other sites. Please be aware that we are not responsible for the privacy practices of such other sites. We encourage our users to be aware when they leave our site and to read the privacy statements of each and every web site that collects Personal Information. This privacy statement applies solely to information collected by this web site.

Requests and Contact


Please contact us about this Privacy Notice or if you have any requests or questions relating to the privacy of your personal information.

Changes to this Privacy Notice


We may revise this Privacy Notice through an updated posting. We will identify the effective date of the revision in the posting. Often, updates are made to provide greater clarity or to comply with changes in regulatory requirements. If the updates involve material changes to the collection, protection, use or disclosure of Personal Information, Pearson will provide notice of the change through a conspicuous notice on this site or other appropriate way. Continued use of the site after the effective date of a posted revision evidences acceptance. Please contact us if you have questions or concerns about the Privacy Notice or any objection to any revisions.

Last Update: November 17, 2020