40

Let's say, on any software (that is installed on Client-Side OS), is it possible, to alter the software in such way (i.e. Zip Passwords) so for incorrect input it redirected to correct "result", like:

enter image description here

Is it possible to alter software logic to execute the command instead of another command? If so, then nothing can be protected from cracking?

T.Todua
  • 2,707
  • 4
  • 20
  • 29
  • 2
    yes but this is simplest kind of RCE. just open program in Debugger/Disassembler and find jump command! watch this https://www.youtube.com/watch?v=uydMlQlEiyc – AminM Dec 11 '16 at 07:51
  • 47
    What you're describing is incorrect for most password protected resources (zip files included) that rely on an encryption algorithm, but is largely how many DRM based solutions operate. – berry120 Dec 11 '16 at 13:30
  • 8
    An example of DRM based solution: PDF. – Gustavo Rodrigues Dec 11 '16 at 17:53
  • 24
    This is entirely possible for many programs which artificially limit functionalities, but it is not for programs which access _encrypted data_. The key here being encrypted data, such as password-protected zip and pdf files, _literally can not be read by any program_ without knowing the password to decrypt it. – daboross Dec 11 '16 at 22:41
  • 1
    Some old games type of protection where to type a specific word from the manual and then it get checked if was correct or not. Changing a Jump-if-zero to a jump-if-not-zero (73h to 74h, if I remember) was all it was needed. – woliveirajr Dec 12 '16 at 16:13
  • 10
    TL;DR: all _software_ protection mechanisms can be bypassed through reversing. _ALL_it's not "if" but "when." That said, I worked at a company that used hardware level data traps to exec/signal threads to process two halves of a passphrase whenever a specific byte in memory was written to (this is an Intel-compatible feature) -- it took two years before someone figured out how our key was being stored.. but.. it was eventually reversed from the code after the algorithm was discovered. – Shaun Wilson Dec 12 '16 at 16:51
  • 1
    @ShaunWilson that sounds diabolically clever and pretty effective. I actually feel sorry for whoever was tasked with debugging that (original dev *and* hackers), that sort of "magic" is infuriating. – brichins Dec 12 '16 at 21:20
  • Ultimately all you are missing is **an understanding of the mathematics behind encryption.** For a primer on the subject, I *highly* recommend **[the chapter on Number Theory](https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-042j-mathematics-for-computer-science-fall-2010/readings/MIT6_042JF10_chap04.pdf)** from MIT's Open Courseware materials for the course "Mathematics for Computer Science." By the end you will have actually worked the RSA algorithm with pencil and paper. – Wildcard Dec 13 '16 at 23:29
  • (If proof notation is unfamiliar to you, [start from the beginning of the course](https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-042j-mathematics-for-computer-science-fall-2010/readings/).) – Wildcard Dec 13 '16 at 23:29

11 Answers11

79

In short, yes, you can modify the executable, use a debugger, etc. to alter the logic of the code being executed.

But, that may not be enough.

To use your example of ".zip passwords", password protected archives use the password to derive an encryption key. Unless you supply a correct password, the generated key will be wrong, and even if you modify it to use a wrong key, it will not successfully decrypt the ZIP file.

Another scenario might involve a setuid executable which runs with higher privileges. You could run it under a debugger, or copy it to your user account and make changes, but all this will achieve is running it with your user's permissions, thus defeating exploitation possibilities.

Alexander O'Mara
  • 8,794
  • 6
  • 34
  • 38
42

Well your perception of .zip passwords is not accurate. The approach, also used by many other programs is to always run a decryption algorithm and obtain a result, before program even reaches the "good or bad password" decision. The trick is that the decryption produces garbage on any password except a good one which "magically" (or rather - mathematically) calculates proper data. So the program doesn't know what the good password is.

The "good or bad" moment that you want to hack only checks whether the result is garbage. It's not much benefit to override that.

kubanczyk
  • 1,192
  • 6
  • 11
21

Yes and No.

Since no one has yet come up with a real life (non-computer-related) example, I'll try here:

