Cracking steams CAPTCHA's

joshww

FS Member
well im a computer programmer of about 5 years now and i want to do a few things in the steam community. so my first project is cracking steams CAPTCHA algorithm ... i first started out compering the captchagid to the picture text.. ( example: 108239064573703777 = AQKLZV ) now if you look at many different captcha's you will notice that the first 9 numbers on the captchagid are the same.. so that only leaves 9 left.. now i know steam is a big fan of math as about 2 years ago i broke the agro. to find out your finds steam with out going in game or anything. ( let me know if anyone wants to know how to do that ill post the info) back to captcha's like i said this leaves 9 chr's left. to figure out. so i first thought ok no big deal this will be easy must be some sort of hex based agro.. nope i was wrong as the last 9 numbers are naver the same. even if the image is the same ... this was enticing to me so i looked a lil harder.. still didint come up with anything.. after trying for more then 2 days still nothing all tho i have found somthing that might be worth wild.. and that is steams full java script calls and functions. now with this and maybe someone that knows a lil more then i do when it comes to java script we can break steams CAPTCHA...
Code:
JavaScript - https://steamcommunity.com/

https://steamcommunity.com/public/javascript/global.js

function addEvent(el, ev, fn, useCapture)

{

	if(el.addEventListener)

	{

		el.addEventListener(ev, fn, useCapture);

	}

	else if(el.attachEvent)

	{

		var ret = el.attachEvent("on"+ev, fn);

		return ret;

	}

	else

	{

		el["on"+ev] = fn;

	}

}

function fixFloatHeight(floatDiv, fixedDiv, type, topDiv)

{

	floatDivEl = document.getElementById(floatDiv);

	fixedDivEl = document.getElementById(fixedDiv);

	if(floatDivEl && fixedDivEl)

	{

		floatHeight = floatDivEl.offsetHeight;

		fixedHeight = fixedDivEl.offsetHeight;

		if(type == 1)

		{

			if(topDiv)

			{

				floatHeight += document.getElementById(topDiv).offsetHeight;

			}

			if(floatHeight > fixedHeight)

			{

				fixedDivEl.style.height = floatHeight+'px';

			}

		}

		else

		{

			if(fixedHeight > floatHeight)

			{

				floatDivEl.style.height = fixedHeight+'px';

			}

		}

	}

}



function setCheck(checkDiv, checkField)

{

	realField = eval('document.loginForm.'+checkField);

	curVal = realField.value;

	if(curVal == 0)

	{

		document.getElementById(checkDiv).style.color = '#909090';

		realField.value = 1;

	}

	else

	{

		document.getElementById(checkDiv).style.color = '#000000';

		realField.value = 0;

	}

}



function createQuery(pushUrl, returnFn)

{

	uid = Math.round(Math.random()*100000);

	rUid = "requester"+uid;

	eval(rUid+" = new xHttpQuery();");

	eval(rUid+".pushUrl = pushUrl;");

	eval(rUid+".returnFn = returnFn;");

	eval(rUid+".selfRef = \""+rUid+"\";");

	eval(rUid+".doRequest();");

}



function createQuery2( pushUrl, returnFn, postData )

{

	uid = Math.round(Math.random()*100000);

	rUid = "requester"+uid;

	eval(rUid+" = new xHttpQuery2();");

	eval(rUid+".pushUrl = pushUrl;");

	eval(rUid+".returnFn = returnFn;");

	eval(rUid+".postData = postData;");

	eval(rUid+".selfRef = \""+rUid+"\";");

	eval(rUid+".doRequest();");

}

	



var updateInProgress = false;

function xHttpQuery()

{

	this.pushUrl = '';

	this.selfRef = '';

	this.returnFn = false;

	this.doRequest = function()

	{

		if(updateInProgress == true)

		{

			setTimeout(this.selfRef+".doRequest()", 200);

			return;

		}

//		alert(this.pushUrl);

		updateInProgress = true;

		if(window.XMLHttpRequest)

		{

			req = new XMLHttpRequest();

			req.onreadystatechange = this.returnFn;

			req.open("GET", this.pushUrl, true);

			req.send(null);

		}

		else if(window.ActiveXObject)

		{

			req = new ActiveXObject("Microsoft.XMLHTTP");

			if(req)

			{

				req.onreadystatechange = this.returnFn;

				req.open("POST", this.pushUrl, true);

				req.send();

			}

		}

	}

}



function xHttpQuery2()

