ctf

Category: WEB, PPC

Can you solve some sudoku challenges?

##Solution

In this challenge we are given a webpage with a sudoku table that we should solve. Also a captcha to protect page from being brute-forced. Requested task is to solve the sudoku for 200 times and submit our results to get the flag. Viewing source code of challenge, we will see that there is a javascript code for rendering sudoku table in client-side.

function sudoku(w){
var str
str = "072106048410000000030874291090052386765080012203961405051390004320040107000000600";
var j
var a,b,l1,l2,l3,l4,t
t="";
l1="<td bgcolor=";
l2=">&nbsp;&nbsp;</td>";
l3="<td bgcolor=";
l4="</td>";
for (j=0;j<9;j++){
if(j==0 | j==1 | j==2 | j==6 | j==7 | j==8){a="DDDDDD";b="FFFFFF";}
if(j==3 | j==4 | j==5){b="DDDDDD";a="FFFFFF";}
t+="<TR>";
if (str.charAt(0+j*9)=="0"){t+=l1+a+l2;}else{t+=l3+a+">"+str.charAt(0+j*9)+l4;}
if (str.charAt(1+j*9)=="0"){t+=l1+a+l2;}else{t+=l3+a+">"+str.charAt(1+j*9)+l4;}
if (str.charAt(2+j*9)=="0"){t+=l1+a+l2;}else{t+=l3+a+">"+str.charAt(2+j*9)+l4;}
if (str.charAt(3+j*9)=="0"){t+=l1+b+l2;}else{t+=l3+b+">"+str.charAt(3+j*9)+l4;}
if (str.charAt(4+j*9)=="0"){t+=l1+b+l2;}else{t+=l3+b+">"+str.charAt(4+j*9)+l4;}
if (str.charAt(5+j*9)=="0"){t+=l1+b+l2;}else{t+=l3+b+">"+str.charAt(5+j*9)+l4;}
if (str.charAt(6+j*9)=="0"){t+=l1+a+l2;}else{t+=l3+a+">"+str.charAt(6+j*9)+l4;}
if (str.charAt(7+j*9)=="0"){t+=l1+a+l2;}else{t+=l3+a+">"+str.charAt(7+j*9)+l4;}
if (str.charAt(8+j*9)=="0"){t+=l1+a+l2;}else{t+=l3+a+">"+str.charAt(8+j*9)+l4;}
t+="</TR>\n";
}
document.getElementById(w).innerHTML="<table style='text-align: center; vertical-align: middle; width: 270px; height: 270px;' border=2 cellpadding=0 cellspacing=0>\n"+t+"</table>\n";
}

The python code for generate this process is given as below:

from PIL import Image
import sys
import urllib
import json
import re
import requests

def findNextCellToFill(grid, i, j):
for x in range(i,9):
for y in range(j,9):
if grid[x][y] == 0:
return x,y
for x in range(0,9):
for y in range(0,9):
if grid[x][y] == 0:
return x,y
return -1,-1

def isValid(grid, i, j, e):
rowOk = all([e != grid[i][x] for x in range(9)])
if rowOk:
columnOk = all([e != grid[x][j] for x in range(9)])
if columnOk:
# finding the top left x,y co-ordinates of the section containing the i,j cell
secTopX, secTopY = 3 *(i/3), 3 *(j/3)
for x in range(secTopX, secTopX+3):
for y in range(secTopY, secTopY+3):
if grid[x][y] == e:
return False
return True
return False

def solveSudoku(grid, i=0, j=0):
i,j = findNextCellToFill(grid, i, j)
if i == -1:
return True
for e in range(1,10):
if isValid(grid,i,j,e):
grid[i][j] = e
if solveSudoku(grid, i, j):
return True
# Undo the current cell for backtracking
grid[i][j] = 0
return False

def create_sudoku_list(s_str):
r = []
for i in range(len(s_str)/9):
r.append([int(x) for x in s_str[9*i:9*i+9]])
return r

def return_back_to_str(s_list):
return ''.join([''.join([str(i) for i in x]) for x in s_list])

# s = requests.Session()
url = "http://ctf.sharif.edu:8084/"
sessionid='xxs408hfkrfj73dpv4pvsdbwh5ku3m9e', PHPSESSID= 'qjp47pv1548uajdfhchddo5js3')

while True:
soup = BeautifulSoup(r.text, 'lxml')
data  = soup.find_all("script").string
data = data.split('\n')
sudoku = data.split('"')
xx = create_sudoku_list(sudoku)
result = solveSudoku(xx)
solved = return_back_to_str(xx)