Imagine trying to board a flight. You need a boarding pass, or the security guys will not let you through. If you have access to the system and you're able to modify it (say you're the CEO), can you bypass the security? Yes! You can:

  • Remove the security guys (remove the entire authentication component)
  • Ask the guys to let everyone in (remove the "if passenger has valid boarding pass" check)
  • Ask the guys to give access if somebody presents a special boarding pass (add a new validation rule to allow fake credentials)

Now, another scenario: a bunch of safes are stored in a bank. To open a safe, you need a physical key to turn the lock.

Can you pull the previous trick? Yes you can, but it won't help. It's not like the security guy who stands there has access to all the safes - he does not have the key to any one of the safes. You can beat the hell out of him, but he does not just possess what is necessary (the physical key) to open the locks.

You can try picking the lock (brute-forcing), but it would be extremely time consuming (the math of modern encryption keys says you need some billions of years to unlock it, even if you have all the computers in the world doing it for you). So there you are - in this design (data encryption), the only way to obtain the stored data is using a key, which makes it impossible to bypass.

kevin
  • 933
  • 4
  • 16
17

Sure, software can do whatever you program it to do.

As a trivial example, if I was provided a Python program that checked for a password:

password = raw_input('Enter your password: ')
if password != 'oh-so-secret':
    sys.exit(1)

do_secure_thing()

I could quite simply change it to not care what the password is:

password = raw_input('Enter your password: ')

do_secure_thing()

(In this case, you could also just see what the hard-coded plaintext password is and enter it.)

With binary applications, you have to decompile them before you can modify the source, but there are plenty of decompilers for common languages.

This is why code signing exists.

Now, if this isn't your own system, your options may be a bit more limited. On most Unix-like systems, executables are generally stored with read- and execute-only permissions for non-root users; thus, if you aren't root, you can't modify the target executable. There are other less direct methods to try, but if those fail you're looking at moving to a different vector.

For instance, a keylogger will record the passwords that the user enters, allowing you to reuse them on your own later.

Another method of attack that doesn't require modifying a program's source is to modify the dynamic library load path such that the program uses a library call that you have written, rather than the one it expects. If they use an external, dynamically-loaded library for password management, and that library has a function verify_password() that returns a boolean, you can write your own verify_password() that always returns true, and load that in instead.

The real distinction that changes the answer from "yes" to "no" is if the password isn't actually a password, but an encryption key. If the data is encrypted, then it doesn't matter what any outside programs do - the data it still encrypted until the decryption algorithm is fed the proper key.

