-
Notifications
You must be signed in to change notification settings - Fork 7
/
sockpuppet.py
81 lines (61 loc) · 2.38 KB
/
sockpuppet.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#!/usr/bin/python
import json
import random
import string
import logging
import tornado.httpclient
import tornado.gen
import tornado.options
import tornado.web
import tornado.websocket
def parse_payload(data):
try:
body = None
frame = json.loads(data)
if isinstance(frame, list) and len(frame) > 0:
frame = frame[0]
body = json.loads(frame.get('body', "{}"))
return frame, body
except Exception as ex:
logging.exception(ex)
return None, None
@tornado.gen.coroutine
def connect_and_read_websocket():
url = tornado.options.options.ws_addr
try:
logging.info("connecting to: %s", url)
w = yield tornado.websocket.websocket_connect(url, connect_timeout=5)
logging.info("connected to %s, waiting for messages", url)
except Exception as ex:
logging.error("couldn't connect, err: %s", ex)
return
while True:
payload = yield w.read_message()
if payload is None:
logging.error("uh oh, we got disconnected")
return
if payload[0] == "o":
cookie = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(32))
msg = json.dumps(['{"action":"login", "client_app":"hermes.push", "cookies":{"nyt-s":"%s"}}' % cookie])
w.write_message(msg.encode('utf8'))
logging.info("sent cookie: %s", cookie)
elif payload[0] == 'h':
logging.info('ping')
elif payload[0] == 'a':
frame, body = parse_payload(payload[1:])
if not frame:
logging.warn("unknown paylod: %s", payload.decode('utf8'))
continue
if frame['product'] == "core" and frame['project'] == "standard":
logging.info("Logged in ok")
elif frame['product'] == "hermes" and frame['project'] == "push" and body:
logging.warn("NEW! %s: %s", body['label'], body['title'])
else:
logging.warn("unknown paylod: %s", payload.decode('utf8'))
if __name__ == '__main__':
tornado.options.define(name="ws_addr", type=str, help="Address of the websocket host to connect to.")
tornado.options.parse_command_line()
if not tornado.options.options.ws_addr:
tornado.options.print_help()
exit()
tornado.ioloop.IOLoop.instance().run_sync(connect_and_read_websocket)