[*Writeup*] Visual Hashing Chrome Extension Reverse-Engineering | CTF Challenge

September 8, 2018 Script hunter

This is a full writeup of recently uploaded ctf challenge Visual Hashing.

Extension Info

Extension will helpful when you don’t ensure that you have typed wrong password or not because it will display four strips of colors on password box that is changing with each key stroke so now you have to remember that colors strip once and then next time when you will type your password again ,you will ensure that you typed Correct password after looking on color strip that you remembered last time.

Challenge Info

: Challenge has given two files – Chrome Extension and Captured Image.
Here you need to decrypt the password that is encrypted with visual hashing in that capture image by Reversing Chrome Extension.

Reverse-Engineering on Chrome Extension

If you are on linux machine,you can find your extension files on path:-$HOME/.config/google-chrome/default/extensions/lkoelcpcjjehbjcchcbddggjmphfaiie.Sometimes .config folder set on hidden so you need to press CTRL + h when you are at $HOME,this will make visible .config folder.
If you are on Window :-C:\Users\User_Name\AppData\Local\Google\Chrome\User Data\Default\Extensions

  1. Here you will find utils.js and some function which generated color strips
  2. function randomizeHash(passwordHash) {
        // Add a little bit of randomness to each byte
        for (var byteIdx = 0; byteIdx < passwordHash.length/2; byteIdx++) {
            var byte = parseInt(passwordHash.substr(byteIdx*2,2),16);
            // +/- 3, within 0-255
            byte = Math.min(Math.max(byte + parseInt(Math.random()*6)-3,0),255);
            var hexStr = byte.toString(16).length == 2 ? byte.toString(16) : '0' + byte.toString(16);
            passwordHash = passwordHash.substr(0,byteIdx*2) + hexStr + passwordHash.substr(byteIdx*2+2);
        }
        return passwordHash;
    }
    
    function getDataURLForHash(passwordHash,inputWidth,inputHeight) {
        var win = window;
        try {
            win = unsafeWindow;   
        }
        catch(e) {}
        var canvas = win.document.createElement('canvas');
        canvas.height = inputHeight;
        canvas.width = inputWidth;
        var context = canvas.getContext('2d');
        
        passwordHash = randomizeHash(passwordHash);
    
        for (var hashBandX = 0; hashBandX < 4; hashBandX++) {
            context.fillStyle='#' + passwordHash.substr(hashBandX*6,6);
            context.fillRect(hashBandX/4*inputWidth,0,inputWidth/4,inputHeight);
            
            context.fillStyle='#000000';
            context.fillRect(((hashBandX+1)/4*inputWidth)-1,0,2,inputHeight);
        }
    
        context.strokeStyle='#000000';
        context.strokeRect(0,0,inputWidth,inputHeight);
    
        return canvas.toDataURL();
    }
  3. So when you enters your password ,function randomizeHash() will first encrypt it in sha1 then takes 24 starting characters and after that this will manipulate(random addition here) every hex character in range of +-[-3,3] and finally split it in 4 division which will be our four colors set.
  4. By using image color picker ,you can find colors RGB value of captured image—Here is a online website for same.
    Visual Hash color RGB VALUE– #e10051 #a5cdf0 #d8922f #b83f16

Final Touch

I wrote a python code which will Brute Force our password and try to match with Visual Hash color RGB value->e10051a5cdf0d8922fb83f16(removed # and spaces).
Payload:= cherry{lowercase three characters}
Password length = 11 = Payload length = Flag length(challenge given).
Python Code:

import hashlib
color = '#e10051#a5cdf0#d8922f#b83f16'
color = color.split('#')
randomizeHash = ''.join(color)

def newrandomizeHash(payload):
	i=0
	check = 0
	newhash = ''
	sha1 = hashlib.sha1(payload.encode()).hexdigest()
	hash = sha1[:24] #takes only up to 24 characters
	while(1):
		for k in range(-3,4):
			if int(hash[2*i:(2*i+2)],16)+k < 16:
				newhash = '0'+hex(int(hash[2*i:(2*i+2)],16)+k)[2:]
			else:
				newhash = hex(int(hash[2*i:(2*i+2)],16)+k)[2:]
			if randomizeHash[2*i:(2*i+2)] == newhash:
				check+=1
		if check>11:
			return 1
		if i==11:
			break
		i += 1

for a in range(ord('a'),ord('z')+1):
	for b in range(ord('a'),ord('z')+1):
		for c in range(ord('a'),ord('z')+1):
			payload = 'cherry{'+chr(a)+chr(b)+chr(c)+'}'
			print 'Trying: '+payload
			if newrandomizeHash(payload):
				print '----------------Possible Flag:'+payload+'-------------------------'
				exit()

Output:-

Flag:- cherry{lol}.
Go challenge page and validate this flag.