Xiong Chiamiov
  • 9,402
  • 2
  • 35
  • 78
  • It could be made a lot more secure by doing: `h = '$1$dikapmhs$4YIBUV3/uTlSZ7dF1/VWt/'` `if crypt(password, h) != h:` then there is no longer a plain text password in the source. – kasperd Dec 10 '16 at 21:28
  • @kasperd Your point is valid in the special case mentioned in the last paragraph of the answer. In the other scenarios however (for example when the attacker _is able to modify the executable_), the victim is out of luck, no matter whether the password is stored in plain-text in the source/binary or not. – Synoli Dec 11 '16 at 00:12
  • 2
    @Synoli Actually whether using `crypt` is a lot more secure or only a little bit more secure depends on what else the password grants the attacker access to. But I agree there are many situations where a password validation implemented in that way would be pointless anyway. – kasperd Dec 11 '16 at 01:44
  • While great answer, the OP explicitly mentioned having admin privileges and your answer focuses more on the non-admin side of the story – Olle Kelderman Dec 11 '16 at 03:32
  • @OlleKelderman At the time I answered, [there was no mention of admin privileges](https://security.stackexchange.com/revisions/144980/1). – Xiong Chiamiov Dec 11 '16 at 21:50
  • @XiongChiamiov oh wops, sorry, haven't said a thing in that case – Olle Kelderman Dec 11 '16 at 21:59
  • Code signing is of no use here. Making the signature check return true is trivial. – Joshua Dec 12 '16 at 20:02
  • The signing check could be implemented in hardware or firmware, but I agree, with administrator privileges, you own the machine. – Xiong Chiamiov Dec 12 '16 at 21:02
5

Suppose you have an app that stores data in a text file (or a small database), but to access the file from the app you need to enter a password or use a special process. You could simply open the text file (or db) from the file directory using the OS (no reverse engineering required). This used to happen a lot in older programs (games, especially).

That's why apps that hope to be secure take measures to protect the data from the OS itself. Like encrypting the data or obfuscating the data to make it difficult to use.

schroeder
  • 125,553
  • 55
  • 289
  • 326
  • 1
    Let me fix that for you: "That's why apps that hope to be *obscure* take measures to protect the data from the OS itself." There is nothing an app can do to protect itself from the OS, the OS has debugger privilege and can pause and dump the decrypted data from memory. – Lie Ryan Dec 12 '16 at 16:36
  • @LieRyan make it an edit! – beppe9000 Dec 14 '16 at 14:17
  • @LieRyan while I agree with the difference between security and obscurity, as you describe it, I'm not sure the difference is worth the correction in this case. I qualify the statement with "hope" and describe obfuscation as a technique. These techniques are also used in-memory. – schroeder Dec 14 '16 at 17:49
3

It depends on how the software XYZ uses the password in order to produce desirable action and what type of data it works with.

If we look at the abstract algorithm of the XYZ program it would be:

  1. Ask user to enter the password.
  2. Do something with the password entered by user.
  3. Produce desirable output (or perform desirable action).

So, your question can be narrowed down to step #3:

Is it possible to produce desirable output (or perform an action) without using the program XYZ?

There are many variants possible here, but the main point is that the software XYZ performs particular steps in order to produce the result.

If one can create a program ABC that can produce the same result in a reasonable amount of time without requiring a password, the XYZ can be bypassed.

That would indicate that the entire "protection" is implemented in the program XYZ itself.

If creation of such program ABC is not possible then the protection relies upon an algorithm that requires the password regardless of what program is trying to use it.

Example 1: An unprivileged OS account can not set password for another user, because it is enforced by the OS. So the OS in this case is XYZ. But one can boot the computer from a bootable drive and overwrite the file containing passwords, because the original OS is not working at this time, therefore it can not enforce the protection. So, we were able to produce desirable result without using the XYZ program.

Example 2: In the second example, the system drive of the OS is properly encrypted with a strong crypto algorithm. If we boot the computer with a bootable drive in attempt to bypass the original OS we will discover that we can not achieve our goal, because we can not access the file containing passwords. It resides on a partition that needs to be decrypted first, but we do not know the password. An attempt to brute force the decryption process would not bring the desirable result any time soon, therefore in this case it was not possible to bypass the XYZ program or any other program with similar functionality, because the underlying data required the password.

VL-80
  • 1,234
  • 1
  • 9
  • 17
3

The zip password is not an example of what you’re thinking. But lots of things are, in particular “trial” versions that are limited in time or feature set.

I recall a pair of articles in a programming magizine (might have been Computer Language) explaining how to do that and how to thwart attempts to do that to your code, respectively.

I know of cases where it was literally as simple as finding the comparison statement and changing the jump condition — that is, changing one byte — to bypass the real check.

This is sometimes the case now if the author simply wrote the line of code as part of the program. But for activation keys and the like a whole industry has sprung up and the author can include a kit that obfuscates the actual test and makes it difficult for the program to function if attempts are made to curcumvent it using common techniques familiar to a programmer debugging code.

JDługosz
  • 1,139
  • 2
  • 7
  • 12
2

It all depends on how the system works when decoding the password.

You are imagining a very basic "log in" type password system that could be infiltrated. However something like ZIP files, and websites use various methods to combat people just editing the system to force it to reveal the password.

One way is the use of MD5 along with 'salt' to add to security - this works on the fact that the password is turned into an unrecognisable code that can't be turned back - a basic example of what happens is as follows

System asks for password - e.g. PASSWORD System adds 'salt' to password - e.g. 1234 (password is now PASSWORD1234) System uses MD5 on the password with salt - most people will know that PASSWORD on it's own will generate the MD5 code 319f4d26e3c536b5dd871bb2c52e3178 however with the "1234" salt added to the password the MD5 now becomes 579f276ad2a77fd1698c38e3ad4d20a7 - which is a totally different code.

At this point the system still hasn't checked whether or not that password was valid, it then passes this new code onto another section of the program that decides whether or not the MD5 code matches what is expected if it does it shows the file (the initial password has long been discarded from memory).

For someone to infiltrate this type of password they would need to obtain the initial password that was typed in first, and then later on find out whether or not the program allowed the file to be opened. On a piece of software on a computer it might be possible to obtain the password and then check later to see if the file was opened and get the password in this way, however if the password is sent as an MD5+salt to another server (for example through javascript and PHP) it becomes a lot more tricky because one computer has the password in it's memory which it converts and the php server has just the md5+salt password which can't be converted back.

On top of that another method used is to take the password and encode it within the data in some way which is how zip files work for example I've got a file with the following text....

the quick brown fox jumps over the lazy dog

I give it a one letter password of ! ok I know it's a bit simple but this is a simple example - the computer could convert that ! into it's ASCII equivalent and subtract the ascii code of every letter from it to encode it - the ascii code for ! is 33 and the ascii code for t is 116 and 116 - 33 = 83 which is the ascii code for a capital letter S so when the data is encrypted the above line ends up stored as

SGD PTHBJ AQNVM ENW ITLOR NUDQ SGD K@YX CNF

now if someone is trying to unencrypt this message you don't know whether or not they've got the right password - if they put in the password of # instead of ! they'd get the following message returned to them

vjg swkem dtqyp hqz lworu qxgt vjg nc|{ fqi

which doesn't make any sense - so most systems actually check the validity of a password, but they alter the password initially so it can't be hacked by someone just diverting the result - the only time this sometimes falls down is when someone creates their own fake website or program and gets the user to initially enter their password into the fake program or website and of course many websites now are even getting round that by using authentication tokens that generate special passwords that are only valid for about 5 minutes at a time (for example the HSBC smart key).

TheKLF99
  • 121
  • 1
  • This answer would be better without the mention of MD5, which is, regardless of salt, a *really bad choice of hashing function for passwords*, and anybody using it for such *is dong it wrong*. It really undermines the credibility of your example. – IMSoP Dec 14 '16 at 14:27
1

The question needs clarification. Your understanding of how a password protected zipfile is read is incorrect. As others have pointed out, a zipfile is encrypted (the data is scrambled) and the password is the key to decrypt.

What you are describing (a redirection of code execution via reverse engineering the code flow) would work to defeat "access control" being enforced by the program.

So, to your original question:

Is it possible to alter software logic to execute the command instead of another command? If so, then nothing can be protected from cracking?

It is certainly possible to alter software logic to execute commands, bypassing access control to do something the program could otherwise do, via reverse engineering. However, that does not support your second statement that "nothing can be protected from cracking." The encrypted zipfile is a fine example of where your control over the code doesn't get you the contents of the file.

In that case, the key is not a gatekeeper preventing you from executing a code path, but rather a required component to get at the plain text data. Nothing to do with program flow control.

JesseM
  • 1,902
  • 10
  • 9
-3

This is basically called cracking and can be done using a debugger. There are conditional jumps like je, jne, jnz etc that can be nopped to achieve this. Lena's reversing tutorials on tuts4you should be a good start.

jammy47
  • 43
  • 1
  • 6
  • 2
    This doesn't answer the question and is incorrect anyway (you wouldn't get very far using your method for an encrypted *.zip file for example). – AStopher Dec 12 '16 at 13:11
-4

The process that could best be described as "reverse engineering" would be a Timing Attack, which involves analysing the time taken to verify a password. It is indeed possible to slow down the processing of an algorithm and count how many processor ticks it takes to reject a password. As you guess more letters correctly, it'll take longer to reject it, so you can be guided in your guesses.

This is not just a hypothetical situation; this attack has been used against SSL and some versions of Unix.

kokociel
  • 101
  • 2