English [Cybercamp part 2 – 2015] [Web 11] Write Up

Description

 

Web 11

Juego: Cybercamp 2015 – Fase 2
Categoría: Web
Puntos máximos:

XX puntos

Descripción:

Puerto: 8081

 

Resolution

Actually, this challenge was not really a Web challenge, as the goal was mainly to read a image, but it was really a fun challenge 🙂

So, the main page looked like this :

<IMAGE>

As you can see, there is only a blank image (loaded with php, in imagen.php file)and a form asking us for a code, which should certainly be in the image. So, we have to analyze it. After a bit of guessing, we found out that the image is not actually really blank. There is a single byte difference in some pixels. After filling some parts, we rapidly saw that the image was actually a QR code :

Beautiful, isn't it?
Beautiful, isn’t it?

We tried to read it, but as we filled it by hand, some pixels were bad and nothing came. We then created a little script that filled the image as it should:

from PIL import Image 
pic = Image.open('tmpfile.png')
pic = pic.convert('RGBA')
pix = pic.load()
(width, height) = pic.size

for i in range(pic.size[0]):
 for j in range(pic.size[1]):
 #print(pix[i,j])
 if (pix[i,j]!= (255, 255, 255, 255)):
 pix[i,j] = (0, 0, 0, 255)
pic.save('imagen3_parsed.png')

The QR code gived us its value : CAX LXVKXM VHWX BL: TRRYLKROSTYJLXVVMONOLNLWKYWXQKMS.

After a few tests, we discovered that it was a caesar cipher with a random key. The decoded valus was ‘The secret code is: ‘ with a code behind. We tried this code in the web page form, but we had an error message saying that the code was false. OK, so, it’s a bit like a catcha, everytime the image page is loaded, a new code is generated.
Oh and moreover, the main page says that we succeeded “0 time” so, obvisouly, we had to succeed multiple times. The best to do was then to create a little script.

To sum up, we have to :

  • get a session that we have to keep
  • get the nearly white image
  • add some black onto the image, in order to read the QR Code
  • read the QR Code
  • “Brute force” the caesar to get the good key
  • Send it to the webpage
  • Do it again and again (except the session of course, which must be the same)

So this is our code (python2) :


# -*- coding: utf-8 -*-

from PIL import Image 
import qrtools
import socket
import request
import sys

def caesar(s, key):
 ret = ""
 for i in s:
 al = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
 if (i ==' '):
 ret += ' '
 elif(i == ':'):
 ret +=':'
 else:
 ret += al[(al.find(i)+1+key)%62]
 return ret

req = request.request()
req.dst = "challenge.cybercamp.es"
req.host = "challenge.cybercamp.es"
req.method = "GET"
req.port = 8091
req.uri = "/"
req.version = "HTTP/1.1"

# first we get the session cookie
rep = req.send()
if rep.cookies:
 req.cookies = rep.cookies[0:rep.cookies.find(";")]

# then we get the f*cking imagen.php file a thousand time
aa=0
while (aa&lt; 1000):
 req.uri = "/imagen.php"
 rep = req.send()
 tmpf = open('tmpfile.png', 'wb')
 tmpf.write(rep.body)
 tmpf.close()
 #print(rep.response.encode('UTF-8'))
 pic = Image.open('tmpfile.png')
 pic = pic.convert('RGBA')
 pix = pic.load()
 (width, height) = pic.size

for i in range(pic.size[0]):
 for j in range(pic.size[1]):
 if (pix[i,j]!= (255, 255, 255, 255)):
 pix[i,j] = (0, 0, 0, 255)
 pic.save('imagen3_parsed.png')
 qr = qrtools.QR()
 qr.decode('imagen3_parsed.png')
 print(qr.data)
 i = 0
 msg = ""
 while not 'secret' in msg:
 msg = caesar(qr.data, i)
 i+=1
 req.uri = "/?respuesta="+msg.split(': ')[1]

rep = req.send()
 print rep.response
 aa+=1

Finally, we launched the script, kept an eye on our console to see the responses coming and… the flag !


<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="favicon.ico">

<title>Web - Challange 11</title>

<!-- Bootstrap core CSS -->
<link href="css/bootstrap.min.css" rel="stylesheet">

<!-- Custom styles for this template -->
<link href="css/jumbotron-narrow.css" rel="stylesheet">

<!-- Just for debugging purposes. Don't actually copy these 2 lines! -->
<!--[if lt IE 9]><script src="../../assets/js/ie8-responsive-file-warning.js"></script><![endif]-->
<script src="js/ie-emulation-modes-warning.js"></script>

<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>

<body>

<div class="container">
<div class="header clearfix">
<nav>
</nav>
<h3 class="text-muted">Challange 11: White</h3>
</div>

<div class="jumbotron">
<h1>Do you see it?</h1>
<center> TOKEN: fe84d2417a135e8fe3b4e6b0fb947334 </center>
</center>

</div>

<footer class="footer">
<p>&copy; Web Challange 11 - 2015</p>
</footer>

</div> <!-- /container -->
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="js/ie10-viewport-bug-workaround.js"></script>
</body>
</html>

Here is the flag : fe84d2417a135e8fe3b4e6b0fb947334

Enjoy

The lsd

Leave a Reply

Your email address will not be published. Required fields are marked *