Saturday, 17 February 2018

Buffer overflow vulnerability

Stack overflow and Buffer overflow are very interesting vulnerabilities, basically if exploited correctly; Hacker could gain complete access to program or machine. This class of vulnerability is also hard to exploit.

Today, In this post I will show few examples of buffer vulnerability, take an example program and then exploit it. Let's first jump to what is buffer overflow?

 void echo()  
   char msg[100];  
   scanf("%s", msg);  
   printf("echo: %s\n", msg);  

Looks good right? How can someone hack this program? And even if they can, what can they do with it?

scanf doesn't know the size of buffer, if a user enters a string more than 100 chars (or even 100), code will corrupt program's stack. So what? program might crash? yep, it will. But a perfect exploit can a do lot with this. Let me give you an example, you have a webserver running an echo service something like that. Because most of time webservers are running as a root program. Hacker can enter a malicious message that let hacker control your root "shell". Hacker will run arbitrary commands on your web server with root privilege. Woah! Practically, Hacker can do anything after that.

How the hackers do that? To understand working of the concept we need to jump into machine's code. I am assuming intel x86 cpu (32bit).

     push    ebp  
     mov    ebp, esp  
     sub    esp, 136  
     lea    eax, [ebp-108]  
     mov    DWORD PTR [esp+4], eax            ; *msg
     mov    DWORD PTR [esp], OFFSET FLAT:LC0  ; "%s\0"
     call    _scanf  
     lea    eax, [ebp-108]  
     mov    DWORD PTR [esp+4], eax            ; *msg
     mov    DWORD PTR [esp], OFFSET FLAT:LC1  ; "echo: %s\12\0"
     call    _printf  
command: gcc -S main.c -m32 -masm=intel

As expected, compiler make room for "char msg[100]" on stack and then pass pointer to this array on stack along with pointer to format string and then call "_scanf" function. Let's look at user's stack

 <-- caller's program counter -->  
 <--       EBP (4 bytes)      -->    ; push ebp  
 <--  empty room (136 bytes)  -->    ; sub esp, 136  

It looks like compiler allocated extra space on stack for optimization reason (stack alignment). Next instruction in series is interesting because it tell us about location of "msg" on stack.

 lea  eax, [ebp-108]  

lea stands for load effective address, so basically "eax = ebp - 108", eax contains pointer to msg because this is passed as the second argument while calling _scanf. Great! so we know out of 136 bytes, higher 108 bytes is for msg. Now our stack looks something like this

 <-- caller's program counter -->  
 <--       EBP (4 bytes)      -->  
 <--      msg (108 bytes)     -->  
 <--  empty room (28 bytes)   -->  

if a user enters 108 bytes of data in input, it will overwrite EBP pointer on the stack which will crash program later but what if we overwrite caller's program counter? Look at last few instructions


"leave" is short-hand for:
     mov esp, ebp  
     pop ebp  
exactly opposite of first few instruction where we copy esp to ebp and push ebp.

so if we have corrupted saved ebp on stack then we can control the value of ebp register after execution of "leave" instruction.

Next instruction we have is "ret", it simply pop "callers instruction pointer" and make a jump there. This is where things go interesting. We can corrupt stack and corrupt caller's saved pointer. so effectively we can control program counter and ebp (base pointer). controlling program counter is like making a jump instruction in the program with the privilege program is running with.

So, here's the exploit; we write machine code in memory that will execute "shell" using execv system call. then we corrupt base pointer and instruction pointer and make it jump to our shellcode. Awesome! after doing that we will be running a shell inside this program.

Thursday, 14 December 2017

Hash forgery

In my opinion, Hashing is one of the best invention in the field of algorithms. You can do so much with hashing, And the mathematics behind all of the hash functions are so amazing! Though it comes with a lot of risks, implementing your own hash function is very challenging. It is because there are uncountably many ways to do it incorrectly!

Hash functions have lots application, Today I will talk about key generation technique. and how to forge it. Interesting?

