]> git.somenet.org - ctf/pub/submit_bot.git/blob - submitbot_tcp.py
modified: submitbot_tcp.py
[ctf/pub/submit_bot.git] / submitbot_tcp.py
1 #!/usr/bin/env python
2
3 # 2014 by Jan "Someone" Vales <someone@somenet.org>
4 # do not publish!
5
6 import psycopg2
7 import psycopg2.extras
8 import sys
9 import time
10 import signal
11 import socket
12
13 def readlines(sock, recv_buffer=4096, delim='\n'):
14         buffer = ''
15         data = True
16         while data:
17                 data = sock.recv(recv_buffer)
18                 buffer += data
19
20                 while buffer.find(delim) != -1:
21                         line, buffer = buffer.split('\n', 1)
22                         yield line
23         return
24
25 def submit(sock,flag):
26     submission_success = False
27     fs=sock.makefile()
28
29     print "submitting flag: "+flag
30
31     sock.sendall(flag+"\n")
32
33     resp = fs.readline()+""
34     print resp
35     if 'Accepted' in resp:
36         return (1, resp.replace(flag,''))
37
38     if 'Denied: no such flag' in resp:
39         return (2, 'Denied: no such flag')
40
41     if 'Denied: invalid flag' in resp:
42         return (2, 'Denied: invalid flag')
43
44     if 'Denied: flag is too old' in resp:
45         return (2, 'Denied: flag is too old')
46
47     if 'Denied: you already submitted this flag' in resp:
48         return (3, 'Denied: you already submitted this flag')
49
50     if 'Denied: flag is your own' in resp:
51         return (2, 'Denied: flag is your own')
52
53     if 'Denied: your appropriate service' in resp:
54         return (4, 'Denied: your appropriate service')
55
56     # RETURN (success?, srvresponse)
57     print resp
58     return (4, 'WTF?!')
59
60 def main():
61     sleeptime = 1
62     dbconn = None
63     while True:
64         try:
65             print "*** sleeping "+str(sleeptime)+" sec..."
66             time.sleep(sleeptime)
67             dbconn = psycopg2.connect("host=s.i port=5432 dbname=flagbot user=flagbot password=flagbotpw")
68             print "Connected to DB"
69
70             cur = None
71             sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
72             sock.connect(("flags.ructfe.org", 31337))
73             eating = True
74             fs=sock.makefile()
75             while eating:
76                  resp = fs.readline()+""
77                  if resp.startswith('Enter your flags, finished with newline'):
78                      eating = False
79
80             while True:
81                 try:
82                     cur = dbconn.cursor(cursor_factory=psycopg2.extras.DictCursor)
83                     cur.execute("SELECT * from flags where status = 0 or status = 4 order by random() limit 1")
84                     print "Fetched " + str(cur.rowcount) + " rows"
85                     if cur.rowcount == 0:
86                         print "*** sleeping another "+str(sleeptime)+" sec..."
87                         time.sleep(sleeptime)
88                         continue
89                     for row in cur.fetchall():
90                     #    print "here" + str(row['fid'])
91                         if row['flag'] is None or row['flag'].strip() == '':
92                             continue                                            
93                         (success, resp) = submit(sock,row['flag'])
94                         if success != 0:
95                             cur.execute("UPDATE flags SET submitted = date_trunc('second', NOW()), status = %s, srvresponse = %s WHERE fid = %s and status = 0 or status = 4",
96                                 (success, resp, row['fid']))
97                             dbconn.commit()
98                 except psycopg2.DatabaseError as e:
99                     print 'Error %s' % e
100                 try:
101                     cur.close()
102                     dbconn.rollback()
103                 except psycopg2.DatabaseError as e:
104                     print 'Error %s' % e
105                 cur = None
106                 dbconn.rollback()
107             sock.shutdown(socket.SHUT_WR)
108             sock.close()
109
110         except psycopg2.DatabaseError as e:
111             print 'Error %s' % e
112         try:
113             dbconn.close()
114         except psycopg2.DatabaseError as e:
115             print 'Error %s' % e
116         dbconn = None
117     print "should never be reached"
118
119 if __name__ == "__main__":
120     def signal_handler(signal, frame):
121         print 'SIG received. exitting!'
122         sys.exit(0)
123     signal.signal(signal.SIGINT, signal_handler)
124     main()