{

	this.pushUrl = '';

	this.selfRef = '';

	this.postData = '';

	this.dataEncoded = false;

	this.returnFn = false;

	this.doRequest = function()

	{

		if ( updateInProgress == true )

		{

			setTimeout( this.selfRef + ".doRequest()", 200 );

			return;

		}

		if ( this.dataEncoded == false )

		{

			var pairs = [];

			var regexp = /%20/g;

			for ( var name in this.postData )

			{

				var value = this.postData[name].toString();

				var pair = encodeURIComponent( name ).replace( regexp, '+' ) + '=' + encodeURIComponent( value ).replace( regexp, '+' );

				pairs.push( pair );

			}

			this.postData = pairs.join( '&' );

			this.dataEncoded = true;

		}

		updateInProgress = true;

		if ( window.XMLHttpRequest )

		{

			req = new XMLHttpRequest();

		}

		else if( window.ActiveXObject )

		{

			req = new ActiveXObject( "Microsoft.XMLHTTP" );

		}

		if ( req )

		{

			req.open( "POST", this.pushUrl, true );

			req.onreadystatechange = this.returnFn;

			req.setRequestHeader( "Content-Type", "application/x-www-form-urlencoded" );

			req.setRequestHeader( "Content-Length", this.postData.length );

			req.send( this.postData );

		}

	}

}



function winDim(wh, vs)

{

	if(window.innerWidth) // most browsers - ff, safari, etc

	{

		return (wh == 'w' ? (vs == 'v' ? window.innerWidth : window.pageXOffset) : (vs == 'v' ? window.innerHeight : window.pageYOffset));

	}

	else if(document.documentElement && document.documentElement.clientWidth) // ie strict

	{

		return (wh == 'w' ? (vs == 'v' ? document.documentElement.clientWidth : document.documentElement.scrollLeft) : (vs == 'v' ? document.documentElement.clientHeight : document.documentElement.scrollTop));

	}

	else // ie normal

	{

		return (wh == 'w' ? (vs == 'v' ? document.body.clientWidth : document.body.scrollLeft) : (vs == 'v' ? document.body.clientHeight : document.body.scrollTop));

	}

}



function getGoodElement(el,nn,cn,next)

{

	if(next == 1)

	{

		el = el.parentNode;

	}

	while(el.nodeName.toLowerCase() != nn && el.nodeName.toLowerCase() != "body")

	{

		el = el.parentNode;

	}

	thisClass = ' '+el.className+' ';

	if(el.nodeName.toLowerCase() != "body" && thisClass.indexOf(' '+cn+' ') == -1)

	{

		return getGoodElement(el,nn,cn,1);

	}

	else if(thisClass.indexOf(' '+cn+' ') != -1)

	{

		return el;

	}

	return false;

}

function addGameActions()

{

	if(!document.getElementsByTagName)

	{

		return;

	}

	var pageDivs = document.getElementsByTagName("div");

	for(var x = 0; x < pageDivs.length; x++)

	{

		tempClassName = " "+pageDivs[x].className+" ";

		tempParentClassName = " "+pageDivs[x].parentNode.className+" ";

		if(tempClassName.indexOf(" gameContainer ") != -1 || tempParentClassName.indexOf(" gameContainer ") != -1)

		{

			addEvent(pageDivs[x], "mouseover", listItem_hilite, false);

			addEvent(pageDivs[x], "mouseout", listItem_lolite, false);

			addEvent(pageDivs[x], "click", listItem_toggle, false);

		}

	}

}



function getPopPos(e, pw, ph, offset)

{

	w = winDim('w','v');

	h = winDim('h','v');

	sl = winDim('w','s');

	st = winDim('h','s');

	// mouse x/y within viewport

	vmX = e.clientX;

	vmY = e.clientY;

	// mouse x/y within document

	smX = vmX + sl;

	smY = vmY + st;

	l = (pw > vmX) ? (smX + offset) : (smX - pw - offset);

	t = (ph > vmY) ? (smY + offset) : (smY - ph - offset);

	popTL = new Array(t, l);

	return popTL;

}



function fade(objId, dir, cur, step, spd)

{

	var obj = document.getElementById(objId);

	if(!obj)

	{

		return false;

	}

	if(dir == 'in')

	{

		if(cur == 0)

		{

			obj.style.opacity = 0;

			obj.style.MozOpacity = 0;

			obj.style.KhtmlOpacity = 0;

			obj.style.filter = "alpha(opacity=0)";

			obj.style.display = 'block';

		}

		cur += step;

	}

	else

	{

		if(cur == 0)

		{

			obj.style.display = 'none';

		}

		cur -= step;

	}

	obj.style.opacity = (cur / 100);

	obj.style.MozOpacity = (cur / 100);

	obj.style.KhtmlOpacity = (cur / 100);

	obj.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity="+cur+")";

	

	setTimeout("fade('"+objId+"','"+dir+"',"+cur+","+step+","+spd+")", spd);

}



var keepTooltip = false;

function tooltipCreate(tipEl, e)