so, let's see first what is key generation?

def generate_key(msg):
if is_valid(msg):
return sha256(SOME_MAGIC || msg)
raise ValueError('invalid message')

def submit(key, msg):
if key != generate_key(msg)
return -1
return 0

Target is to get an invalid message successfully accepted by submit procedure. You might be wondering what is the application of this.

Imagine a case, server generates a cookie and inject that in your browser, everytime you visit the website server check if cookie is valid or not. if it is valid then get data from cookies. Interesting right?

so how to forge it? Is it possible to get a invalid message accepted by the server? And Is it valid for every key generation function?

This code is vulnerable because of this line return sha256(SOME_MAGIC || msg). So what is wrong with this line? we are simply appending message to some internal magic string which is unknown to attacker and finding hash of it, even I have used this way of generating key many time when I was not so much in cryptography.

To see what is wrong with this method of hashing we need to find how sha256 works.

def sha256(msg):
""" Return the SHA-256 hash of msg as a hex string. """
# Pad the message
msg = pad_message_512(msg)
# Initialization vector
md = [0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19]
# Break msg into 512-bit chunks
view = memoryview(msg)
for chunk_num in range(0, len(msg), CHUNK_SIZE):
chunk_start = chunk_num * CHUNK_SIZE
process_chunk(md, view[chunk_start:chunk_start + CHUNK_SIZE])
# Produce the final value
return hexdigest(md)
this is my implementation of sha256

if you are not good at reading python code:
1) pad the message with zeros (roughly)
2) process message in the blocks of size 512-bits
3) return internal register values in string format

Before reading further you take your time to figure out what is wrong with that generate_key function, it should be clear by now.

So, sha256 returns the value of internal register, which gets updated after processing each chunk of 512 bits right? if I call generate_key("") it should return hash of empty message.

Assume empty string is a valid message and SOME_MAGIC hash length less than 512 bits. what you can say about key now?

Can we say key is actually internal state of sha256 after processing SOME_MAGIC || PADDING (size 512 bits). what if I know this internal state can I use it to call process_chunk again with next 512-bit block of data? ofcourse! And do I need SOME_MAGIC to know what will be hash of this new added block if I have passed it through generate_key. NO!

putting it all together
1) generate key of empty message.
2) split key into 8-internal registers
3) convert your invalid data into bits and add necessary padding
4) use 8-internal registers and your data block to generate new key.

This hack is valid on all hashing function that process data this way. So, never hash data this way. Happy Hacking!

Saturday, 24 June 2017

Editing WhatsApp Message

First thing, It's not really a vulnerability or something. It's like tricking WhatsApp sandbox environment. But I will still recommend to use it for educational purpose only and any illegal use of the tool is not my responsibility.

Proof of Concept video first!

Looks cool, right?
You can download the tool and script I created which automates all the process, from here:

What you need to run the script ?
1. Android device with WhatsApp Installed :p
2. adb.exe should be in path
3. Developer Option should be enabled
4. Python3

How it works?
1. Install WhatsApp with API level < 21.
2. Get the WhatsApp backup
3. Decompress and extract mgstore.db
4. Edit the database file
5. Compress and Pack database file again into android backup file
6. Restore the backup

PS. Kudos to my friend Garvit. but wait I don't have permission from him to post this video :p Please hope he don't kill me for this xD

Friday, 10 March 2017

Atom OS: Why Open Source?

