pcme0 (Writeup)

pancrackme: v0

This crackme from crackmes.one was a relatively easy one where the basic idea is the implementaion of multiprocessing using the fork system call and how such challenges can be debugged. My approach was good old gdb and IDAPro where I used IDA for static analysis and decompilation and gdb for the dynamic analysis.

On running the binary!

On running the binary using gdb!

Here we can see that including the parent process there are a total of three processes switching between themselves to finally give the “yeah” output. From the image we can figure out that the first parent process prints the line “pancrackme: v1.0” . And then switches to the new process which writes “Password: ” before it makes the next switch which reads and checks the user input.

Next , on going through the disassembly , we know the second fork call actually produces the process which reads and checks the input. Here the child process . First you follow the default child process on gdb using

$ set follow-fork-mode child

Before the second fork is called , we reset the fork settings on gdb and follow the parent process

$ set follow-fork-mode parent

now in the disassembly we can see that the winwin function as marked and renamed in the following image prints out the yeah statement. In turn it checks our input.

Here we can see a debugger check implementation using ptrace which is bypassed by changing the reaturn value of ptrace.

The lines 49 to 52 can be precisely called the input check where it reads input of maximum 128 characters . If there is a valid input we are taken to the winwin function where the elaborate input check happens in the ‘real_funct’ which on passing allows the filedescriptor to write yeah into the write end of the pipe which is printed if the input is correct.

The check is basically :

input[i]^0x3a==BYTE PTR[arr] // where arr is the hardcoded string in the binary at the location [ 0x804a240+0x7c ] , which can be spotted only on dynamic analysis of the binary. This part of the binary is not decompiled by IDA due to dynamic allocation and unpacking of the binary!

Thus to get the input values, all we have to do is reverse xor the hard coded values and there you have the input to the crack me!

AND FINALLY YEAH! 🙂

HackIm’16 zorro_pub(Writeup)

  • The binary zorro_bin is a stripped file.

In this challenge basically the binary asks you for a number initially, (that is the number of drinks ). And further asks for the drinks’ id’s.If the first input is x, then a loop runs for x times xoring the values of drink id’s , which becomes the seed to a rand function in the code. The drink ids have to have their value in the range (16,0xffff). The seed value is checked against a function which checks whether the bin(seed) has 10 1’s if the condition is satisfied , the seed for the rand function is set and the rand values are updated to a string which is MD5 hashed and eventually checked against a hardcoded hash in the binary. Thats pretty much much it for the description for the challenge.

Solution:

My approach to this was to write a python script to find the input that would give the hash.

import random
import hashlib
from ctypes import *
libc=CDLL('libc.so.6')
arr=[0x3c8,0x32,0x2ce,0x302,0x7f,0x1b8,0x37e,0x188,0x349,0x27f,0x5e,0x234,0x354,0x1a3,0x96,0x340,0x128,0x2fc,0x300,0x28e,0x126,0x1b,0x32a,0x2f5,0x15f,0x368,0x1eb,0x79,0x11d,0x24e]
for j in range(16,0xffff):
    n=j
    c=0
    while(n!=0 and n>0):
        c=c+1
        n=n&(n-1)
    if(c==10):
        n=j
        libc.srand(n)
        c=0
        st=''
        final=''
        for i in range(30):
            a = libc.rand()%1000
            st = st + str(a)
            final = final + chr((a^arr[i])&0xff)
        final =final+'0'
        result = hashlib.md5(st.encode())
        if(result.hexdigest()=='5eba99aff105c9ff6a1a913e343fec67'):
            print(j)
            print(a)
            break

This script will give two outputs the first one being the seed value.