n3or3trosecurity
n3or3trosecurity
n3or3tro Security
44 posts
Don't wanna be here? Send us removal request.
n3or3trosecurity · 6 years ago
Text
CRACKME 0x04 Solution
Task:
i) Find input that results in the program printing 'License valid!'. ii) Modify the binary such that any input results in the program printing 'License valid!'.
Solution:
Tumblr media
i) As you can see from the above screenshot, the validate_license() function which is called from main checks to see if there is a license file in the current directory called ‘license.txt’ if there is, it open it and read it’s contents. If the contents are the number 6447 then access is granted. So the input that results in the program printed ‘License Valid’ is a file with the contents 6447.
ii)
Tumblr media
You could easilly bypass this security measure by just creating the file and writing to it yourself. The other way is to patch the binary so that the program always jumps to the ‘License Valid’ case regardless of the return of the validate_license() function.
Tumblr media
0 notes
n3or3trosecurity · 6 years ago
Text
CRACKME 0x06 Solution
Task:
i) Find input that results in the program printing 'Access granted!'. ii) Modify the binary such that any input results in the program printing 'Access denied!'.
Solution:
Tumblr media
i) This program is vulnarable because it uses the C function rand() which is deterministic given a certain seed. If you disassemble the binary you can see that the program grants access if the rand() function outputs 0x6eb933c2 = 1857631170. Using the knowledge that rand() is deterministic, we can try to brute force a seed. I wrote the following small script in C to attempt to brute force the seed.
Tumblr media
This indeed worked and the seed was 22. Thus If you run the program seeded with 22 it will always give you access. ii) This can be achieved by patching the jump that occurs after the comparison of rand(), such that the program always jumps to ‘Access granted’ without considering the output of the function.
Tumblr media
Above: the patched program. It will grant access on any input, but an input must be provided.
0 notes
n3or3trosecurity · 6 years ago
Text
Case Study: Aeroplane Cockpits
Task: In light of several recent incidents with rogue-Pilates, faulty cockpit controls and cockpit doors, we were tasked with considering how we could design the most secure cockpit control system possible?
Suggestions To Increase Security
Cockpit security can be broken into two main concerns
Doors: Having one entity with a deeper level of control compared to any other entity means you create a single point of failure, in a system that so direly cannot afford failure, this is not suitable. It is thus best to distribute the power among several parties. A solution we came up with was to have the have the control of the cockpit door shared between 3 parties. The first two being each pilot and the third being ground-control, or in emergency cases where communication to ground-control is lost, a head-flight attendant becomes the third party. The idea is: that for the door to be opened you need a majority rules situation. This mitigates almost all the risks associated with a single threat-actor, whether it be a rogue pilot, or hijacker.
Flight Controls and Software: Although they exist already, automated flight control systems do not have ultimate authority over the plane, i.e. if a rogue actor wanted to, they can take over the controls of the plane from the software. We decided it would be much safer to have software at the root of the planes control system acting as the ultimate authority on any decisions that are made from inside the cockpit. This again mitigates the risk of any single rogue actor, and also groups of rogue actors. However this creates a single point of failure, which as aforementioned is just not appropriate for a system where security is so essential. Therefore we decided that although software would be at the root, ground control would be the soil (bad analogy I know). Essentially if you think in terms of rings of privilege often used in operating systems, the automated flight software would sit at level 0, the pilots at level 1, but ground control would have level -1 access. This mitigates the main risk associated with having software as the root of you control system: software malfunction caused by a bug. The idea is that if both pilots can confirm with ground control that the automated software is malfunctioning then the ground control will grant the pilots high-levels of privilege than the software. The reason is that both pilots would be needed is because, if only one were needed, then it’s easy for a rogue pilot to incapacitate his co-pilot and then fool ground control into granting him control. Of course no solution is perfect (the more data I gather about security the more and more clear it becomes that there is often no ultimate ground truth right answer/solution; rather there are many many trade offs that need to be weighed and navigated in order to meet the desired goals) , for example what would happen if one pilot is non-maliciously incapacitated (heart attack for e.g.) and then the software starts to malfunction? How can ground control tell this scenario apart from the previous one where a rogue-pilot takes out his co-pilot? In conclusion, when designing a secure cockpit system one needs to assess the trade-offs between the centralization of authority and it’s decentralization. It’s all well and good to have an extensively complicated system that attempts to mitigate EVERY potential risk, but how much would such a system cost to implement? is it worth it to airlines? Because as harsh as it sounds the odds are airline companies care about their passengers in as far as the fact that they represent profit, and their harm represent a down-turn in the companies image and therefore profit; in security you can never assume that a company has ethical or moral values you have to assume (and you would probably often be correct) that businesses / corporations are money making conglomerations that care for nothing other than maximizing profits. As a result, part of a good security solution is making sure that it’s accessible and viable to whoever you are providing it for.
0 notes
n3or3trosecurity · 6 years ago
Text
WannaCry: Why An Insecure Internet Is In No One’s Interest.
The WannaCry virus was a ransomware cryptoworm from 2017 that infected hundreds of thousands of Windows machines. The virus uses EternalBlue, a Windows exploit that allows arbitrary code execution, to gain access into the system and then uses the DoublePulsar backdoor tool to install and execute a copy of itself. The virus would encrypt the computers data and display a message telling the user that they had to send an amount of bitcoin to an address in order to get it de-crypted. The authors of the malware had no way of keeping track of who did and didn’t pay the ransom and so most users lost their data anyway, if they didn’t have a backup. What I want to focus on is the fact that the 2 main tools used in this worm that cost hundreds of millions of dollars worth of damage, were stolen from the NSA. Both DoublePulsar and EternalBlue are NSA tools, the later being an exploit that they had discovered 5 years before the attack, but decided to horde for their own offensive capabilities. I think this really strikes at the heart of why the current practice of deeply-funded and powerful state actors hording exploits and buying vulnerabilities is ultimately not going to be stable, effective or safe going forward. We are lucky security researchers were able to find the kill-switch relatively quickly (4 days), but in this time it still managed to spread to 200 000 computers, infecting hospital systems, businesses, infrastructure. The NSA (and other intelligence organizations around the world) have the dual responsibility of protecting their own citizens and attacking/gathering informational resources of opposition. This may have worked during the second world war when these were two very different things, but now to attack and discover vulnerabilities in your enemies systems is also uncovering holes in your own and thus leaving yourself and the rest of the world vulnerable. This newly arisen fact is only going to become more prominent and more devastating as the world moves into ever increasing levels of technological entanglement. As computation becomes embedded in every single aspect of human life, we can no longer afford to not act on security vulnerabilities just because they give our side an advantage. Because they don’t, they may give your organization an advantage, but you can’t keep that advantage while simultaneously not leaving yourself open to attack. You may ask what then should these organizations do ? should they not collect these exploits to use against criminals and enemies of their state? I think the answer is no for now, and definitely not going forward. How did the police or any military/intelligence/government agency gather intel on individuals and situations before the masses of the worlds put their communication out into the open for the taking ? They performed old fashioned targeted police work. I think these organizations have become spoiled by the ease at which they’ve been able to collect information, but I think this is only a product of the very unusual time we have and still are (for the next short while) living in, where technological has flung our information out into the open, but hasn’t yet become absolutely critical to our survival, i.e. there aren’t many instances of computers keeping people alive. But this will not be the case going forward, as medical and computational technologies reach a concrescence we will see more and more the merging of biology and computation, and when this happens we can no longer afford to have intentionally vulnerable systems, an insecure internet/computational landscape is in no ones interest, unless you’re an anarchist. I propose that these organization moving forward will have to disbandon the idea of mass invasion of privacy and mass exploitation/vulnerability hording, and instead move back to old fashion detective/police/intelligence work. It doesn’t mean their methods need to be archaic, I’m sure the technological revolution of the 21st century has enabled great intelligence gathering technologies that don’t put humanity at risk.
0 notes
n3or3trosecurity · 6 years ago
Text
Job Application
Analytical Ability
Case Studies:
The analysis performed in my case-studies and subsequent write-ups represent both my ability to research and reflect upon security related occurrences in the real world.
Deep Water Horizon Aeroplane Cockpits
Other Research:
WannaCry Julian Assange
Personal Projects/Research
Reverse engineering + cracking:
these posts demonstrate all three characteristics of analysis:
Research - I had to undertake copious amounts of research in order to go from being a beginner in reversing, to being able to use reverse engineering + a working understanding of x86 ASM to crack software.
Reflection - The lengthy reflective write-ups I did on each exercise, particularly the earlier ones, demonstrate my ability to reflect on what I learnt from doing the exercises and communicate my thought process behind each decision I made when cracking the software.
Application - In order to be able to successfully crack software I needed to apply the theoretical knowledge I picked up from textbooks, online tutorials, information from my tutors/friends to the real world pieces of software in order to crack them. 
0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07
Threat Modelling
I wrote a short over-view analyzing threat modelling and how it works.
Time Management
Perhaps my greatest feat of time-management was the careful selection of my something awesome project. Although we did not have the job application spec at the time of proposing our  projects we did have a rough overview of what it would entail. Using this information I picked a project that I knew would require me to research, analyse, develop skills and work within the security community at UNSW, all components of the job proposal, thus killing many birds with one stone.
Further evidence of my time management skills is the fact that I started working on my something awesome project a few days after it was approved and steadily worked on it throughout the term. You can see evidence of this from these something awesome blog posts:
Attended reverse engineering and cracking seminar week 2 Started over the wire a few days after my proposal was accepted Did the first few crackme’s a few weeks after proposal This was of great assistance when I hit a hard roadblock during the last few weeks of my project, I realized I had to alter the final leg of my something awesome since the piece of software was not crack-able. I instead decided to complete some more sophisticated COMP6447 Wargames challenges, and having consistently worked throughout the term meant that I had accumulated enough skill and left enough time to execute my changed plans.
Skills:
Lock picking:
I was very impressed with how easy it seemed to pick locks, as per what was presented in the week 3 seminars. So I decided to go down to the demonstration table and learn exactly how to pick padlocks. You can find video of this here.
Practical Cryptography:
Cipher cracking: I can solve substitution cipher’s with relative ease as I have practiced them throughout the term. Evidence of this is here and here, I did not make a post for EVERY cipher I solved as that’s redundant.
Key Exchange: Diffie-Helman Merkle Puzzles
Reverse Engineering + Cracking:
Early in term I was exposed and thus became deeply interested in reverse engineering and cracking, I was amazed that this was even possible so I set out to acquire as much knowledge and skill as possible in this field. A lot of this learning is covered in my posts about my something awesome project. CRACKMEs: Particularly useful were the CRACKME challenges my tutor wrote which I completed multiple times. At first I was abusing the power of my disassembler and just patching and nopping the program until it behaved how I wanted to if the rest of the program was mangled. This was due to a lack of knowledge of how to read assembly programs, which only came with practice. As I was able to better understand the disassembled binary I was able to start cracking the programs more elegantly, in 1 or 2 changes. Refer above for the links to my blog-posts about the solutions.
Buffer Overflows & Scripting:
As part of exploiting programming error to cause a buffer overflow for example, I had to learn how to write scripts. I particularly learnt how to use pwntools which is a python library that greatly simplifies the script writing process. These scripts can be seen in my write-ups of the COMP6447 Wargames, these also illustrate a skillful understanding of computer systems fundamentals and reverse engineering used in conjuction to gain control of a vulnerable system.
Wargame02 Challenge 1 Wargame02 Challenge 2 Wargame02 Challenge 3
x86 ASM programming
As part of my goal of learning how to reverse engineer + crack and just to gain a deeper understanding of computer systems fundamentals I learnt x86 how to assembly programs. This is a very rewarding skill in and of itself, but it is particularly useful to one who is looking to learn how to reverse engineer, as dissemblers are best used with ASM. Programs I wrote can be found here and here.
Community & Professionalism
Early Adoption of Friday Night Fight-Club:
Contribution To Course Environment, Teamwork, Communication: Each week on Friday some tutors and their students stay back in-order to work on security related things: wargames, CTF challenges, something awesome projects, etc. I feel I helped this community develop in the first few weeks of term by being willing to interact and ask prolonged questions as to cultivate group conversation, when perhaps others didn’t feel comfortable to stay after class and talk and interact (at least they were not doing it, I know not their motivations). What started with 4 people is now a weekly happening of 10+ students and a few tutors where security ideas are exchanged and things are hacked.
Furthermore, I am active in online Slack secedu communities where we discuss both the course content and security ideas in general.
CTF Challenges
I worked with a team of students from my tutorial group to solve challenges in the Security Society CTF. I leveraged my experience in reverse engineering to solve some of the reverse engineering challenges, and buffer-overflow challenges.
Security Everywhere
I documented several occurrences of interesting security related events, in accordance with the course idea of developing ‘security eyes’:
Tracking the development of a spam worm: here and here.
Questioning the implementation of broken MDA5 algorithm by a popular Linux distro to fingerprint their OS: here. Noting Neuralink is looking for Security Engineers
Something Awesome
Find out about my something awesome here.
0 notes
n3or3trosecurity · 6 years ago
Text
Some x86 Assembly Programs
Tumblr media
The first basic ASM program I wrote, simply exits.
Tumblr media
I then wrote a program that prints a string literal held in the .data segment.
Tumblr media
I then wrote a program that can print any string that is NULL terminated (you don’t have to explicitly tell the program the string length).
Tumblr media
I then wrote a program that prints any integer as a string of its decimal digits.
Tumblr media
I then wrote a program that prints a greeting based on a user inputted string. These programs taught me the fundamentals of programming in assembly and gave me greater confidence in navigating disassembled x86, which was of great use in my overall goal of becoming good at reverse engineering and cracking.
0 notes
n3or3trosecurity · 6 years ago
Text
Something Awesome: Recap
This is a review post discussing and linking together all the parts of my something awesome project.
1. Go to workshops put on by the secsoc and csesoc that teach skills related to reverse engineering.
2. Complete at least the 1st stage of OverTheWire to get comfortable with the UNIX command line. 0-4 5-9 10-14 I only completed half of these challenges. The reason being that I wanted to do these challenges in order to get comfortable performing security related task on a Linux command line since I wasn’t very experienced. However as the term went on and I got more and more experience with Linux, from these challenges but more so just from using it on a day to day basis, these challenges no longer became necessary and were taking time away from learning about reversing. 3. Read Chapters 1 (x86 and x64 Assembly Language) and 4 (Debugging and Automation) of Practical Reverse Engineering by Bruce Dang, Alexandre Gazet and Elias Bachaalany + the Comp6447 resources to learn the fundamentals of reverse engineering. I didn’t write a book/chapter review, but it should be clear that I read through these resources as I started the term as an absolute beginner with 0 knowledge of any reversing or cracking or x86 ASM programming and can now sufficiently use all of these tools in order to solve challenges and real world tasks.
4. Write several small x86 assembly language programs in order to build a strong understanding how higher level computational constructs are represented in assembly language
I talk about and show x86 ASM programming here.
5. Complete all of Jazz’s reverse engineering CRACKME exercises.
0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 6. Completing online challenges for reverse engineering.
I met this criteria by competing in the sec-soc CTF. I didn’t do a write-up of the event, but my tutor was present there and can attest to the fact that I participated with my team on the day for many hours. I solved 2-3 of the reverse engineering challenges and also utilized reverse engineering to assist my teammates in solving a buffer-overflow challenge
7. Altered: Complete wargames challenges from COMP6447 Wargames01 - just did the intro to get the hang of it.
Wargames02: Challenge1: jump Challenge2: bllind Challenge3: bestsecurity
0 notes
n3or3trosecurity · 6 years ago
Text
Wargames02 Challenge 3
\canThis is the write-up of my solution to the COMP6447 Wargames02 ‘bestsecurity’ challenge.
Challenge: ‘bestsecurity’ Solution:
This challenge is a bit more realistic as it has you try and defeat a (slightly less-robust) Canary, which would be in almost any gcc compiled binary.
Tumblr media
From above: we can see that the buffer which gets() will read into is at ebp-0x89. However before this buffer is created there is also a variable placed onto the stack at ebp-0x09. These are the only 2 things on the stack so we can assume that the length of the buffer = 0x89 - 0x09 = 0x80 = 128 bytes. Just before the conditional jumps we can see that the variable that was placed onto the stack is checked against the string “1234″; from here we can deduce that this variable is acting like a canary, sitting between the return address of the function and all the data above it in the stack. Since the buffer that sits directly above it is written to by gets() we can overwrite this canary and thus fool the program into thinking we haven’t overflowed the buffer. In this challenge the canary value was given to us, but in the real world one would need to secure it through some sort of information leak.
Tumblr media
Above is the script I wrote to exploit this binary. I used the pwntools function fit, which takes a dictionary (hash-table) where the key is the amount of bytes you want to padding you want and the value is the payload you want to put at the end of that padding. You’ll notice above my payload I have 2 commented out lines.
0 notes
n3or3trosecurity · 6 years ago
Text
Wargames 02 Challenge 2
This is the write-up of my solution to the COMP6447 Wargame02 ‘blind’ challenge. Challenge: Blind
Tumblr media
Above: The vulnerable vuln() function that uses gets. Solution: This challenge was similar to the first except the address of the win() function is not given to you. Conveniently though, pwntools allows you to find the address of a function given it's name. I utilised this to get the address, and then from here on out it was pretty similar to the previous challenge.
I did have to prepare the payload slightly differently though. Rather than the vulnerable program logic being in main, main instead calls a function that uses gets() named vuln(). This meant that the return address that was popped after vuln() exits would have been +0x04 from wherever the bottom of the stackFrame was for vuln(), as oppose to having to overwrite a function pointer in the last challenge. Hence when I overflowed the buffer I had to include an extra 4 bytes in the length of the buffer and then put the return address at the end of that.
Tumblr media
Above: Script that exploits the use of gets().
For an analysis of the script refer to the write-up of the previous challenge, the payloads are meaningfully the same.
0 notes
n3or3trosecurity · 6 years ago
Text
Wargames02 Challenge 1
This is the write-up of my solutions to the COMP6447 Wargames02 ‘jump’ challenge. Challange: Jump Solution: I used binary ninja to reverse engineer the binary in order to gain a deeper insight into the specifics of the program.
Tumblr media
I see that the buffer which gets writes to was put at ebp-0x48. So my initial assumption is to write all 72 Bytes of the buffer and then put the payload at the end in order to overwrite the return address, but this was giving me the results I wanted. I then looked closer at the disassembly and realise that the main function was getting the address of the function it would jump to from ebp-0x08, so I knew I had to shorted my payload by 8 bytes since I wasn’t overwriting the return address directly below this functions stack frame, but rather this function was using a function a pointer to jump to a new function and this pointer was the first thing on the stack. After shortening my payload by 8 bytes, I was able to exploit the flaw.
Tumblr media
Above: the script I used to exploit the vulnarability this program had due to using gets(). the first 6 lines involve storing the address of the win() function which is given as output from the program. We then craft the payload; it begins by creating a string of 64 arbitrary bytes, this is what line 12 is, and then on the next line we add on the address that we want the program to jump to and pack it little-endian because this is how x86_64 Linux reads memory addresses. Essentially the 64 bytes of padding fills up the buffer and then leaves us right at the start of the variable we want to overflow,  we then add the address at the end of the padding and once this is payload is read using gets() the function pointer will be overwritten.
0 notes
n3or3trosecurity · 6 years ago
Text
CRACKME 0x07 Solution
Task: i) Exploit a bug that results in the program printing 'Access granted!'. ii) Modify the binary such that any input results in 'Access granted!'. Solution: i) I was not able to find a ‘bug’ in the program. ii) I was able to modify the binary such that any input resulted in access granted. I did find it quite dificult to figure out how it was to be done though. What helped me solve it was pulling back and zooming out my perspective and taking a high level view. This is why I really like Binary Ninja because this mind-state was facilitated by the fact that I can hold control + scroll my mouse wheel and get as wide a view of the software as I need.
Tumblr media
You get a kind of topographical view, where you don’t care about the details just the inherit shape and form of the program. After looking at it like this I recognized that that we could avoid all the looping logic in the middle and really simplify the problem (so long as doing that doesn’t break anything, which in the real world it may, but in this exercise it did not). Then I ran the binary and nothing really changed, I still wasn’t allowed access, so I looked to see what was blocking me.
Tumblr media
Above: Disassembled Binary after patching out the loop body. As you can see, there are 3 cases that lead to ‘Access denied’:
fgets returned 0 (NULL) meaning it didn’t read a string.
strlen(passwordAttempt) != 7.
and the last route’s logic I can understand but I can’t translate what it means. Essentialy we xor 0 with 1 and then jump to failure if the result == 0 or success otherwise. I am pretty sure this will always jump to access granted since those two items being compared are also 0 and 1.
We can bypass all 3 of these obstacles by altering the comparison in case 2. By changing the 0x7 -> 0x0, and the jne to jl, we get the expression: ‘jump to failure if the strlen returns < 0, which of-course doesn’t happen. So we then proceed through to where case 3. and like I suspected, without any patching we always jump to the Access granted case.
The final patched program disassembled looks like this
Tumblr media
And now grants access no matter the input.
0 notes
n3or3trosecurity · 6 years ago
Text
CRACKME 0x03: Solution
Task: i) Find input that results in the program printing 'Password correct!'. ii) Modify the binary such that any input results in the program printing 'oPassword correct!'
Solution: i) This program doesn't take any input, instead it searched for FLAG in the environment list, and if FLAG=6841 then it prints 'password correct'.
Tumblr media
As we can see in the above photo: in the first block the program calls getenv and if it doesn’t find the variable ‘flag’ in our environment then it goes the ‘Password incorrect’ state. If getenv does return a value, it then converts that value into a long via ‘strtol()’ and then compares it against 6841, if they are equal then it goes to the ‘password correct’ or failure otherwise. So from this we can tell that the flag is 6841. ii) This one took me a while to figure out. I figured the best solution was not to actually modify the binary but rather just to alter my environment so that the program always printed 'password correct'. I did this by modifying my list of environment variables adding FLAG=6841. It made more sense to do this because manipulating the binary wasn't really effective -  as you can see if FLAG isn't an env variable than we aren’t allowed access. You could change this so that it always passes this check, however then you end up in the next part of the program where it expects you to have a received a non-NULL return from getenv, instead we will have received NULL and then we will be trying to de-reference it which will lead to a segmentation fault. The only (not completely necessary) patch I did make was for the program to always jump to ‘password correct even if your FLAG != 6841. I did this to practice mitigating when pieces of software check for the existence and contents of license files. I learnt during my investigation of VSTs (virtual studio technology) that the software will often check a directory for some sort of file and then compare the return of a function that analyses that file. This means that at times it can be enough just for a file or flag to exist, as to get the program into the point of comparing and jumping, and we can then patch these jumps.
0 notes
n3or3trosecurity · 6 years ago
Text
Threat Modelling: An Overview
Threat modelling is a simple and effective tool used for understanding where resources should be allocated when securing any system. It comprises of 3 steps:
Figure out what you consider to be your assets.
Figure out what are the threats to those assets.
Figure out mitigations against those threats.
What are your assets?
An effective and general method of figuring this out is ordering all of your organisations assets. This will require assigning each asset a heuristic value. You will then cut off that list at a certain depth, depending on the amount of resources your company is willing to allocate to security.
What are the threats to your assets?
This essentially means: who would want to compromise your system to get at your assets? and how would they attack you? This is an example of the importance of thinking like an attacker when you’re defending. It’s an effective paradigm for finding and thus being able to patch holes in your system - it’s easier to see the holes in something if you are facing it, rather than with your back to it.
How can we protect our assets?
Now that you know what’s important to your organization and how adversaries will attempt to get at these assets, you need to come up with effective defense mechanisms to protect against these attacks. It should be clear to see that the deeper you consider question one and two, the deeper your possibilities for defenses are. You can only work with the information you have gathered. That’s why the NSA ‘collect everything’.
0 notes
n3or3trosecurity · 6 years ago
Text
CRACKME 0x02 Solution
Task:
i) Find input that results in the program printing 'Password correct!'.
ii) Modify the binary such that any input results in the program printing 'Password correct!'.
Solution:
i) The input that results in the program printing 'Password correct!' is 7623.
Tumblr media
My disassembler has an intermediate medium-IL ASM language, which sits somewhere between raw ASM and C. I used it here to easily track which register contained the pointer to the program arguments. This allowed me to deduce that the the first command line argument was being compared to  0x1dc7, which is 7623 which was the flag.
Tumblr media
I was able to decipher this by checking the conditional that leads to the 'password correct' state, i.e. checking the cmp instruction that compares the argv[1] to some hex value, which was in fact the password.
ii) I was able to do this in just one patch. Initially I was trying to get the program to the state where it prints 'password correct' with as few changes as possible, but I was going the traditional route, i.e. there is an existing path to where the program prints 'password correct' so I'm going to try to force the program down that path every time. I found that I was only able to achieve this with more changes than I felt was elegant. So instead I started from the original binary and realised that rather than force the program down the existing 'password correct' path, I could instead make every path the 'password correct' path. I was able to do this by realising that this binary already contains the data to print 'password correct', so I patched the part of the program that handles incorrect inputs so that it loads that same data and therefore prints 'password correct' no matter the input.
Tumblr media
Above: program in it’s original state.
Tumblr media
Above: I was able to load the same string into rdi by realising that both strings were sitting in memory. So now no matter what the input the program always prints program correct. This may seem like a bit of a cheap way to a solution, but to me it was the simplest way to solve the challenge of: ‘Modify the binary such that any input results in the program printing 'Password correct!'.’
0 notes
n3or3trosecurity · 6 years ago
Text
CRACKME 0x01 Solution
Task:
i) Find input that result in the program printing 'Password correct!'.
ii) Modify the binary such that any input results in the program printing 'Password correct!'.
Solution:
i) The input that results in the program printing 'Password correct!' is 1337.
Tumblr media
As we can see from the above photo of the disassembled binary, if the program gets a non-empty input it tests it against 0x539; which in decimal is 1337. We know this is the flag because, immediately after this value is tested we jump to either ‘password correct or ‘password incorrect’.
ii) I was able to do this in 2 steps.
The first was changing the branch conditions after comparing the user's inputted attempt against the password.
Tumblr media
The instruction is set to jne, i.e. jump if attempt != password. So I patched the binary to ALWAYS jump to the ‘password correct’ case, no matter the input. Thus it no longer matters what the prior cmp instruction evaluates to because the program no longer considers it’s result.
The second was now to change the behavior of the program upon receiving empty input (I’m including no input in the class ‘any input‘ from the task definition).
Tumblr media
As we can see from above the program jumps to the 'password incorrect' case if if rax & rax == 0, where rax is the return from fgets. We know fgets returns NULL when no characters have been read. From this we can deduce that upon empty input the program resolves to ‘password incorrect’ and doesn’t even enter the comparison case.
To get around this, rather than just patching the branch instruction (an equally viable solution), I decided to change the values in the cmp just before the initial branch, if rax == 0, I checked if rax == 1, which would never be the case, because if fgets reads 0 characters than it returns NULL (0) or it returns the string that it read the characters into (which deffs != 1).
Tumblr media
  After these 2 patches the program prints 'password correct no matter the input.