{

	ttEl = document.getElementById('tooltip');

	if(ttEl)

	{

		ttEl.parentNode.removeChild(ttEl);

	}

	ttEl = document.createElement('div');

	ttEl.id = 'tooltip';

	ttEl.style.position = 'absolute';

	ttEl.appendChild(tipEl);

	document.getElementsByTagName('body')[0].appendChild(ttEl);

	tipTL = getPopPos(e, ttEl.clientWidth, ttEl.clientHeight, 6);

	ttEl.style.top = tipTL[0] + 'px';

	ttEl.style.left = tipTL[1] + 'px';

}



function tooltipDestroy(go)

{

	if ( go != 1 )

	{

		setTimeout( "tooltipDestroy(1)", 10 );

	}

	else

	{

		ttEl = document.getElementById('tooltip');

		if(ttEl)

		{

			ttEl.parentNode.removeChild(ttEl);

		}

	}

}



function getElement( elementId )

{

	var elem;

	if ( document.getElementById ) // standard compliant method

		elem = document.getElementById( elementId )

	else if ( document.all ) // old msie versions

		elem = document.all[ elementId ]

	else

		elem = false;



	return elem;

}



function setImage( elementId, strImage )

{

	var imageElem = getElement( elementId );

	if ( !imageElem ) 

		return;



	imageElem.src = strImage;

}



function iSwapFullURL( imgID, newImg )

{

	newImgPath = newImg;

	setImage( imgID, newImgPath );

}





function iSwap( imgID, newImg )

{

	newImgPath = "https://steamcommunity.com/public/images/" + newImg;

	setImage( imgID, newImgPath );

}



function setTimezoneCookies()

{

	var now = new Date();

	var expire = new Date();



	// One year expiration, this way we don't need to wait at least one page

	// load to have accurate timezone info each session, but only each time the user

	// comes with cleared cookies

	expire.setTime( now.getTime() + 3600000*24*365 );

	tzOffset = now.getTimezoneOffset() * -1 * 60;

	isDST = 0;

	document.cookie = "timezoneOffset=" + tzOffset + "," + isDST + ";expires="+expire.toGMTString() + ";path=/";

}





// We always want to have the timezone cookie set for PHP to use

setTimezoneCookies();



function toggleAbuse()

{

	abuseDiv = document.getElementById( 'reporter' );

	if ( abuseDiv.style.display != 'block' )

	{

		abuseDiv.style.display = 'block';

	}

	else

	{

		abuseDiv.style.display = 'none';

	}

}



function setupSteamLinks()

{

	anchors = document.getElementsByTagName( 'a' );

	for( x = 0; x < anchors.length; x++ )

	{

		thisA = anchors[x];

		tmpClass = ' ' + thisA.className + ' ';

		if ( tmpClass.indexOf( ' steamLink ' ) != -1 )

		{

			addEvent( thisA, 'mouseover', showSteamTooltip, false );

			addEvent( thisA, 'mouseout', tooltipDestroy, false );

		}

	}

}



function showSteamTooltip(e)

{

	var srcEl = window.event ? window.event.srcElement : e ? e.target : null;

	if(!srcEl)

	{

		return;

	}

	linkA = getGoodElement(srcEl, 'a', 'steamLink', 0);

	if(!linkA)

	{

		return;

	}

	thisTip = document.createElement('div');

	thisTip.className = 'steamTooltip';

	thisTip.style.width = '32px';

	thisTip.style.height = '32px';

	steamImg = document.createElement( 'img' );

	steamImg.src = 'https://steamcommunity.com/public/images/skin_1/steamTooltip.jpg';

	steamImg.style.border = 'none';

	steamImg.style.width = '32px';

	steamImg.style.height = '32px';

	thisTip.appendChild(steamImg);



	tooltipCreate(thisTip, e);

}



function setupFriendBlockHoverIE6()

{

	if ( vIE() != 6 )

	{

		return;

	}

	if ( document.getElementById( 'friendBlocks' ) )

	{

		allDivs = document.getElementById( 'friendBlocks' ).getElementsByTagName( 'div' );

		for( x = 0; x < allDivs.length; x++ )

		{

			div = allDivs[x];

			if ( div.className.indexOf( 'friendBlock_' ) != -1 )

			{

				addEvent( div, 'mouseover', friendBlockHighlightIE6, false );

				addEvent( div, 'mouseout', friendBlockLolightIE6, false );

			}

		}

	}

}



var currentHigh = false;

var waitEl = false;

function friendBlockHighlightIE6()

