Skip to content

Instantly share code, notes, and snippets.

@vqhuy
Forked from TylerOderkirk/crackme.c
Last active August 3, 2016 16:26
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save vqhuy/c6b3a603f6671c62a785 to your computer and use it in GitHub Desktop.
Save vqhuy/c6b3a603f6671c62a785 to your computer and use it in GitHub Desktop.
A demonstration of Markus Gaasedelen's method for reversing a binary - see URL in find_password.py
#include <stdlib.h>
#include <stdio.h>
void main(int argc, char *argv[])
{
if( argv[1][0] == 'f' ) {
if( argv[1][1] == 'o' ) {
if( argv[1][2] == 'o' ) {
if( argv[1][3] == '\x00' ) {
printf( "good password\n" );
} else {
printf( "bad password\n" );
}
} else {
printf( "bad password\n" );
}
} else {
printf( "bad password\n" );
}
} else {
printf( "bad password\n" );
}
}
#!/usr/bin/env python
# see http://gaasedelen.blogspot.com/2014/09/solving-fireeyes-flare-on-six-via-side.html
# another approach: http://www.ghettoforensics.com/2014/09/a-walkthrough-for-flare-re-challenges.html
# we use the inscount0 example tool included with pin. extract pin and run 'make' in
# source/tools/ManualExamples on linux to build the tool.
from subprocess import Popen, PIPE
import operator
PIN_PATH = "/home/tz/src/pin-2.14-67254-gcc.4.4.7-linux/"
EXAMPLE_TOOLS_PATH = "source/tools/ManualExamples/obj-intel64/"
def get_instruction_count(password):
p = Popen([PIN_PATH + "pin", "-t", PIN_PATH + EXAMPLE_TOOLS_PATH + "inscount0.so", "-o", "/dev/stdout", "--", "./crackme", password], stdout=PIPE)
instruction_count = int(p.communicate()[0].splitlines()[1].split(" ")[1]) # stdout, second line, second space-separated word
return instruction_count
if __name__ == '__main__':
password = ""
# build the password one character at a time
while True:
instruction_counts={}
for char in "abcdefghijklmnopqrstuvwxyz":
instruction_count = get_instruction_count(password + char)
print( "tried password '%s'. %d instructions were required." % (password + char, instruction_count))
instruction_counts[char]=instruction_count
if len(set(instruction_counts.values())) > 2:
print( "warning: more than 2 distinct instruction counts were found." )
elif len(set(instruction_counts.values())) == 1:
print( "quitting. instruction counts were the same for all attempts." )
break
# sort the instruction counts in descending order and append the character that gave us the highest count to the password
password += sorted(instruction_counts.items(), key=operator.itemgetter(1), reverse=True)[0][0]
print( "password: '%s'" % (password))
$ ./find_password.py
tried password 'a'. 100080 instructions were required.
tried password 'b'. 100080 instructions were required.
tried password 'c'. 100080 instructions were required.
tried password 'd'. 100080 instructions were required.
tried password 'e'. 100080 instructions were required.
tried password 'f'. 100088 instructions were required. <--
tried password 'g'. 100080 instructions were required.
[...]
tried password 'foow'. 100102 instructions were required.
tried password 'foox'. 100102 instructions were required.
tried password 'fooy'. 100102 instructions were required.
tried password 'fooz'. 100102 instructions were required.
quitting. instruction counts were the same for all attempts.
password: 'foo'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment