RSS

Hack.LU CTF 2012: Big Zombie Business writteup

0 Comments | This entry was posted on Oct 25 2012

It’s a disaster! Not only that these useless piles of rotten meat obfuscate all their stupid code, they have also lost our precious root password, or “Flag” as they call it. Is there a chance you can reverse this obfuscation to extract the Flag?

credits: 200 +3 (1st), +2 (2nd), +1 (3rd)

So, we started to access the page in browsers. In chrome I couldn’t access it, so I used firefox instead for this challenge.

Now let’s see the source:


html,body{background:#000;height:100%;min−height:100%}#zombie{border:1px solid #fff;}#zombie2{color:#fff}
(\u0066\u0075\u006e\u0063\u0074\u0069\u006f\u006e(){\u0069\u0066(\u0074\u0079\u0070\u0065\u006f\u0066 \u0063\u006f\u006e\u0073\u006f\u006c\u0065==\u0075\u006e\u0064\u0065\u0066\u0069\u006e\u0065\u0064)\u0063\u006f\u006e\u0073\u006f\u006c\u0065={'\154\157\147':\u0066\u0075\u006e\u0063\u0074\u0069\u006f\u006e(){}};\u0073\u0065\u0074\u0049\u006e\u0074\u0065\u0072\u0076\u0061\u006c((\u0066\u0075\u006e\u0063\u0074\u0069\u006f\u006e(){\u0076\u0061\u0072 \u0063=\u0063\u006f\u006e\u0073\u006f\u006c\u0065.\u006c\u006f\u0067;\u0076\u0061\u0072 \u0075=\u0066\u0075\u006e\u0063\u0074\u0069\u006f\u006e(){\u0063('45\143\102\162\141\141\141\141\101\101\101\111\116\132\132\132\132','\143\157\154\157\16272\162\145\14473\146\157\156\16455\163\151\172\14572626060\160\17073')};\u0075(),\u0075(),\u0075();\u0072\u0065\u0074\u0075\u0072\u006e \u0075})(),100);\u0066=\u0066\u0075\u006e\u0063\u0074\u0069\u006f\u006e(){\u006c\u006f\u0063\u0061\u0074\u0069\u006f\u006e='\156\157\146\154\141\147'};\u006e={\u0076\u0061\u006c\u0075\u0065:\u0066,\u0063\u006f\u006e\u0066\u0069\u0067\u0075\u0072\u0061\u0062\u006c\u0065:\u0066\u0061\u006c\u0073\u0065};(\u0061=\u0064\u006f\u0063\u0075\u006d\u0065\u006e\u0074.\u0061\u0064\u0064\u0045\u0076\u0065\u006e\u0074\u004c\u0069\u0073\u0074\u0065\u006e\u0065\u0072)('\104\117\115\101\164\164\162\115\157\144\151\146\151\145\144',\u0066,\u0066\u0061\u006c\u0073\u0065);a('\104\117\115\116\157\144\145\111\156\163\145\162\164\145\144',\u0066,\u0066\u0061\u006c\u0073\u0065);\u0061('\104\117\115\103\150\141\162\141\143\164\145\162\104\141\164\141\115\157\144\151\146\151\145\144',\u0066,\u0066\u0061\u006c\u0073\u0065);\u0066\u006f\u0072(\u0069 \u0069\u006e \u006d=['\167\162\151\164\145','\167\162\151\164\145\154\156','\143\162\145\141\164\145\105\154\145\155\145\156\164','\141\160\160\145\156\144\103\150\151\154\144','\143\154\157\156\145\116\157\144\145','\151\156\163\145\162\164\102\145\146\157\162\145','\162\145\160\154\141\143\145\103\150\151\154\144','\143\162\145\141\164\145\105\154\145\155\145\156\164\116\123'])\u004f\u0062\u006a\u0065\u0063\u0074.\u0064\u0065\u0066\u0069\u006e\u0065\u0050\u0072\u006f\u0070\u0065\u0072\u0074\u0079(\u0064\u006f\u0063\u0075\u006d\u0065\u006e\u0074.\u0063\u006f\u006e\u0073\u0074\u0072\u0075\u0063\u0074\u006f\u0072.\u0070\u0072\u006f\u0074\u006f\u0074\u0079\u0070\u0065,\u006d[\u0069],\u006e);\u0076\u0061\u0072 \u0079=\u0061\u006c\u0065\u0072\u0074;\u004f\u0062\u006a\u0065\u0063\u0074.\u0064\u0065\u0066\u0069\u006e\u0065\u0050\u0072\u006f\u0070\u0065\u0072\u0074y(\u0077\u0069\u006e\u0064\u006f\u0077,'\141\154\145\162\164',{\u0076\u0061\u006c\u0075\u0065:\u0066\u0075\u006e\u0063\u0074\u0069\u006f\u006e(){\u0079('\142\162\141\141\141\151\156\172\172\172')},\u0063\u006f\u006e\u0066\u0069\u0067\u0075\u0072\u0061\u0062\u006c\u0065:\u0066\u0061\u006c\u0073\u0065});\u0076\u0061\u0072 \u007a=\u0070\u0072\u006f\u006d\u0070\u0074;\u004f\u0062\u006a\u0065\u0063\u0074.\u0064\u0065\u0066\u0069\u006e\u0065\u0050\u0072\u006f\u0070\u0065\u0072\u0074\u0079(\u0077\u0069\u006e\u0064\u006f\u0077,'\160\162\157\155\160\164',{\u0076\u0061\u006c\u0075\u0065:\u0066\u0075\u006e\u0063\u0074\u0069\u006f\u006e(\u0071){brain(z('\127\150\141\16447\16340\155\17140\172\157\155\142\151\14540\156\141\155\14577'),\u0071)},\u0063\u006f\u006e\u0066\u0069\u0067\u0075\u0072\u0061\u0062\u006c\u0065:\u0066\u0061\u006c\u0073\u0065});\u0066\u006f\u0072(\u0069 \u0069\u006e \u006d=['\143\157\156\146\151\162\155','\143\157\156\163\157\154\145'])\u004f\u0062\u006a\u0065\u0063\u0074.\u0064\u0065\u0066\u0069\u006e\u0065\u0050\u0072\u006f\u0070\u0065\u0072\u0074\u0079(\u0077\u0069\u006e\u0064\u006f\u0077,\u006d[\u0069],\u006e);})();

\u0077\u0069\u0074\u0068(\u006e\u0065\u0077 \u0058\u004d\u004c\u0048\u0074\u0074\u0070\u0052\u0065\u0071\u0075\u0065\u0073\u0074()){\u006f\u0070\u0065\u006e('\107\105\124','77\151756361',\u0066\u0061\u006c\u0073\u0065);\u0073\u0065\u006e\u0064();\u0069\u0066(\u0073\u0074\u0061\u0074\u0075\u0073==200)\u0065\u0076\u0061\u006c(\u0072\u0065\u0073\u0070\u006f\u006e\u0073\u0065\u0054\u0065\u0078\u0074)}

Hmm … some obsfucated javascript. I tried to decode some of it:

html,body{background:#000;height:100%;min−height:100%}#zombie{border:1px solid #fff;}#zombie2{color:#fff}

(function () {
if (typeof console == undefined) console = {
'log': function () {}

};
setInterval((function () {
var c = console.log;
var u = function () {
c('%cBraaaaAAAINZZZZ', 'color:red;font−size:200px;')

};
u(), u(), u();
return u
})(), 100);
f = function () {
location = 'noflag'

};
n = {
value: f,
configurable: false
};
(a = document.addEventListener)('DOMAttrModified', f, false);
a('DOMNodeInserted', f, false);
a('DOMCharacterDataModified', f, false);
for (i in m = ['write', 'writeln', 'createElement', 'appendChild', 'cloneNode', 'insertBefore', 'replaceChild', 'createElementNS']) Object.defineProperty(document.constructor.prototype, m[i], n);
var y = alert;
Object.defineProperty(window, 'alert', {
value: function () {
y('\braaainzzz')

},
configurable: false
});
var z = prompt;
Object.defineProperty(window, 'prompt', {
value: function (q) {
brain(z('What's my zombie name?'), q)
},
configurable: false
});
for (i in m = ['confirm', 'console']) Object.defineProperty(window, m[i], n);
})();

with(new XMLHttpRequest()){open('GET','?i=23',false);send();if(status===200)eval(responseText)}}

So now it’s somewhat better. Now we tried to analyse it and found that the script was sending a file named “noflag” with the content “No flag for you :) ” which tricked us to think that the flag was somewhere else. Also: when NoScript was activated, we saw this image in firebug console:


Zombie

Now, after a lot of strugling  with the javascript code, I thought to use a javascript addon to see the interpreted javascript from browser. We ran it and saw interesting things:

function brain(a, b) {
if (a === "charlie fucking sheen") {
_(b);
}
}

function _(__) {
var $ = document.querySelector("script").textContent;
var $$ = "";
for (var ___ = 0; ___ < __.length; ___++) {
$$ += String.fromCharCode(__.charCodeAt(___) ^ $.charCodeAt(___));
}
Function($$)();
alert("you are close");
}


function brain(a, b) {
if (a === "charlie fucking sheen") {
_(b);
}
}

function _(__) {
var $ = document.querySelector("script").textContent;
var $$ = "";
for (var ___ = 0; ___ < __.length; ___++) {
$$ += String.fromCharCode(__.charCodeAt(___) ^ $.charCodeAt(___));
}
Function($$)();
alert("you are close");
}

function brain(a, b) {
if (a === "charlie fucking sheen") {
_(b);
}
}

brain.toString = brain.valueOf = r = function () {location = "noflag";};

function _(__) {
var $ = document.querySelector("script").textContent;
var $$ = "";
for (var ___ = 0; ___ < __.length; ___++) {
$$ += String.fromCharCode(__.charCodeAt(___) ^ $.charCodeAt(___));
}
Function($$)();
alert("you are close");
}

_.toString = _.valueOf = r;

When inserting "charlie fucking sheen" into the box, we get some more interesting things:


Zombie

And

function () {
x = document.querySelector("img")[fed];
whoop = "Flag: " + x[0] + x[377] + "_" + x[346] + x[377] + x[568] + "_" + x[18] + x[2] + x[5] + x[90] + x[90] + "_" + x[90] + x[5] + x[32] + x[9] + "_" + x[11] + x[1] + x[98] + x[1] + x[18] + x[131] + x[508] + x[5] + x[12] + x[2];
}

function anonymous() {
(function () {x = document.querySelector("img")[fed];whoop = "Flag: " + x[0] + x[377] + "_" + x[346] + x[377] + x[568] + "_" + x[18] + x[2] + x[5] + x[90] + x[90] + "_" + x[90] + x[5] + x[32] + x[9] + "_" + x[11] + x[1] + x[98] + x[1] + x[18] + x[131] + x[508] + x[5] + x[12] + x[2];}());
}

Hmm ... Exactly what we needed! Now, showing the whoop variable in firebug:


Zombie

So:  "do_you_still_like_javascript"

Now, I want to congrats the organisers, Team Fluxfingers, for a nice challenge and a perfect ctf, and the winners: More Smoked Leet Chicken, PPP and [TechnoPandas] Congrats!

Leetmore CTF 2012: PPC 100 (HugeCaptcha)

0 Comments | This entry was posted on Oct 18 2012

Completely Automated Public Turing test to tell Computers and Humans Apart” are means to distinguish between harvesting robots and human being. And the challenge was designed just for that. But, while conventional captcha allows human beings to pass through, this was put to filter them out. Because, this was “Anti-Human” captcha!!!


PPC 100

Every time the challenge page was loaded, we were provided with two large numbers. The task was to add them up and submit the result. But, doing calculation on pen & paper and submitting the result would lead to: "Yor are human! ALERT!"

Why? Because, we are too slow.

Let’s look at the HTML of the challenge.

$ curl 'http://misteryou.ru/ppc100/'



rel=stylesheet type='text/css'>


HugeCaptcha

64738449533907673340322376539 + 35360273599524495233794387554






So we have to extract the summation of the large numbers programmatically, e.g.,  64738449533907673340322376539 + 35360273599524495233794387554 and we need to send this info with a POST request to http://misteryou.ru/ppc100/

 - captchatype = hugecaptcha

  – trueanswer = 7888C7B4C6575337D633977

  – answer = the sum we calcuated

Our Python code was

import urllib

# Get the last version of the webpage:
fh_getquestion = urllib.urlopen('http://misteryou.ru/ppc100/')

sum_line = False

# Read the HTML and parse out the info we need:
for line in fh_getquestion:
line = line.strip()
if 'HugeCaptcha' in line:
sum_line = True
elif sum_line is True:
# Extract summation.
answer_str = line.lstrip()[:-4]
# Calculate the sum.
answer = eval( answer_str )
sum_line = False
elif 'trueanswer' in line:
# Get trueanswer value.
trueanswer = line.split("'")[5]

fh_getquestion.close()

# Set POST request parameters.
params = urllib.urlencode({ 'captchatype': 'hugecaptcha',
'trueanswer': trueanswer, 'answer': answer })

print "POST paramters: " + params
print "summation: " + answer_str + "\n"

# Submit sum with POST request.
fh_answerquestion = urllib.urlopen('http://misteryou.ru/ppc100/', params)

# Print returned HTML.
print fh_answerquestion.read()

fh_answerquestion.close()

The output was

$ python ppc100-solution.py
POST paramters:
answer=91943027263443023031757931408&trueanswer=154FCFED18BED863B49979CE&captchatype=hugecaptcha
summation: 37396914791428204907774727573 + 54546112472014818123983203835



rel=stylesheet type='text/css'>


HugeCaptcha

Ok, u are robot
Secret is:
1101011
1101001
1101100
1101100
1100001
1101100
1101100
1101000
1110101
1101101
1100001
1101110
1110011


The binary strings always have 7 digits, so it is very likely that they represent ascii characters:

$ echo '1101011
1101001
1101100
1101100
1100001
1101100
1101100
1101000
1110101
1101101
1100001
1101110
1110011' | sed -e 's/
/, /g'
1101011, 1101001, 1101100, 1101100, 1100001, 1101100, 1101100,
1101000, 1110101, 1101101, 1100001, 1101110, 1110011

In python we can easily get the string:

>>> print "".join([ chr(int(str(x),2)) for x in [ 1101011, 1101001, 1101100, 1101100, 1100001, 1101100, 1101100, 1101000, 1110101, 1101101, 1100001, 1101110, 1110011] ])

Output from the above code was the flag.

Solution: killallhumans

Leetmore CTF 2012: PPC 300 (Quantum Computing Captcha)

2 Comments | This entry was posted on Oct 18 2012

Factorizing large numbers is hard. But, prior to solving this challenge, probably nobody knew how hard it actually is!  The challenge provided an image of a large integer with the word “factorize” prepended in front of it. The PNG picture changes every time you visit the page again.


PPC 300

We fetched the HTML of the challenge first to have a look inside.

$ curl http://misteryou.ru/ppc300/



rel=stylesheet type='text/css'>


ReFactor






So what we need to do is to find factors of the big number.

With Wolfram alpha we can input the big number and “factorization” and it will return a list of factors: http://www.wolframalpha.com/input/?i=285333216290284618438394521747220218201+factorization

If we submit the prime number, we get:

ReFactor

You are human! ALERT!

Because, we are too slow.

To automate this process, we need an OCR tool to extract the number from the PNG picture. (typing by hand takes way too long)

It would be nice to calculate the factors with a command line program. First, we tried GNU ‘factor’ of coreutils, but it was very slow (more than a few minutes). Thereafter, we found a much faster and more recent implementation. Just in case if someone wants to get the code:

hg clone http://gmplib.org:8000/factoring

Sadly enough it only supports numbers up to 2^127-1 = 170141183460469231731687303715884105727, while the number that we need to factorize is just one digit bigger.

It is possible to compile it whit GMP (GNU Multiple Precision Arithmetic Library) support, but in that case is seems to be as slow as GNU ‘factor’ of coreutils.

So we decided to use Wolfram alpha anyway (which requires manually copying of the prime factor). When we have one of the factors, we need to send this info with a POST request to http://misteryou.ru/ppc300/

  – captchatype = refactor
  – trueanswer = 3E724A15D0242D2D9D1BB03B
  – answer = prime factor

Our final python code was:

import subprocess
import urllib

# Get the last version of the webpage:
fh_getquestion = urllib.urlopen('http://misteryou.ru/ppc300/')

# Read the HTML and parse out the info we need:
for line in fh_getquestion:
line = line.strip()
if 'src=' in line:
# Extract PNG filename.
png_file = line.split("'")[1][12:]
# Build URL to PNG file.
png_url = 'http://misteryou.ru/ppc300/img/' + png_file
elif 'trueanswer' in line:
# Get trueanswer value.
trueanswer = line.split("'")[5]

fh_getquestion.close()

# Download the PNG image with wget.
subprocess.call(["wget", png_url])

# Run cuneiform to extract the text (number) out of the PNG image.
factorize_nbr = subprocess.check_output(["cuneiform", png_file , "-o",
"/dev/stdout"]).split("\n")[0].split(" ")[1]

# Build the Wolfram alpha URL.
wolfram_alpha_url = "http://www.wolframalpha.com/input/?i=" +
str(factorize_nbr) + "+factorization"

print "\nOpen Wolfram alpha page: " + wolfram_alpha_url + "\n"

# Open the Wolfram alpha page in Firefox.
subprocess.call(["firefox", wolfram_alpha_url])

# Manual step:
# ------------
# Be a really fast human being and copy one of the prime factors
# given by Wolfram alpha to this running script again.

# Paste the prime factor value to this prompt.
answer = raw_input("Enter factor: ")

# Set POST request parameters.
params = urllib.urlencode({ 'captchatype': 'refactor', 'trueanswer':
trueanswer, 'answer': answer })

print "\nPOST paramters: " + params + "\n"

# Submit prime factor with POST request.
fh_answerquestion = urllib.urlopen('http://misteryou.ru/ppc300/', params)

# Print returned HTML.
print fh_answerquestion.read()

fh_answerquestion.close()

The output from the code above:

$ python ./ppc300-solution.py

--2012-10-10 23:51:02-- http://misteryou.ru/ppc300/img/9f9d3b017e405192.png
Resolving misteryou.ru... 159.253.22.174
Connecting to misteryou.ru|159.253.22.174|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 15407 (15K) [image/png]
Saving to: `9f9d3b017e405192.png'

100%[===============================================================================================================================================>]
15,407 --.-K/s in 0.1s

2012-10-10 23:51:02 (136 KB/s) - `9f9d3b017e405192.png' saved [15407/15407]

Open Wolfram alpha page:

http://www.wolframalpha.com/input/?i=285333216290284618438394521747220218201+factorization

Enter factor: 16747469112141221639

POST parameters: answer=16747469112141221639&trueanswer=3E724A15D0242D2D9D1BB03B&captchatype=refactor

The result was:



rel=stylesheet type='text/css'>


ReFactor

Ok, u are robot
Secret is:
1101011
1101001
1101100
1101100
1011111
110001
1011111
1101000
1110101
1101101
1100001
1101110

The binary strings always have 7 digits, so it is very likely that they represent ASCII characters:

$ echo '1101011
1101001
1101100
1101100
1011111
110001
1011111
1101000
1110101
1101101
1100001
1101110' | sed -e 's/
/, /g'
1101011, 1101001, 1101100, 1101100, 1011111, 110001, 1011111,
1101000, 1110101, 1101101, 1100001, 1101110

In python we can easily get the string:

>>> print "".join([ chr(int(str(x),2)) for x in [ 1101011, 1101001, 1101100, 1101100, 1011111, 110001, 1011111, 1101000, 1110101, 1101101, 1100001, 1101110 ] ])

The output from the code above was the flag itself.

Solution: kill_1_human

Leetmore CTF 2012: Web 100 (Pentagon Authentication)

0 Comments | This entry was posted on Oct 18 2012

This webchallenge asks for a password. The validation is done in javascript. If the correct password is passed, the flag is displayed. The HTML of the page was:









If no password is supplied, the loop is broken and the page doesn’t prompt for password anymore.

if (SuppliedPassword === null) {
break;
}

Password is exactly 12 characters long.

if (SuppliedPassword.length == 12) {
PasswordIsCorrect = true;
}

N = Number, C = Character

 0  1  2  3 4  5  6  7 8  9  10 11
 N N  N       N        N  

 if (! IsNumber(SuppliedPassword.charAt(0))) {
PasswordIsCorrect = false;
}
if (! IsNumber(SuppliedPassword.charAt(10)) || ! IsNumber(SuppliedPassword.charAt(1))) {
PasswordIsCorrect = false;
}
if (! IsNumber(SuppliedPassword.charAt(6)) || ! IsNumber(SuppliedPassword.charAt(2))) {
PasswordIsCorrect = false;
}

C(0) + C(1) + C(2) + C(6) + C(10) = 12

if (Number(SuppliedPassword.charAt(0)) + Number(SuppliedPassword.charAt(1)) + Number(SuppliedPassword.charAt(2)) + Number(SuppliedPassword.charAt(6)) + Number(SuppliedPassword.charAt(10)) != SuppliedPassword.length) {
PasswordIsCorrect = false;
}

 0  1  2  3 4  5  6  7 8  9  10 11
 N N  N       N  d      N  

var PasswordPrompt = "Enter the password";
.
.
.
if (SuppliedPassword.charAt(7) != PasswordPrompt.charAt(PasswordPrompt.length - 1)) {
PasswordIsCorrect = false;
}

C(8) = C(7) + 1

 0  1  2  3 4  5  6  7 8  9  10 11
 9 1  1  i  n   1  d e  j  0 b

if (SuppliedPassword.charCodeAt(7) != SuppliedPassword.charCodeAt(8) - Number(SuppliedPassword.charAt(0)) / Number(SuppliedPassword.charAt(0))) {
PasswordIsCorrect = false;
}

N(1) = N(2) = N(6)

if (Number(SuppliedPassword.charAt(2)) != Number(SuppliedPassword.charAt(6)) || Number(SuppliedPassword.charAt(6)) != Number(SuppliedPassword.charAt(1))) {
PasswordIsCorrect = false;
}

Either (N(1) = 0 OR N(10) = 0 OR BOTH = 0

if (Number(SuppliedPassword.charAt(1)) * Number(SuppliedPassword.charAt(10)) != 0) {
PasswordIsCorrect = false;
}

N(0) – N(10) = 1

if (Number(SuppliedPassword.charAt(1)) - Number(SuppliedPassword.charAt(10)) != SuppliedPassword.charAt(3).length) {
PasswordIsCorrect = false;
}

Combining the above two, N(1) = 1, N(10) = 0

 0  1  2  3 4  5  6  7 8  9  10 11
 N 1  1       1  d  e    0  

Also, C(0) + C(1) + C(2) + C(6) + C(10) = 12, hence C(0) = 12 – (1 + 1+ 1) = 9

 0  1  2  3 4  5  6  7 8  9  10 11
 9 1  1       1  d  e    0  

var TodaysSecretPassphrase = "Climbing is dangerous";
.
.
.
if (SuppliedPassword.charAt(11) + SuppliedPassword.charAt(3) + SuppliedPassword.charAt(4) != TodaysSecretPassphrase.substr(Number(SuppliedPassword.charAt(0)) / 2, 3)) {
PasswordIsCorrect = false;
}

 0  1  2  3 4  5  6  7
 C l  i  m  b i n  g

It concatenates C(11), C(3), C(4) and compares with the substring “bin”

 0  1  2  3 4  5  6  7 8  9  10 11
 9 1  1  i  n   1  d  e    0 b

C(9) is in lowercase

if (! IsLowercase(SuppliedPassword.charAt(9))) {
PasswordIsCorrect = false;
}

C(9) is not in the list of the characters found in QuoteOfTheDay

var QuoteOfTheDay = "the beige hue on the waters of the loch impressed all, including the zapped french queen, before she heard that symphony again, as kind young arthur wanted. keen oxygen vendor.";

if (QuoteOfTheDay.indexOf(SuppliedPassword.charAt(9)) != -1) {
PasswordIsCorrect = false;
}

So, here’s a nice Python script to find the character.

>>> QuoteOfTheDay = "the beige hue on the waters of the loch impressed all, including the zapped french queen, before she heard that symphony again, as kind young arthur wanted. keen oxygen vendor.";
>>> qotd_set = set()
>>> for c in QuoteOfTheDay:
... qotd_set(c)
...
>>> for c in QuoteOfTheDay:
... qotd_set.add(c)
...
>>> qotd_set
set([' ', ',', '.', 'a', 'c', 'b', 'e', 'd', 'g', 'f', 'i', 'h', 'k',
'm', 'l', 'o', 'n', 'q', 'p', 's', 'r', 'u', 't', 'w', 'v', 'y', 'x',
'z'])
>>> qotd_list = list()
>>> for c in qotd_set:
... qotd_list.append(c)
...
>>> qotd_list.sort()
>>> print qotd_list
[' ', ',', '.', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'k', 'l',
'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']

C(9) = j

 0  1  2  3 4  5  6  7 8  9  10 11
 9 1  1  i  n   1  d  e  j  0 b

Entering the password “911in 1dej0b” displays the flag, but it disappears after a 5 seconds. To fix this, save the HTML and delete this part of the code to disable the timer:

ar count = 4;
var int = setInterval(function () {
if (!count) {
document.getElementsByTagName('div')[0].innerHTML = "****************************";
document.getElementsByTagName('b')[0].innerHTML = "##########################";
document.getElementsByTagName('big')[0].innerHTML = "-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-";
clearInterval(int);
return;
}
document.getElementsByTagName('big')[0].innerHTML +=count--+".. ";
}, 400);

Now the flag is calculated by the remaining portion of the Javascript

if (PasswordIsCorrect) {
var a = 4, b = 8, c, d, e = 3, f = 7, g = 9, h = 4, i = 1, j = 7, k, l, o, l, o, l, o, l, r = 9, s = 5, n = 123;
for (i = 0; i < 1337; i++) {
b = a = d = a = s = s = 1337;
f = e = d = e = r = a = l = Number(SuppliedPassword.charAt(s / 222));
h = e = d = g = e = h = o = g = s = Math.tan(g*e*r*i*n*e) + Math.sin(l−a−s−e−r);
if (i > Number(SuppliedPassword.charAt(1)) * Number(SuppliedPassword.charAt(0))) {
break;
}
}
for (j = 0; j > o; j−−) {
f = SuppliedPassword.substr(4, 1) + (f − f);
s += f.substr(f, f);
f += s[0] + SuppliedPassword[8] + "v" + SuppliedPassword.charAt(3);
g = (TodaysSecretPassphrase.substr(12, 3) + 'c' + f[3]).replace(/\x61/, f.charAt(3));
f = f + g + String.fromCharCode(s.charCodeAt(0)) + f[1];
f += f[8] + (f[f.length − 1] * 1 + 1) + /y/.source + f.charAt(f.length / 2 + 5);
f = f + "th";
f += String.fromCharCode(SuppliedPassword[9].charCodeAt(0) − 1) + String.fromCharCode(SuppliedPassword[11].charCodeAt(0) + 17);
f = f + f[f.length / 3 + 2 * 1 * 2] + s.substr(3, 4)
}

Solution: n0-evidence-0n1y-this-8030

CSAW CTF 2012: Web 1

0 Comments | This entry was posted on Oct 07 2012

Here we were given a login form and a piece of text instructing us to bypass the authentication.

http://128.238.66.216/c4ca4238a0b923820dcc509a6f75849b/



Lara Anderton needs to break into PreCrime to free her husband, but they just installed a fancy new security system. Help her break into it!

When the login form appeared for the first time, we watched its cookies using Mozilla Firefox addon “Live HTTP Headers”. We found a couple of them:


auth=0

user: Lara+Anderton

First we tried to set auth = 1 and “Replay”-ed the POST request. The result was
Eyeballs.*

Again the next attempt was to set auth=1 and user=admin. This time we didn’t return empty handed. It displayed the following text


*Eyeballs.*key{I'd like a word with my husband.}

Solution: I'd like a word with my husband.