Automatically fill in captcha code in course selection system

Captcha code is broadly used in different websites to ensure the contents are only accessible by humans rather than bots. The course selection system in my college has also been adopting captcha code in the login page to reduce momentary load of its server. (by slowing down everyone's time to fill in the code and hit log in)

Besides that, the system was kindly designed a "Play Audio" button as well for visually impaired people to "hear" the captcha code. However, it becomes a defect that we can take advantage of the "Play Audio" button function to fill in the captcha code programmatically for us.

Since I have done my last course selection in my college life, I will demonstrate how to fill in the captcha code by exploiting the "Play Audio" button function in below.


To start with, we open the sorcecode page and take a look at the "Play Audio" button code. Whenever the "Play Audio" button is clicked, we can see that the readyAudio() function is invoked.

Let's jump to the readyAudio() function. In line 224, ajax function requests Handler1.ashx for some reason and returns voice object on success in line 229.

The values in voice object are then composed and embedded in playlist array. Because the lenth of the playlist is 6, we can have a guess that each element in the playlist represents the filename of the sound for each number in the captcha code. Therefore, we speculate the behavior of Handler1.ashx is to return the filenames of the sounds of 6 numbers in the captcha code.

Let's see what have been executed in the nextAudio() function.

Exactly that's what we gussed. audio.src gets the element from playlist sequentially and plays the sound file until it loops through everything in playlist array. So if we get the contents in voice object, we can then figure out the 6 numbers in the captcha code.

To verify our assumption, check out the network tab in developer tools. We are using Chrome in this case. After that, by hitting the "Play Audio" button, we can see that ajax requests the Handler1.ashx page.

Handler1.ashx should have successfully returned the voice object so that the 6 sound files are loaded following by it. We should also hear the sounds played after each file is loaded.

If we open the preview page of Handler1.ashx, we can see the content of voice object. Now, we know how everything works.

The next step is to analyze the voice object. Find out the mapping rules that how filenames are mapped to the corresponding numbers. Finally, write a piece of javascript code to automatically get the voice object and convert the filenames as numbers and fill in it as the captcha code.

Let's refresh the login page and click the "Play Audio" button for several times, write down the filenames and the number it represents in javascript object format for number 0 to 9. We now have our mapping rules ready and will be using it later.

var numHash = {
	"b6589fc6ab0dc82cf12099d1c2d40ab994e8410c": "0",
	"356a192b7913b04c54574d18c28d46e6395428ab": "1",
	"da4b9237bacccdf19c0760cab7aec4a8359010b0": "2",
	"77de68daecd823babbb58edb1c8e14d7106e83bb": "3",
	"1b6453892473a467d07372d45eb05abc2031647a": "4",
	"ac3478d69a3c81fa62e60f5c3696165a4e5e6ac4": "5",
	"c1dfd96eea8cc2b62785275bca38ac261256e278": "6",
	"902ba3cda1883801594b6e1b452790cc53948fda": "7",
	"fe5dbbcea5ce7e2988b8c69bcfdfde8904aabc1f": "8",
	"0ade7c2cf97f75d009975f4d720d1fa6c19f4897": "9"
};

I'm not sure that how many people knows Chrome's bookmark supports embedded javascript. We can put our javascript code in the bookmark and execute it by clicking it. It's a handy feature for programmers.

By taking advantage of Chrome's bookmark, lets simulate the ajax request to Handler1.ashx, and get back the voice object. Next, concatenate the 6 numbers represented by the filenames in voice object and fill it into the captcha code field txtCONFM in our login page.

Below is the javascript code I wrote.

javascript: (function() {
	var numHash = {
		"b6589fc6ab0dc82cf12099d1c2d40ab994e8410c": "0",
		"356a192b7913b04c54574d18c28d46e6395428ab": "1",
		"da4b9237bacccdf19c0760cab7aec4a8359010b0": "2",
		"77de68daecd823babbb58edb1c8e14d7106e83bb": "3",
		"1b6453892473a467d07372d45eb05abc2031647a": "4",
		"ac3478d69a3c81fa62e60f5c3696165a4e5e6ac4": "5",
		"c1dfd96eea8cc2b62785275bca38ac261256e278": "6",
		"902ba3cda1883801594b6e1b452790cc53948fda": "7",
		"fe5dbbcea5ce7e2988b8c69bcfdfde8904aabc1f": "8",
		"0ade7c2cf97f75d009975f4d720d1fa6c19f4897": "9"
	};
	$.ajax({
		url: "https://www.xxx.yyy.edu.tw/EleCos_English/Handler1.ashx",
		type: "post",
		async: false,
		success: function(voice) {
			document.getElementById("txtCONFM").value =
				numHash[voice[0]] +
				numHash[voice[1]] +
				numHash[voice[2]] +
				numHash[voice[3]] +
				numHash[voice[4]] +
				numHash[voice[5]];
		}
	});
})();

Remove all the newline characters and white spaces to fit the code into a single row.

javascript: (function(){ var numHash={b6589fc6ab0dc82cf12099d1c2d40ab994e8410c:"0","356a192b7913b04c54574d18c28d46e6395428ab":"1",da4b9237bacccdf19c0760cab7aec4a8359010b0:"2","77de68daecd823babbb58edb1c8e14d7106e83bb":"3","1b6453892473a467d07372d45eb05abc2031647a":"4",ac3478d69a3c81fa62e60f5c3696165a4e5e6ac4:"5",c1dfd96eea8cc2b62785275bca38ac261256e278:"6","902ba3cda1883801594b6e1b452790cc53948fda":"7",fe5dbbcea5ce7e2988b8c69bcfdfde8904aabc1f:"8","0ade7c2cf97f75d009975f4d720d1fa6c19f4897":"9"};$.ajax({url:"https://www.xxx.yyy.edu.tw/EleCos_English/Handler1.ashx",type:"post",async:false,success:function(voice){document.getElementById("txtCONFM").value=numHash[voice[0]]+numHash[voice[1]]+numHash[voice[2]]+numHash[voice[3]]+numHash[voice[4]]+numHash[voice[5]];}}); })();

Creat a new bookmark in Chrome with the javascript code we wrote and save it.

Now everything is ready, lets see how it works.

Bravo. We will never fail the captcha code again from now on.


Leave a Reply