0 notes
n3or3trosecurity · 6 years ago
Text
CRACKME 0x04 Solution
Task:
i) Find input that results in the program printing 'License valid!'. ii) Modify the binary such that any input results in the program printing 'License valid!'.
Solution:
i) The input that results in the program printing 'license valid!' is a file called 'license.txt' with its contents being the number 6447.
ii) I patched the binary such that the comparison that checks the return value of the 'validate_license()’ function to always jumps regardless of the functions return value.
Tumblr media
The above photo is the disassembled binary of the program I am trying to crack. The black arrow points to the instruction “jne ....” which basically says “jump if the 2 values from the previous compare instruction were not equal”. That previous compare is the line directly above: “test al, 0x01″, which is testing if al == 0x01. The register al is the lower 16 bits of rax which is the register used as the return value from the function _validate_license;  al = return value from _validate_license. So with this information we can deduce that if we can either change the test operation or the jmp operation we can control how the program will behave.
Tumblr media
I chose to patch the jmp instruction setting it to always jump to the desired address regardless of _validate_license()’s return value.
The other way to solve this challenge was to realize that _validate_license() checks for a file ‘license.txt’ in the same directory as itself, since this binary was running locally you could have just created a file ‘license.txt’ and wrote the flag to it.
Tumblr media
From the photo above: if we step into the _validate_license() function we can see the value that is compared against license number from “license.txt” - this is the flag. 0x192f when converted to decimal is 6447.
Tumblr media
0 notes
n3or3trosecurity · 6 years ago
Video
tumblr
Neuralink looking for security engineers
0 notes