5th March, 2017. It was a beautiful Sunday. I woke up late as usual. Though next day I had Advanced Computer Architecture exam but I decided to take a look at some unfixed bugs in Atom and study for exam later in night. I was coding, building and testing in repeat for continuously 2 hour. But I don't know how it come to mind that "let's make it open source today".
I was thinking about making it open source from a long time. But was not fully convince to make it. why? From the very first day, I was fully committed to every piece of code. But things was not working that way anymore. I was still fully committed but hard to hold myself to see the big picture. I don't know if that was my failure and I was not capable of it from starting.
It still don't make sense why I open sourced, right? It is something which I never wanted it to discuss with anyone. I failed in interviews and many other things one-by-one. Story date back to 1st Aug, 2016. First Company which visited our Campus (NSIT) was Amazon for internship. I applied and qualified for face-to-face interview round. what happen next was something I never expected! I actually failed in interview! I failed to complete code on paper. And so I was rejected.
It was an evaluation time something which I always do after a major failure. where I went wrong? Guess what. It isn't difficult to answer this question. I didn't prepare for interviews (during summer vacation) I was doing GSoC and rest of time contributing to Atom. I am not really giving any excuse. Things don't come easy You always have to work for it! I didn't sit for any other campus interview because I didn't had enough courage to face it again. Thanks to Manraj sir who tried his best to take me out of depression! I started preparing for interviews and applied in Directi (off campus). 5th October, 2016. I remember everything date-by-date time-by-time. 13.30 I had my first interview in Directi office. It went good. I completed code in 15 minutes (out of 40 minutes). In the last interview. I was able to find the optimal algorithm but failed to debug my code on time. Result? I was rejected in the interview! haha! what could be the excuse this time? I don't know. But I prepared hard for my next interview. I mean I seriously did. My third interview was with Google USA. I got a call for telephonic round. But despite of having great interviews I was still rejected. Feedback? None. This was something where I gave up. I really did well in interview. I remember my last interview It was a guy from Google HQ working in search engine team. He asked one question I answered two! and he was like "oh! you just answered my next question" and indeed we completed interview before time and discussed some other stuffs in last 10 minutes. I don't know where I failed? My grades? Probably. when you face a failure you count every negative thing.

Fast forward 4 months! I open sourced Atom!

why? I didn't had enough belief in myself that I can pull it anymore. But something else happened that day. It went trending. woah! I was not expecting that :') I was not enjoying the fame I was building up my confidence. oh! I am really sorry for spamming on Facebook I know it was childish.

People were discussing about Atom. They were amazed to see the code base. Reddit.

Discussing on Forums:


Hey Google, you rejected me na?

Retweeting everywhere:

That felt amazing!

I got new ideas for Atom from some amazing people. I have new motivation now. don't know where will it go from here. But I am again committed to it!


Monday, 16 November 2015

Vulnerability in OJs

23rd of May, 2015 00:50

That day :')
I already had a piece of code which I wrote 1 week ago and which was capable of reading files on ideone with system calls. But the problem was, I don't have sufficient permission to read every file *I was not the root user*. New idea was to call own process continuously so that I can make system out of run of its resources. And It will definitely work because I have enough permission to execute binary of my own parent process.

I was testing on ideone only that time; using system call to get shell access was very clever idea but I was not the root user so I had restriction on the commands which I can execute. My idea of executing own process continuously itself had some hurdles.

Q: What is the location of compiled code binary?
Well, It is really difficult to this answer that time, Because I had no idea what is the name of file and I had limitations to the output screen buffer, So; I can't really use search option. What's next? I had only two ways, 1) Brute 2) Guess; I started making some guess. I was really lucky that time; I got the correct path by just making few guesses.

Q: How I confirmed that the path is correct?

Okay, very first thing I checked was file creation time; But that doesn't prove anything at all; I need a strong evidence to prove my statement correct. next? I edited my code and declared a static global int variable with a value 0xDEADCAFE. Great! Now I went back to that directory and tried to search these four bytes in the compiled binary. Awesome! It said one match found.

My final code to execute own process continuously on the server.

Code was working perfectly on ideone and codechef; So I immediately inboxed an email to their security team. Clock was striking 04:00 and I was really excited to test my code on other OJs like Hackerrank, Codeforces and HackerEarth.

Started doing the same thing with Hackerrank website. But no luck this time. They have things working in a very beautiful way!

Take a look at this directory:
We have everything here; Input file, output file and compiled binary. Can we read input files? Yes!! But No use :/ we have no buffer screen to write test cases at the time of submission. Now what? Sleep :p