{

	var srcEl = window.event ? window.event.srcElement : null;

	if(!srcEl)

	{

		return;

	}

	var friendClasses = new Array( 'friendBlock_offline', 'friendBlock_online', 'friendBlock_in-game', 'friendBlock_ignored' );

	for ( x = 0; x < friendClasses.length; x++ )

	{

		var thisClass = friendClasses[x];

		div = getGoodElement( srcEl, 'div', thisClass, 0 );

		if ( div )

		{

			break;

		}

	}

	if(!div)

	{

		return;

	}

	div.className = thisClass + ' friendHighlight';

	currentHigh = div;

}



function friendBlockLolightIE6( )

{

	var srcEl = window.event ? window.event.srcElement : null;

	if(!srcEl)

	{

		return;

	}

	var friendClasses = new Array( 'friendBlock_offline', 'friendBlock_online', 'friendBlock_in-game', 'friendBlock_ignored' );

	for ( x = 0; x < friendClasses.length; x++ )

	{

		var thisClass = friendClasses[x];

		div = getGoodElement( srcEl, 'div', thisClass, 0 );

		if ( div )

		{

			break;

		}

	}

	if(!div)

	{

		return;

	}

	div.className = thisClass;

}



function vIE()

{

	return (navigator.appName=='Microsoft Internet Explorer') ? parseFloat( ( new RegExp( "MSIE ([0-9]{1,}[.0-9]{0,})" ) ).exec( navigator.userAgent )[1] ) : -1;

}



function checkAbuseSub()

{

	if ( !document.getElementById( 'contentType2' ).checked && !document.getElementById( 'contentType3' ).checked && !document.getElementById( 'contentType4' ).checked )

	{

		alert( 'Please select a reason for reporting abuse' );

		return false;

	}

	document.getElementById( 'abuseForm' ).submit();

}



addEvent(window, "load", setupSteamLinks, false);




https://steamcommunity.com/public/javascript/home.js


function setLoginFocus()

{

	focalbox = document.getElementById('steamAccountName');

	if ( focalbox )

	{

		focalbox.focus();

	}

}





addEvent( window, 'load', setLoginFocus, false );





var iRefreshes = 0;

function RefreshCaptcha()

{

	// Adding count to prevent caching

	URL = captchaRefreshURL + '?count=' + iRefreshes++;

	createQuery( URL, ReceiveCaptchaRefreshData );

}





function ReceiveCaptchaRefreshData()

{

	if ( req.readyState == 4 )

	{

		if ( req.status == 200 )

		{

			gid = req.responseText;

			if ( gid != -1 ) 

			{

				iSwapFullURL( 'captchaImg', captchaImgURL+'?gid='+gid );

			}

			document.getElementById('captchagid').value = gid;

		}

		// annoying global in our ajax functions, which prevents new ajax calls until

		// reset...

		updateInProgress = false;

	}

}


Inline Script from https://steamcommunity.com/

var captchaRefreshURL = 'https://steamcommunity.com/actions/RefreshCaptcha';
var captchaImgURL = 'https://steamcommunity.com/public/captcha.php';
 
yea my main goal is to make a data site.. but yes this will enable ppl to make a brute forcer. i made a brute forcer about 3 years ago i was the first to do so. it was befor steam ever hade a http login and i did it all with api. we got a lot of steam accounts back then we even figured out that if the account was a email it was a low digit then i figured out a way to find out what the steam id was for ppl on your friends list ( so if you added someone to your friends you could then check to see what steam id it was ) this is becuz steam used your registry to save this info and they used a numric key to save the user.... well that numric key was also the steam id to that user.. you just hade to decode it and it wasent hard at all some very simple math...


soooooo needless to say we cracked a few 2 digits a few valve admin and a few 3 , 4 digits and a lot of 5 and 6 digits it was fun but im over that stage in my programing and on to more community based stuff.
 
Easiest approach would be to build a database of all the image guids and match them but that would take a really long time, how did you find an algo the first time?

And there are 17 digits in the guid, during my test the last 7 digits changed so we can assume there are 9,999,999 combinations.

When you reload the captcha image the text remains the same so we COULD build a db
 
to build a db is well trash that would take along time and well not fast enuff.. we could go proxy route.. and say f* the image. and use a list of proxys and changed them every login. iv did this befor for a few other login. and well its not hard just not alll that fast. but would be faster then using a db.
 
sorry for the double post the edit button would not click. but here i made a simple login script in vb6 using inet controll to play about a bit. ... i was going to go winsock and use my ssl user control i made a while back but seems steam has a newer version of ssl then my control. ( will need to update my control )

but with inet it has all options built in to use a proxy and such.

here is the source code iv commented it so that ppl that dont know much can understand.
 

Attachments

  • steam_inet.zip
    2.4 KB · Views: 7
I think in order for this to be reasonable at all then we are going to have to crack the algo or find some way to get the text out of the image.

If someone knows java here then we can edit the megaupload OCR script to accommodate our needs. This way we don't have to worry about proxies or large databases it can be 100% dynamic.
 
Back
Top