After enough sleep I went back to work. Here's the explanation of problem.
We have access to test cases right? But these are the test files on which current code is being processed so it means no hidden test cases are listed in this directory.

Q: Is there any possibility that on submission, It will have hidden test files too in this directory?
Umm, maybe; Lets try. I just modified my C code this way that It creates a runtime error if there are more input*****.in files in the directory.
Result? Runtime Error :D (First time in my life when I was happy with a runtime error :p)

Q: Can I get a buffer to transfer data from runtime submission to website screen?
I can't, Submissions has no output window.

Q: Any workaround?
Meanwhile I was playing a bit with commands,  And guess what? I was able to create directories in some corner of server. Great! But once I created the file I can't read it from other process :/ So no use? Nah!
Finally the Exploit: I will create files and folder with the same name as that of test cases!!!

Proof Of Concept

I reported it as soon as I completed the making of proof of concept video. Thanks to Manraj sir for contact details :D
I was feeling lazy to test other OJs so I planned to wait for the reply of these two mails and will exploit other websites later. (HackerEarth was vulnerable, while CodeForces was not)
Bad decision! Next time when I went to HackerEarth It was already patched! God knows how.

Tuesday, 10 November 2015

First Post

As the title suggests; This is my first blog post. I don't know from where I should start, But I am going to share every experience of my life with the reader. And I will be happy to hear back. Before you move on reading my blog, One thing I state clearly that my english is not good so please ignore errors. Thanks :D !

I am Aman Priyadarshi, a computer enthusiast who loves to write software and hunt bugs; That's All!

Let's start from the beginning.... It was jan 11, 2007 when I first time booted up a computer. windows XP dual core; Latest that time. The moving cursor excited me and way computer was doing so many things at one time. That time I played a lot with mspaint; Guess what? I started photo editing with mspaint, sounds unbelievable? photo editing with mspaint!! I was only in 6th standard what you can expect more? So photo editing (:p) changing each pixel color manually to its background pixel color!! My first bad experience with computer was when I accidently moved all excel sheet (which was on desktop) to Recycle bin; And I was afraid to tell this to my father. (I thought that I deleted all files) later on, papa told me about Recycle bin (:p)
Okay fast forward a bit; The first time I logged on Internet was back in 2009; Another exciting thing!! I use to search for games online/offline multiplayer/AI etc; The first 3D game I played was "Spiderman"; But slowly my mind start diverging from games, I started searching for "How to make softwares" (I was not good at googling that time :p) I followed series of tutorials and articles to get some concept; And I started my journey with VB.NET made few (crappy xD) softwares. This is how I started my development field.

Hacking is something that sounds very interesting to anyone; But being good at it is also difficult. During googling tutorials, I use to search for "Notepad virus" "batch virus" "hacking facebook account" (crap xD) tutorials too! Following those tutorials was fun xD
Hacker is someone who knows really in depth of computer working. But I continued searching some hacking keywords and hackers blog. Guess what? I failed lot of times to understand some basic concepts until I seriously took this leaving behind my development, Because I was failing at that too!
At last I succeed in understanding working concepts.

Things took a long nap due to board exams, followed by JEE preparation...But I was still continuing development (only). I continued my Hacking profile only after getting into the college; basically After the hacking workshop (by IEEE-NSIT :p) which motivated me to explorer this field again. This is basically how I continued my hacking profile, And I am really enjoying this now! Thanks for that motivation :D !

Coder? yeah, I started sport programming too after getting into the college; october 2014 I guess; The first time I solved any competitive programming question. And after nearly in one year I explored this field a lot. These ACs TLEs WAs are something that keep coder busy in solving problems. But Guess what? I am not continuing this profile anymore, I failed more than I succeed... leave. :)

I will keep updating this blog with some of my experiences and development diaries :D !

I didn't mention anything about "Atom OS" development in this, because it is a different story :p