Bad Behavior - Version 2.0.11

Version Description

Download this release

Release Info

Developer error
Plugin Icon wp plugin Bad Behavior
Version 2.0.11
Comparing to
See all releases

Code changes from version 1.2.2 to 2.0.11

Files changed (51) hide show
  1. COPYING +15 -15
  2. README.txt +44 -23
  3. bad-behavior-accept.php +0 -40
  4. bad-behavior-banned.php +0 -70
  5. bad-behavior-blackhole.php +0 -70
  6. bad-behavior-core.php +0 -151
  7. bad-behavior-database.php +0 -121
  8. bad-behavior-functions.php +0 -47
  9. bad-behavior-generic.php +100 -41
  10. bad-behavior-google.php +0 -14
  11. bad-behavior-http-headers.php +0 -49
  12. bad-behavior-konqueror.php +0 -23
  13. bad-behavior-lifetype.php +148 -0
  14. bad-behavior-lynx.php +0 -13
  15. bad-behavior-mediawiki.php +108 -68
  16. bad-behavior-movabletype.php +0 -23
  17. bad-behavior-mozilla.php +0 -27
  18. bad-behavior-msie.php +0 -31
  19. bad-behavior-msnbot.php +0 -18
  20. bad-behavior-opera.php +0 -13
  21. bad-behavior-php4.php +0 -12
  22. bad-behavior-referer.php +0 -25
  23. bad-behavior-safari.php +0 -12
  24. bad-behavior-user-agent.php +0 -70
  25. bad-behavior-whitelist.php +0 -128
  26. bad-behavior-wordpress.php +116 -46
  27. bad-behavior/admin.inc.php +75 -0
  28. bad-behavior/banned.inc.php +48 -0
  29. bad-behavior/blackhole.inc.php +37 -0
  30. bad-behavior/blacklist.inc.php +113 -0
  31. bad-behavior/common_tests.inc.php +120 -0
  32. bad-behavior/core.inc.php +203 -0
  33. bad-behavior/functions.inc.php +70 -0
  34. bad-behavior/google.inc.php +13 -0
  35. bad-behavior/housekeeping.inc.php +16 -0
  36. bad-behavior/index.html +0 -0
  37. bad-behavior/konqueror.inc.php +17 -0
  38. bad-behavior/lynx.inc.php +13 -0
  39. bad-behavior/movabletype.inc.php +14 -0
  40. bad-behavior/mozilla.inc.php +19 -0
  41. bad-behavior/msie.inc.php +24 -0
  42. bad-behavior/msnbot.inc.php +13 -0
  43. bad-behavior/opera.inc.php +13 -0
  44. bad-behavior/post.inc.php +71 -0
  45. bad-behavior/responses.inc.php +44 -0
  46. bad-behavior/safari.inc.php +13 -0
  47. bad-behavior/screener.inc.php +63 -0
  48. bad-behavior/trackback.inc.php +18 -0
  49. bad-behavior/version.inc.php +3 -0
  50. bad-behavior/whitelist.inc.php +56 -0
  51. index.html +0 -0
COPYING CHANGED
@@ -1,8 +1,8 @@
1
  GNU GENERAL PUBLIC LICENSE
2
  Version 2, June 1991
3
 
4
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
5
- 675 Mass Ave, Cambridge, MA 02139, USA
6
  Everyone is permitted to copy and distribute verbatim copies
7
  of this license document, but changing it is not allowed.
8
 
@@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This
15
  General Public License applies to most of the Free Software
16
  Foundation's software and to any other program whose authors commit to
17
  using it. (Some other Free Software Foundation software is covered by
18
- the GNU Library General Public License instead.) You can apply it to
19
  your programs, too.
20
 
21
  When we speak of free software, we are referring to freedom, not
@@ -55,7 +55,7 @@ patent must be licensed for everyone's free use or not licensed at all.
55
 
56
  The precise terms and conditions for copying, distribution and
57
  modification follow.
58
-
59
  GNU GENERAL PUBLIC LICENSE
60
  TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61
 
@@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
110
  License. (Exception: if the Program itself is interactive but
111
  does not normally print such an announcement, your work based on
112
  the Program is not required to print an announcement.)
113
-
114
  These requirements apply to the modified work as a whole. If
115
  identifiable sections of that work are not derived from the Program,
116
  and can be reasonably considered independent and separate works in
@@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent
168
  access to copy the source code from the same place counts as
169
  distribution of the source code, even though third parties are not
170
  compelled to copy the source along with the object code.
171
-
172
  4. You may not copy, modify, sublicense, or distribute the Program
173
  except as expressly provided under this License. Any attempt
174
  otherwise to copy, modify, sublicense or distribute the Program is
@@ -225,7 +225,7 @@ impose that choice.
225
 
226
  This section is intended to make thoroughly clear what is believed to
227
  be a consequence of the rest of this License.
228
-
229
  8. If the distribution and/or use of the Program is restricted in
230
  certain countries either by patents or by copyrighted interfaces, the
231
  original copyright holder who places the Program under this License
@@ -278,8 +278,8 @@ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278
  POSSIBILITY OF SUCH DAMAGES.
279
 
280
  END OF TERMS AND CONDITIONS
281
-
282
- Appendix: How to Apply These Terms to Your New Programs
283
 
284
  If you develop a new program, and you want it to be of the greatest
285
  possible use to the public, the best way to achieve this is to make it
@@ -291,7 +291,7 @@ convey the exclusion of warranty; and each file should have at least
291
  the "copyright" line and a pointer to where the full notice is found.
292
 
293
  <one line to give the program's name and a brief idea of what it does.>
294
- Copyright (C) 19yy <name of author>
295
 
296
  This program is free software; you can redistribute it and/or modify
297
  it under the terms of the GNU General Public License as published by
@@ -303,16 +303,16 @@ the "copyright" line and a pointer to where the full notice is found.
303
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304
  GNU General Public License for more details.
305
 
306
- You should have received a copy of the GNU General Public License
307
- along with this program; if not, write to the Free Software
308
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
309
 
310
  Also add information on how to contact you by electronic and paper mail.
311
 
312
  If the program is interactive, make it output a short notice like this
313
  when it starts in an interactive mode:
314
 
315
- Gnomovision version 69, Copyright (C) 19yy name of author
316
  Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317
  This is free software, and you are welcome to redistribute it
318
  under certain conditions; type `show c' for details.
@@ -335,5 +335,5 @@ necessary. Here is a sample; alter the names:
335
  This General Public License does not permit incorporating your program into
336
  proprietary programs. If your program is a subroutine library, you may
337
  consider it more useful to permit linking proprietary applications with the
338
- library. If this is what you want to do, use the GNU Library General
339
  Public License instead of this License.
1
  GNU GENERAL PUBLIC LICENSE
2
  Version 2, June 1991
3
 
4
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6
  Everyone is permitted to copy and distribute verbatim copies
7
  of this license document, but changing it is not allowed.
8
 
15
  General Public License applies to most of the Free Software
16
  Foundation's software and to any other program whose authors commit to
17
  using it. (Some other Free Software Foundation software is covered by
18
+ the GNU Lesser General Public License instead.) You can apply it to
19
  your programs, too.
20
 
21
  When we speak of free software, we are referring to freedom, not
55
 
56
  The precise terms and conditions for copying, distribution and
57
  modification follow.
58
+
59
  GNU GENERAL PUBLIC LICENSE
60
  TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61
 
110
  License. (Exception: if the Program itself is interactive but
111
  does not normally print such an announcement, your work based on
112
  the Program is not required to print an announcement.)
113
+
114
  These requirements apply to the modified work as a whole. If
115
  identifiable sections of that work are not derived from the Program,
116
  and can be reasonably considered independent and separate works in
168
  access to copy the source code from the same place counts as
169
  distribution of the source code, even though third parties are not
170
  compelled to copy the source along with the object code.
171
+
172
  4. You may not copy, modify, sublicense, or distribute the Program
173
  except as expressly provided under this License. Any attempt
174
  otherwise to copy, modify, sublicense or distribute the Program is
225
 
226
  This section is intended to make thoroughly clear what is believed to
227
  be a consequence of the rest of this License.
228
+
229
  8. If the distribution and/or use of the Program is restricted in
230
  certain countries either by patents or by copyrighted interfaces, the
231
  original copyright holder who places the Program under this License
278
  POSSIBILITY OF SUCH DAMAGES.
279
 
280
  END OF TERMS AND CONDITIONS
281
+
282
+ How to Apply These Terms to Your New Programs
283
 
284
  If you develop a new program, and you want it to be of the greatest
285
  possible use to the public, the best way to achieve this is to make it
291
  the "copyright" line and a pointer to where the full notice is found.
292
 
293
  <one line to give the program's name and a brief idea of what it does.>
294
+ Copyright (C) <year> <name of author>
295
 
296
  This program is free software; you can redistribute it and/or modify
297
  it under the terms of the GNU General Public License as published by
303
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304
  GNU General Public License for more details.
305
 
306
+ You should have received a copy of the GNU General Public License along
307
+ with this program; if not, write to the Free Software Foundation, Inc.,
308
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309
 
310
  Also add information on how to contact you by electronic and paper mail.
311
 
312
  If the program is interactive, make it output a short notice like this
313
  when it starts in an interactive mode:
314
 
315
+ Gnomovision version 69, Copyright (C) year name of author
316
  Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317
  This is free software, and you are welcome to redistribute it
318
  under certain conditions; type `show c' for details.
335
  This General Public License does not permit incorporating your program into
336
  proprietary programs. If your program is a subroutine library, you may
337
  consider it more useful to permit linking proprietary applications with the
338
+ library. If this is what you want to do, use the GNU Lesser General
339
  Public License instead of this License.
README.txt CHANGED
@@ -1,41 +1,62 @@
1
  === Bad Behavior ===
2
  Tags: comment,trackback,referrer,spam,robot,antispam
3
- Contributors: MichaelHampton,MarkJaquith,FirasDurri
4
- SeeAlso: http://www.ioerror.us/software/bad-behavior/
 
 
 
5
 
6
- This README.txt file applies to WordPress installations. For other types of
7
- installations, please see the documentation at
8
- http://www.ioerror.us/software/bad-behavior/installing-and-using-bad-behavior/
9
- .
10
 
11
- Bad Behavior is a set of PHP scripts which prevents spambots from accessing your site by analyzing their actual HTTP requests and comparing them to profiles from known spambots. It goes far beyond User-Agent and Referer, however.
12
 
13
- The problem: Spammers run automated scripts which read everything on your web site, harvest email addresses, and if you have a blog, forum or wiki, will post spam directly to your site. They also put false referrers in your server log trying to get their links posted through your stats page.
 
 
 
 
14
 
15
- As the operator of a Web site, this can cause you several problems. First, the spammers are wasting your bandwidth, which you may well be paying for. Second, they are posting comments to any form they can find, filling your web site with unwanted (and unpaid!) ads for their products. Last but not least, they harvest any email addresses they can find and sell those to other spammers, who fill your inbox with more unwanted ads.
 
 
 
16
 
17
- Bad Behavior intends to target any malicious software directed at a Web site, whether it be a spambot, ill-designed search engine bot, or system crackers. In that spirit, it is not limited to WordPress users; a generic interface has been provided whereby it can be integrated into virtually any PHP-based software.
 
18
 
19
- == Installation ==
20
- SeeAlso: http://www.ioerror.us/software/bad-behavior/installing-and-using-bad-behavior/on-wordpress/
 
 
 
 
21
 
22
- 1. Bad Behavior installs like any other multi-file WordPress plugin. Unzip the bad-behavior.zip file, and you will have a bad-behavior folder containing all the Bad Behavior files.
 
 
 
23
 
24
- 2. Before uploading, edit the bad-behavior/bad-behavior-wordpress.php file and customize the configuration variables there. When logging is on, all blocked requests will be logged. When verbose logging is on, all requests - successful or not - will be logged. And the logging duration specifies how many days worth of logs will be stored in the database. I recommend not using verbose logging without a really good reason, as your database will fill up fast.
25
 
26
- 3. Upload the folder and its contents to your wp-content/plugins directory, taking care to use ASCII mode. Once on the server, activate the plugin from your admin page.
27
 
28
- == Frequently Asked Questions ==
29
- SeeAlso: http://www.ioerror.us/software/bad-behavior/bad-behavior-faq/
30
 
31
- = I have been blocked by Bad Behavior! What do I do? =
 
32
 
33
- In extremely rare circumstances, Bad Behavior may block actual human visitors. Bad Behavior was designed to target robots, not people. If this happens, the profile presented by your browser matched that seen from actual malicious robots. In most cases, this is caused by over-aggressive personal firewall/browser privacy software. In some cases, this is caused by improperly configured Web proxy server software.
 
34
 
35
- Try disabling the browser privacy settings in your personal firewall/browser privacy software, and/or bypassing the Web proxy and making a direct connection. Disable any download accelerators in use, especially if you are on dialup and your ISP provided you one. (These so-called accelerators rarely speed up anything; our analysis of these accelerators indicate they usually slow things down!) If all else fails, try a different Web browser with a new user profile.
 
36
 
37
- If you continue to have trouble, contact me and provide a copy of the logs which Bad Behavior stores in the database showing where your IP address was blocked. I will provide further assistance until the trouble is resolved.
38
 
39
- = How can I view Bad Behavior's log files? =
40
 
41
- To view the Bad Behavior log, you will need a copy of phpMyAdmin installed, or some other way to view the database. Bad Behavior stores its log in the wp_bad_behavior_log table in your WordPress database. Browse or search through it with phpMyAdmin, the MySQL command line, or another tool. At this time Bad Behavior does not come with a built-in log viewer, though this feature is planned.
 
1
  === Bad Behavior ===
2
  Tags: comment,trackback,referrer,spam,robot,antispam
3
+ Contributors: error, MarkJaquith, Firas, skeltoac
4
+ Donate link: http://www.bad-behavior.ioerror.us/
5
+ Requires at least: 1.2
6
+ Tested up to: 2.3.1
7
+ Stable tag: 2.0.11
8
 
9
+ Bad Behavior is a set of PHP scripts which prevents spambots and other
10
+ malicious accesses to your PHP-based Web site. It prevents comment spam,
11
+ trackback spam, guestbook spam, wiki spam, referrer spam, and some types
12
+ of malicious Web site hacking.
13
 
14
+ == Installation ==
15
 
16
+ *Warning*: If you are upgrading from a 1.x.x version of Bad Behavior,
17
+ you must remove it from your system entirely, and delete all of its
18
+ database tables, before installing Bad Behavior 2.0.x. You do not need
19
+ to remove a 2.0.x version of Bad Behavior before upgrading to this
20
+ release.
21
 
22
+ Bad Behavior has been designed to install on each host software in the
23
+ manner most appropriate to each platform. It's usually sufficient to
24
+ follow the generic instructions for installing any plugin or extension
25
+ for your host software.
26
 
27
+ For complete documentation and installation instructions, please visit
28
+ http://www.bad-behavior.ioerror.us/
29
 
30
+ == Warning ==
31
+
32
+ The WordPress-hosted copy of Bad Behavior should never be used in
33
+ conjunction with Dave's Spam Karma plugin. If you intend to use Spam
34
+ Karma and Bad Behavior together, always use the official copy from the
35
+ Bad Behavior home page at http://www.bad-behavior.ioerror.us/download/ .
36
 
37
+ The WordPress-hosted copy of Bad Behavior is unofficial and updated
38
+ only when a major bug or security fix is available. To ensure that you
39
+ always have the latest available release, always use the official copy
40
+ from the Bad Behavior home page at http://www.bad-behavior.ioerror.us/ .
41
 
42
+ == Release Notes ==
43
 
44
+ = Bad Behavior 2.0 Known Issues =
45
 
46
+ * Bad Behavior may be unable to protect cached pages on MediaWiki.
 
47
 
48
+ * On WordPress when using WordPress Advanced Cache (WP-Cache), Bad Behavior
49
+ requires a patch to WP-Cache 2 in order to protect cached pages.
50
 
51
+ Edit the wp-content/plugins/wp-cache/wp-cache-phase1.php file and find the
52
+ following two lines at around line 32:
53
 
54
+ ` if (! ($meta = unserialize(@file_get_contents($meta_pathname))) )
55
+ return;`
56
 
57
+ Immediately after this, insert the following line:
58
 
59
+ ` require_once( ABSPATH . 'wp-content/plugins/Bad-Behavior/bad-behavior-generic.php');`
60
 
61
+ Then visit your site. Everything should work normally, but spammers will
62
+ not be able to access your cached pages either.
bad-behavior-accept.php DELETED
@@ -1,40 +0,0 @@
1
- <?php
2
-
3
- // Check for various Accept: headers
4
-
5
- if (!defined('WP_BB_CWD'))
6
- die('');
7
-
8
- function wp_bb_check_accept() {
9
- global $wp_bb_http_headers_mixed;
10
- if (!array_key_exists('Accept', $wp_bb_http_headers_mixed)) {
11
- wp_bb_spammer("Required header 'Accept' missing");
12
- }
13
- }
14
-
15
- function wp_bb_check_accept_encoding() {
16
- global $wp_bb_http_headers, $wp_bb_http_headers_mixed;
17
-
18
- // FIXME: skip this check; too many examples of legit user agents
19
- // are omitting Accept-Encoding; come back to it later when more
20
- // data is available
21
- return;
22
-
23
- // In some cases we can skip this check
24
- // HTTP proxies munch the Accept-Encoding header
25
- if (array_key_exists('X-BlueCoat-Via', $wp_bb_http_headers_mixed) ||
26
- array_key_exists('X-Forwarded-For', $wp_bb_http_headers) ||
27
- array_key_exists('Via', $wp_bb_http_headers)) {
28
- return;
29
- }
30
-
31
- // Check for Accept-Encoding
32
- if (!array_key_exists('Accept-Encoding', $wp_bb_http_headers_mixed) &&
33
- !array_key_exists('~~~~~~~~~~~~~~~', $wp_bb_http_headers) &&
34
- !array_key_exists('---------------', $wp_bb_http_headers) &&
35
- !array_key_exists('XXXXXXXXXXXXXXX', $wp_bb_http_headers)) {
36
- wp_bb_spammer("Required header 'Accept-Encoding' missing");
37
- }
38
- }
39
-
40
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bad-behavior-banned.php DELETED
@@ -1,70 +0,0 @@
1
- <?php
2
- // This function is called when there is absolutely no hope for redemption for
3
- // the offending spammer.
4
- function wp_bb_banned($denied_reason) {
5
- global $wp_bb_request_uri, $wp_bb_remote_addr, $wp_bb_server_signature;
6
- global $wp_bb_email, $wp_bb_server_protocol;
7
-
8
- header($wp_bb_server_protocol . " 412 Precondition Failed");
9
- header("Status: 412 Precondition Failed");
10
- ?>
11
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
12
- <html xmlns="http://www.w3.org/1999/xhtml">
13
- <head>
14
- <title>412 Precondition Failed</title>
15
- </head>
16
- <body>
17
- <h1>Precondition Failed</h1>
18
- <p>We're sorry, but we could not fulfill your request for
19
- <?php echo htmlspecialchars($wp_bb_request_uri) ?> on this server.</p>
20
- <p>We have established rules for access to this server, and any person or robot
21
- that violates these rules will be unable to access this site.</p>
22
- <p>To resolve this problem, please try the following steps:</p>
23
- <ul>
24
- <li>Ensure that your computer is free of viruses, Trojan horses, spyware or
25
- any other sort of malicious software.</li>
26
- <li>If you are using any sort of personal firewall or browser privacy
27
- software, check to ensure that its settings do not cause your web browser to
28
- inadvertently violate any of the rules listed below.</li>
29
- <li>If you are behind a Web proxy or corporate firewall, the proxy must
30
- conform to the <a href="http://www.isi.edu/in-notes/rfc2616.txt">HTTP
31
- specification</a> with respect to proxy servers. Contact your network
32
- administrator if the trouble persists, or bypass the proxy and connect
33
- directly if possible.</li>
34
- <li>Disable any download accelerators you may be using. They don't speed up
35
- your downloads anyway; in most cases, they actually run slower!</li>
36
- <li>If all else fails, try using a different Web browser, such as
37
- <a href="http://www.spreadfirefox.com/?q=affiliates&amp;id=32135&amp;t=71">Firefox</a>.</li>
38
- </ul>
39
- <p>If you still need assistance, please contact <a href="mailto:<?php echo htmlspecialchars(str_replace("@", "+nospam@nospam.", $wp_bb_email)); ?>"><?php echo htmlspecialchars(str_replace("@", " at ", $wp_bb_email)); ?></a>.</p>
40
- <h2>More Information</h2>
41
- <p>For your reference, the conditions for access to this server are:</p>
42
- <h3>Robots:</h3>
43
- <ul>
44
- <li>MUST read and obey <a href="http://www.robotstxt.org/">robots.txt</a>.</li>
45
- <li>MUST identify themselves properly; for example MUST NOT identify as Mozilla.</li>
46
- <li>MUST NOT pretend to be a human.</li>
47
- </ul>
48
- <h3>Humans:</h3>
49
- <ul>
50
- <li>MUST NOT pretend to be a robot.</li>
51
- <li>MUST NOT use a computer infected with viruses, Trojan horses or other
52
- malicious software.</li>
53
- </ul>
54
- <h3>Both:</h3>
55
- <ul>
56
- <li>MUST NOT harvest email addresses.</li>
57
- <li>MUST NOT attempt to send spam.</li>
58
- <li>MUST NOT attempt to compromise server security.</li>
59
- <li>MUST NOT use excessive amounts of bandwidth or other server resources.</li>
60
- </ul>
61
- <p>The precondition on the request for the URL
62
- <?php echo htmlspecialchars($wp_bb_request_uri); ?> evaluated to false.</p>
63
- <hr>
64
- <?php echo htmlspecialchars($wp_bb_server_signature); ?>
65
- </body>
66
- </html>
67
- <?php
68
- die('');
69
- }
70
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bad-behavior-blackhole.php DELETED
@@ -1,70 +0,0 @@
1
- <?php
2
-
3
- // Set to false to NOT notify Bad Behavior Blackhole
4
- // You would do this if it's being slow or whatever
5
- $wp_bb_ping_blackhole = false;
6
-
7
- // Set the connection timeout in seconds.
8
- $wp_bb_ping_timeout = 15;
9
-
10
- if (!defined('WP_BB_CWD'))
11
- die('');
12
-
13
- function wp_bb_blackhole_ping($response, $denied_reason) {
14
- global $wp_bb_remote_addr, $wp_bb_request_method, $wp_bb_http_host;
15
- global $wp_bb_request_uri, $wp_bb_server_protocol, $wp_bb_http_referer;
16
- global $wp_bb_http_user_agent, $wp_bb_headers, $wp_bb_request_entity;
17
-
18
- $ping = "http://ping.ioerror.us/ping";
19
-
20
- $remote_addr = urlencode($wp_bb_remote_addr);
21
- $request_method = urlencode($wp_bb_request_method);
22
- $http_host = urlencode($wp_bb_http_host);
23
- $request_uri = urlencode($wp_bb_request_uri);
24
- $server_protocol = urlencode($wp_bb_server_protocol);
25
- $http_referer = urlencode($wp_bb_http_referer);
26
- $user_agent = urlencode($wp_bb_http_user_agent);
27
- $headers = urlencode($wp_bb_headers);
28
- $request_entity = urlencode($wp_bb_request_entity);
29
- $denied = urlencode($denied_reason);
30
-
31
- $query = "remote_addr=$remote_addr&request_method=$request_method&http_host=$http_host&request_uri=$request_uri&server_protocol=$server_protocol&http_referer=$http_referer&user_agent=$user_agent&headers=$headers&request_entity=$request_entity&denied_reason=$denied&http_response=$response";
32
-
33
- $ping_url = parse_url($ping);
34
- if ('' == $ping_url['port']) $ping_url['port'] = 80;
35
-
36
- $post_request = "POST " . $ping_url['path'] . ($ping_url['query'] ? "?".$ping_url['query'] : "") . " HTTP/1.0\r\n";
37
- $post_request .= "Host: " . $ping_url['host'] . "\r\n";
38
- $post_request .= "Content-Type: application/x-www-form-urlencoded; charset=utf-8\r\n";
39
- $post_request .= "Content-Length: " . strlen($query) . "\r\n";
40
- $post_request .= "User-Agent: Bad Behavior/" . WP_BB_VERSION . "\r\n";
41
- $post_request .= "\r\n" . $query;
42
-
43
- // Now determine HOW to send the ping
44
- $ping_sent = false;
45
- if (ini_get('allow_url_fopen') != false) {
46
- $fs = @fsockopen($ping_url['host'], $ping_url['port'], $errno, $errstr, $wp_bb_ping_timeout);
47
- if ($fs) {
48
- @fputs($fs, $post_request);
49
- // Don't bother with a response
50
- @fclose($fs);
51
- $ping_sent = true;
52
- }
53
- }
54
- if (!$ping_sent && is_callable('curl_init')) {
55
- $ch = curl_init($ping);
56
- curl_setopt($ch, CURLOPT_FORBID_REUSE, true);
57
- curl_setopt($ch, CURLOPT_POST, true);
58
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
59
- curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $wp_bb_ping_timeout);
60
- curl_setopt($ch, CURLOPT_PORT, $ping_url['port']);
61
- curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
62
- curl_setopt($ch, CURLOPT_USERAGENT, "Bad Behavior/" . WP_BB_VERSION);
63
- curl_exec($ch);
64
- $r = curl_getinfo($ch, CURLINFO_HTTP_CODE);
65
- if ($r >= 200 && $r <= 399) {
66
- $ping_sent = true;
67
- }
68
- }
69
- }
70
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bad-behavior-core.php DELETED
@@ -1,151 +0,0 @@
1
- <?php
2
-
3
- if (!defined('WP_BB_CWD'))
4
- die('');
5
-
6
- // die("Do NOT check Bad Behavior out of svn! Install the <a href=\"http://www.ioerror.us/software/bad-behavior/\">current version</a>.");
7
-
8
- define(WP_BB_VERSION, "1.2.2");
9
-
10
- require_once(WP_BB_CWD . "/bad-behavior-functions.php");
11
-
12
- // Write to the log file.
13
- function wp_bb_log($response, $denied_reason) {
14
- global $wp_bb_logging, $wp_bb_verbose_logging;
15
-
16
- if (($wp_bb_verbose_logging) || ($wp_bb_logging && ($response == 403 || $response == 412))) {
17
- require_once(WP_BB_CWD . "/bad-behavior-database.php");
18
- wp_bb_db_log($response, $denied_reason);
19
- }
20
- }
21
-
22
- // This function is called when there is absolutely no hope for redemption for
23
- // the offending spammer.
24
- function wp_bb_spammer($denied_reason) {
25
- global $wp_bb_http_headers_mixed;
26
-
27
- if (is_callable('wp_bb_denied_callback')) {
28
- wp_bb_denied_callback($wp_bb_http_headers_mixed, 403, $denied_reason);
29
- }
30
- wp_bb_log(403, $denied_reason);
31
- require_once(WP_BB_CWD . "/bad-behavior-banned.php");
32
- wp_bb_banned($denied_reason);
33
- }
34
-
35
- // Load up PHP4 specific stuff if needed
36
- if (version_compare(phpversion(), "5.0.0") < 0) {
37
- require_once(WP_BB_CWD . "/bad-behavior-php4.php");
38
- }
39
-
40
- // Set up some initial variables.
41
- $wp_bb_approved = 2;
42
- $wp_bb_db_failure = FALSE;
43
- $wp_bb_remote_addr = $_SERVER['REMOTE_ADDR'];
44
- $wp_bb_request_method = $_SERVER['REQUEST_METHOD'];
45
- $wp_bb_http_host = $_SERVER['HTTP_HOST'];
46
- $wp_bb_request_uri = $_SERVER['REQUEST_URI'];
47
- $wp_bb_server_protocol = $_SERVER['SERVER_PROTOCOL'];
48
- if (array_key_exists('HTTP_REFERER', $_SERVER))
49
- $wp_bb_http_referer = $_SERVER['HTTP_REFERER'];
50
- else
51
- $wp_bb_http_referer = '';
52
- $wp_bb_http_user_agent = $_SERVER['HTTP_USER_AGENT'];
53
- $wp_bb_server_signature = $_SERVER['SERVER_SIGNATURE'];
54
-
55
- // Load up database stuff only if requested
56
- if ($wp_bb_verbose_logging || $wp_bb_logging) {
57
- require_once(WP_BB_CWD . "/bad-behavior-database.php");
58
- }
59
-
60
- // Reconstruct the entire HTTP headers as received.
61
- $wp_bb_headers = "$wp_bb_request_method $wp_bb_request_uri $wp_bb_server_protocol\n";
62
- $wp_bb_http_headers = getheaders();
63
- foreach ($wp_bb_http_headers as $wp_bb_header => $wp_bb_value) {
64
- $wp_bb_headers .= "$wp_bb_header: $wp_bb_value\n";
65
- }
66
-
67
- // Reconstruct the HTTP entity, if present.
68
- $wp_bb_request_entity = "";
69
- if (!strcasecmp($wp_bb_request_method, "POST")) {
70
- foreach ($_POST as $wp_bb_header => $wp_bb_value) {
71
- $wp_bb_request_entity .= "$wp_bb_header: $wp_bb_value\n";
72
- }
73
- }
74
-
75
- // Postprocess the headers to mixed-case
76
- // FIXME: get the world to stop using PHP as CGI
77
- $wp_bb_http_headers_mixed = array();
78
- foreach ($wp_bb_http_headers as $h=>$v)
79
- $wp_bb_http_headers_mixed[uc_all($h)]=$v;
80
-
81
- // First check the whitelist
82
- require_once(WP_BB_CWD . "/bad-behavior-whitelist.php");
83
- if (!wp_bb_check_whitelist()):
84
-
85
- // Easy stuff: Ban known bad user-agents
86
- require_once(WP_BB_CWD . "/bad-behavior-user-agent.php");
87
-
88
- // Now analyze requests coming from "MSIE"
89
- if (stripos($wp_bb_http_user_agent, "MSIE") !== FALSE) {
90
- if (stripos($wp_bb_http_user_agent, "Opera") === FALSE) {
91
- require_once(WP_BB_CWD . "/bad-behavior-msie.php");
92
- } else {
93
- require_once(WP_BB_CWD . "/bad-behavior-opera.php");
94
- }
95
- }
96
- elseif (stripos($wp_bb_http_user_agent, "msnbot") !== FALSE) {
97
- require_once(WP_BB_CWD . "/bad-behavior-msnbot.php");
98
- }
99
- elseif (stripos($wp_bb_http_user_agent, "Googlebot") !== FALSE ||
100
- stripos($wp_bb_http_user_agent, "Mediapartners-Google") !== FALSE) {
101
- require_once(WP_BB_CWD . "/bad-behavior-google.php");
102
- }
103
- // Now analyze requests coming from "Konqueror"
104
- elseif (stripos($wp_bb_http_user_agent, "Konqueror") !== FALSE) {
105
- require_once(WP_BB_CWD . "/bad-behavior-konqueror.php");
106
- }
107
- elseif (stripos($wp_bb_http_user_agent, "Opera") !== FALSE) {
108
- require_once(WP_BB_CWD . "/bad-behavior-opera.php");
109
- }
110
- elseif (stripos($wp_bb_http_user_agent, "Safari") !== FALSE) {
111
- require_once(WP_BB_CWD . "/bad-behavior-safari.php");
112
- }
113
- elseif (stripos($wp_bb_http_user_agent, "Lynx") !== FALSE) {
114
- require_once(WP_BB_CWD . "/bad-behavior-lynx.php");
115
- }
116
- elseif (stripos($wp_bb_http_user_agent, "MovableType") !== FALSE) {
117
- require_once(WP_BB_CWD . "/bad-behavior-movabletype.php");
118
- }
119
- elseif (stripos($wp_bb_http_user_agent, "Mozilla") !== FALSE &&
120
- stripos($wp_bb_http_user_agent, "Mozilla") == 0) {
121
- require_once(WP_BB_CWD . "/bad-behavior-mozilla.php");
122
- }
123
-
124
- // Analyze the Referer, if present
125
- if (array_key_exists('Referer', $wp_bb_http_headers_mixed)) {
126
- require_once(WP_BB_CWD . "/bad-behavior-referer.php");
127
- }
128
-
129
- // Now analyze all other requests
130
- require_once(WP_BB_CWD . "/bad-behavior-http-headers.php");
131
-
132
- // Finally see if it's a spammer we know about
133
- if ($wp_bb_logging && wp_bb_db_search()) {
134
- $denied_reason = "I know you and I don't like you, dirty spammer.";
135
- if (is_callable('wp_bb_denied_callback')) {
136
- wp_bb_denied_callback($wp_bb_http_headers_mixed, 412, $denied_reason);
137
- }
138
- wp_bb_log(412, $denied_reason);
139
- require_once(WP_BB_CWD . "/bad-behavior-banned.php");
140
- wp_bb_banned($denied_reason);
141
- }
142
-
143
- endif; // whitelist
144
-
145
- // If we get this far, the client is probably OK
146
- if (is_callable('wp_bb_approved_callback')) {
147
- wp_bb_approved_callback($wp_bb_http_headers_mixed);
148
- }
149
- wp_bb_log(200, '');
150
-
151
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bad-behavior-database.php DELETED
@@ -1,121 +0,0 @@
1
- <?php
2
-
3
- // Database functions. This needs review to ensure it isn't MySQL specific;
4
- // it certainly is right now.
5
-
6
- if (!defined('WP_BB_CWD'))
7
- die('');
8
-
9
- function wp_bb_db_create_tables() {
10
- global $wp_bb_db_failure;
11
-
12
- if (defined("WP_BB_NO_CREATE"))
13
- return;
14
-
15
- // Determine if we can skip all this
16
- // If this exists, table structure is presumed up to date
17
- // $query = "DESCRIBE `" . WP_BB_LOG . "` `denied_reason`;";
18
- // if (wp_bb_db_query($query) != 0) return;
19
-
20
- // Create everything
21
- $query = "CREATE TABLE IF NOT EXISTS `" . WP_BB_LOG . "` (
22
- `id` int(11) NOT NULL auto_increment,
23
- `ip` text NOT NULL,
24
- `date` datetime NOT NULL default '0000-00-00 00:00:00',
25
- `request_method` text NOT NULL,
26
- `http_host` text,
27
- `request_uri` text NOT NULL,
28
- `server_protocol` text NOT NULL,
29
- `http_referer` text,
30
- `http_user_agent` text,
31
- `http_headers` text NOT NULL,
32
- `request_entity` text NOT NULL,
33
- `denied_reason` text NOT NULL,
34
- `http_response` int(3) NOT NULL,
35
- PRIMARY KEY (`id`) );";
36
- if (wp_bb_db_query($query) === FALSE) {
37
- $wp_bb_db_failure = TRUE;
38
- }
39
- // Upgrades from 1.0
40
- $query = "DESCRIBE `" . WP_BB_LOG . "` `request_entity`;";
41
- if (wp_bb_db_query($query) == 0) {
42
- $query = "ALTER TABLE `" . WP_BB_LOG . "` ADD `request_entity` TEXT AFTER `http_headers`;";
43
- if (wp_bb_db_query($query) === FALSE) {
44
- $wp_bb_db_failure = TRUE;
45
- }
46
- }
47
- // Upgrades from 1.1
48
- $query = "DESCRIBE `" . WP_BB_LOG . "` `denied_reason`;";
49
- if (wp_bb_db_query($query) == 0) {
50
- $query = "ALTER TABLE `" . WP_BB_LOG . "` ADD `denied_reason` TEXT AFTER `request_entity`;";
51
- if (wp_bb_db_query($query) === FALSE) {
52
- $wp_bb_db_failure = TRUE;
53
- }
54
- }
55
- }
56
-
57
- function wp_bb_db_clear_old_entries() {
58
- global $wp_bb_logging_duration;
59
-
60
- $query = "DELETE FROM `" . WP_BB_LOG . "` WHERE
61
- `date` < DATE_SUB('" . gmstrftime("%Y-%m-%d %H:%M:%S") .
62
- "', INTERVAL $wp_bb_logging_duration DAY)";
63
- if (wp_bb_db_query($query) === FALSE) {
64
- $wp_bb_db_failure = TRUE;
65
- }
66
- }
67
-
68
- // This sanitizes input for SQL! not necessarily for anything else
69
- function wp_bb_db_sanitize($untrusted_input) {
70
- return addslashes($untrusted_input);
71
- }
72
-
73
- function wp_bb_db_log($response, $denied_reason = '') {
74
- global $wp_bb_remote_addr, $wp_bb_request_method, $wp_bb_http_host;
75
- global $wp_bb_request_uri, $wp_bb_server_protocol, $wp_bb_http_referer;
76
- global $wp_bb_http_user_agent, $wp_bb_headers;
77
- global $wp_bb_request_entity;
78
-
79
- // Sanitize input
80
- $remote_addr = wp_bb_db_sanitize($wp_bb_remote_addr);
81
- $request_method = wp_bb_db_sanitize($wp_bb_request_method);
82
- $host = wp_bb_db_sanitize($wp_bb_http_host);
83
- $request_uri = wp_bb_db_sanitize($wp_bb_request_uri);
84
- $server_protocol = wp_bb_db_sanitize($wp_bb_server_protocol);
85
- $referer = wp_bb_db_sanitize($wp_bb_http_referer);
86
- $user_agent = wp_bb_db_sanitize($wp_bb_http_user_agent);
87
- $headers = wp_bb_db_sanitize($wp_bb_headers);
88
- $request_entity = wp_bb_db_sanitize($wp_bb_request_entity);
89
- $denied_reason = wp_bb_db_sanitize($denied_reason);
90
- $response = intval($response);
91
-
92
- $date = wp_bb_date();
93
- $query = "INSERT INTO `" . WP_BB_LOG . "`
94
- (`ip`, `date`, `request_method`, `http_host`, `request_uri`, `server_protocol`, `http_referer`, `http_user_agent`, `http_headers`, `request_entity`, `denied_reason`, `http_response`) VALUES
95
- ('$remote_addr', '$date', '$request_method', '$host', '$request_uri', '$server_protocol', '$referer', '$user_agent', '$headers', '$request_entity', '$denied_reason', '$response')";
96
- if (wp_bb_db_query($query) === FALSE) {
97
- $wp_bb_db_failure = TRUE;
98
- }
99
- }
100
-
101
- // See if we've seen this spammer recently.
102
- // Interval is 10 minutes for 1 spam attempt, double it for each additional
103
- function wp_bb_db_search() {
104
- global $wp_bb_remote_addr;
105
-
106
- $query = "SELECT `ip` FROM `" . WP_BB_LOG . "` WHERE `ip` LIKE '" . $wp_bb_remote_addr . "' AND `http_response` = 403";
107
- $count = wp_bb_db_query($query);
108
-
109
- if ($count === FALSE)
110
- return FALSE;
111
-
112
- $interval = pow(2, ($count - 1)) * 10;
113
-
114
- $query = "SELECT `ip` FROM `" . WP_BB_LOG . "` WHERE `ip` LIKE '" . $wp_bb_remote_addr . "' AND `http_response` = 403 AND `date` > DATE_SUB('" . gmstrftime("%Y-%m-%d %H:%M:%S") . "', INTERVAL $interval MINUTE)";
115
- return wp_bb_db_query($query);
116
- }
117
-
118
- wp_bb_db_create_tables();
119
- register_shutdown_function('wp_bb_db_clear_old_entries');
120
- // wp_bb_db_clear_old_entries();
121
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bad-behavior-functions.php DELETED
@@ -1,47 +0,0 @@
1
- <?php
2
-
3
- // Convert a string to mixed-case on word boundaries
4
- function uc_all($string) {
5
- $temp = preg_split('/(\W)/', str_replace("_", "-", $string), -1, PREG_SPLIT_DELIM_CAPTURE );
6
- foreach ($temp as $key=>$word) {
7
- $temp[$key] = ucfirst(strtolower($word));
8
- }
9
- return join ('', $temp);
10
- }
11
-
12
- // Obtain all the HTTP headers.
13
- // NB: on PHP-CGI we hve to fake it out a bit, since we can't get the raw
14
- // headers
15
- function getheaders() {
16
- if (!is_callable('getallheaders')) {
17
- $headers = array();
18
- foreach($_SERVER as $h=>$v)
19
- if(ereg('HTTP_(.+)',$h,$hp))
20
- $headers[str_replace("_", "-", uc_all($hp[1]))]=$v;
21
- return $headers;
22
- } else {
23
- return getallheaders();
24
- }
25
- }
26
-
27
- // $addr should be an ip address in the format '0.0.0.0'
28
- // $cidr should be a string in the format '100/8'
29
- // or an array where each element is in the above format
30
- function matchCIDR($addr, $cidr) {
31
- $output = false;
32
-
33
- if ( is_array($cidr) ) {
34
- foreach ( $cidr as $cidrlet ) {
35
- if ( matchCIDR( $addr, $cidrlet) ) {
36
- $output = true;
37
- }
38
- }
39
- } else {
40
- list($ip, $mask) = explode('/', $cidr);
41
- $mask = 0xffffffff << (32 - $mask);
42
- $output = ((ip2long($addr) & $mask) == (ip2long($ip) & $mask));
43
- }
44
- return $output;
45
- }
46
-
47
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bad-behavior-generic.php CHANGED
@@ -1,15 +1,18 @@
1
  <?php
2
  /*
3
- http://www.ioerror.us/software/bad-behavior/
4
-
5
  Bad Behavior - detects and blocks unwanted Web accesses
6
- Copyright (C) 2005 Michael Hampton
7
 
8
  This program is free software; you can redistribute it and/or modify
9
  it under the terms of the GNU General Public License as published by
10
  the Free Software Foundation; either version 2 of the License, or
11
  (at your option) any later version.
12
 
 
 
 
 
 
13
  This program is distributed in the hope that it will be useful,
14
  but WITHOUT ANY WARRANTY; without even the implied warranty of
15
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@@ -18,64 +21,120 @@ GNU General Public License for more details.
18
  You should have received a copy of the GNU General Public License
19
  along with this program; if not, write to the Free Software
20
  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
- */
22
 
23
- // This file is the entry point for Bad Behavior.
24
- // See below to customize it for your particular CMS or PHP application.
25
- // Preferably by the time this file is loaded, everything in your app will
26
- // be initialized, but no output sent to the browser. If output has been
27
- // sent, Bad Behavior will fail.
28
 
29
  ###############################################################################
30
  ###############################################################################
31
 
32
- // Configuration
33
- // Nothing will be written to a DB unless you implement DB queries below
34
 
35
- // Log failed requests to the database.
36
- $wp_bb_logging = TRUE;
 
 
 
 
 
 
37
 
38
- // Log all requests to the database, not just failed requests.
39
- $wp_bb_verbose_logging = TRUE;
40
 
41
- // How long to keep the logs around (in days).
42
- // Lowering this may have profound negative effects!
43
- $wp_bb_logging_duration = 7;
 
44
 
45
- // Email address to contact you in case of problems
46
- // This will be shown to users on the error page, which means it will
47
- // be exposed to spammers! Bad Behavior will munge it automatically; you
48
- // should NOT munge it here!
49
- $wp_bb_email = "badbots@ioerror.us";
50
 
51
- // The database table name to use.
52
- // You can customize the table name if necessary.
53
- define('WP_BB_LOG', /* $software_specific_prefix . */ 'bad_behavior_log');
 
 
54
 
55
- ###############################################################################
 
 
 
 
 
56
 
57
- # DO NOT EDIT BELOW THIS LINE
 
 
 
 
 
58
 
59
- ###############################################################################
 
 
 
 
 
60
 
61
- define('WP_BB_CWD', dirname(__FILE__));
 
 
 
 
62
 
63
- // Callbacks
 
 
 
 
 
64
 
65
- // generic code; you should reimplement these if you want logging and
66
- // database functions
 
 
67
 
68
- // return a UTC date in the format preferred by your database
69
- function wp_bb_date() {
70
- return gmdate('Y-m-d H:i:s');
71
  }
72
 
73
- // run a SQL query and return # of rows affected, or FALSE if query failed
74
- function wp_bb_db_query($query) {
75
- return FALSE;
 
 
 
 
76
  }
77
 
78
- // Load core functions and do initial checks
79
- require_once(WP_BB_CWD . "/bad-behavior-core.php");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
 
81
  ?>
1
  <?php
2
  /*
 
 
3
  Bad Behavior - detects and blocks unwanted Web accesses
4
+ Copyright (C) 2005-2006 Michael Hampton
5
 
6
  This program is free software; you can redistribute it and/or modify
7
  it under the terms of the GNU General Public License as published by
8
  the Free Software Foundation; either version 2 of the License, or
9
  (at your option) any later version.
10
 
11
+ As a special exemption, you may link this program with any of the
12
+ programs listed below, regardless of the license terms of those
13
+ programs, and distribute the resulting program, without including the
14
+ source code for such programs: ExpressionEngine
15
+
16
  This program is distributed in the hope that it will be useful,
17
  but WITHOUT ANY WARRANTY; without even the implied warranty of
18
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
  You should have received a copy of the GNU General Public License
22
  along with this program; if not, write to the Free Software
23
  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
24
 
25
+ Please report any problems to badbots AT ioerror DOT us
26
+ */
 
 
 
27
 
28
  ###############################################################################
29
  ###############################################################################
30
 
31
+ define('BB2_CWD', dirname(__FILE__));
 
32
 
33
+ // Settings you can adjust for Bad Behavior.
34
+ // Most of these are unused in non-database mode.
35
+ $bb2_settings_defaults = array(
36
+ 'log_table' => 'bad_behavior',
37
+ 'display_stats' => true,
38
+ 'strict' => false,
39
+ 'verbose' => false
40
+ );
41
 
42
+ // Bad Behavior callback functions.
 
43
 
44
+ // Return current time in the format preferred by your database.
45
+ function bb2_db_date() {
46
+ return gmdate('Y-m-d H:i:s'); // Example is MySQL format
47
+ }
48
 
49
+ // Return affected rows from most recent query.
50
+ function bb2_db_affected_rows() {
51
+ return false;
52
+ }
 
53
 
54
+ // Escape a string for database usage
55
+ function bb2_db_escape($string) {
56
+ // return mysql_real_escape_string($string);
57
+ return $string; // No-op when database not in use.
58
+ }
59
 
60
+ // Return the number of rows in a particular query.
61
+ function bb2_db_num_rows($result) {
62
+ if ($result !== FALSE)
63
+ return count($result);
64
+ return 0;
65
+ }
66
 
67
+ // Run a query and return the results, if any.
68
+ // Should return FALSE if an error occurred.
69
+ // Bad Behavior will use the return value here in other callbacks.
70
+ function bb2_db_query($query) {
71
+ return FALSE;
72
+ }
73
 
74
+ // Return all rows in a particular query.
75
+ // Should contain an array of all rows generated by calling mysql_fetch_assoc()
76
+ // or equivalent and appending the result of each call to an array.
77
+ function bb2_db_rows($result) {
78
+ return $result;
79
+ }
80
 
81
+ // Return emergency contact email address.
82
+ function bb2_email() {
83
+ // return "example@example.com"; // You need to change this.
84
+ return "badbots@ioerror.us"; // You need to change this.
85
+ }
86
 
87
+ // retrieve settings from database
88
+ // Settings are hard-coded for non-database use
89
+ function bb2_read_settings() {
90
+ global $bb2_settings_defaults;
91
+ return $bb2_settings_defaults;
92
+ }
93
 
94
+ // write settings to database
95
+ function bb2_write_settings($settings) {
96
+ return false;
97
+ }
98
 
99
+ // installation
100
+ function bb2_install() {
101
+ return false;
102
  }
103
 
104
+ // Screener
105
+ // Insert this into the <head> section of your HTML through a template call
106
+ // or whatever is appropriate. This is optional we'll fall back to cookies
107
+ // if you don't use it.
108
+ function bb2_insert_head() {
109
+ global $bb2_javascript;
110
+ echo $bb2_javascript;
111
  }
112
 
113
+ // Display stats? This is optional.
114
+ function bb2_insert_stats($force = false) {
115
+ $settings = bb2_read_settings();
116
+
117
+ if ($force || $settings['display_stats']) {
118
+ $blocked = bb2_db_query("SELECT COUNT(*) FROM " . $settings['log_table'] . " WHERE `key` NOT LIKE '00000000'");
119
+ if ($blocked !== FALSE) {
120
+ echo sprintf('<p><a href="http://www.bad-behavior.ioerror.us/">%1$s</a> %2$s <strong>%3$s</strong> %4$s</p>', __('Bad Behavior'), __('has blocked'), $blocked[0]["COUNT(*)"], __('access attempts in the last 7 days.'));
121
+ }
122
+ }
123
+ }
124
+
125
+ // Return the top-level relative path of wherever we are (for cookies)
126
+ // You should provide in $url the top-level URL for your site.
127
+ function bb2_relative_path() {
128
+ //$url = parse_url(get_bloginfo('url'));
129
+ //return $url['path'] . '/';
130
+ return '/';
131
+ }
132
+
133
+ // Calls inward to Bad Behavor itself.
134
+ require_once(BB2_CWD . "/bad-behavior/version.inc.php");
135
+ require_once(BB2_CWD . "/bad-behavior/core.inc.php");
136
+ bb2_install(); // FIXME: see above
137
+
138
+ bb2_start(bb2_read_settings());
139
 
140
  ?>
bad-behavior-google.php DELETED
@@ -1,14 +0,0 @@
1
- <?php
2
-
3
- // This file is included only when the user-agent is claiming to be Google
4
-
5
- if (!defined('WP_BB_CWD'))
6
- die('');
7
-
8
- // require_once(WP_BB_CWD . "/bad-behavior-accept.php");
9
-
10
- if (matchCIDR($wp_bb_remote_addr, "66.249.64.0/19") === FALSE) {
11
- wp_bb_spammer("User-Agent claimed to be Googlebot, claim appears to be false");
12
- }
13
-
14
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bad-behavior-http-headers.php DELETED
@@ -1,49 +0,0 @@
1
- <?php
2
-
3
- if (!defined('WP_BB_CWD'))
4
- die('');
5
-
6
- // Analyze the headers of all user-agents
7
- // These checks apply to any user-agent regardless of identification
8
-
9
- // Range: field exists and begins with 0
10
- // Real user-agents do not start ranges at 0
11
- // NOTE: this blocks the whois.sc bot. No big loss.
12
- // FIXME: whitelist whois.sc netblocks when rwhoisd.ccom.net becomes available
13
- if (array_key_exists('Range', $wp_bb_http_headers_mixed) &&
14
- strpos($wp_bb_http_headers_mixed['Range'], "=0-") !== FALSE) {
15
- if (strncmp($wp_bb_http_user_agent, "MovableType", 11))
16
- wp_bb_spammer("Prohibited header 'Range' present");
17
- }
18
-
19
- // Lowercase via is used by open proxies/referrer spammers
20
- if (array_key_exists('via', $wp_bb_http_headers)) {
21
- wp_bb_spammer("Prohibited header 'via' present");
22
- }
23
- // pinappleproxy is used by referrer spammers
24
- if (array_key_exists('Via', $wp_bb_http_headers_mixed)) {
25
- if (stripos($wp_bb_http_headers_mixed['Via'], "pinappleproxy") !== FALSE ||
26
- stripos($wp_bb_http_headers_mixed['Via'], "PCNETSERVER") !== FALSE ||
27
- stripos($wp_bb_http_headers_mixed['Via'], "Invisiware") !== FALSE) {
28
- wp_bb_spammer("Banned proxy server '" . $wp_bb_http_headers_mixed['Via'] . "' in use");
29
- }
30
- }
31
-
32
- // TE: if present must have Connection: TE
33
- // RFC 2616 14.39
34
- // FIXME: This check is temporarily disabled due to bug in Opera 8
35
- /*
36
- if (array_key_exists('Te', $wp_bb_http_headers_mixed)) {
37
- if (!preg_match('/\bTE\b/', $wp_bb_http_headers_mixed['Connection'])) {
38
- wp_bb_spammer("Header 'TE' present but TE not specified in 'Connection' header");
39
- }
40
- }
41
- */
42
-
43
- // Headers which are not seen from normal user agents; only malicious bots
44
- if (array_key_exists('X-Aaaaaaaaaaaa', $wp_bb_http_headers_mixed) ||
45
- array_key_exists('X-Aaaaaaaaaa', $wp_bb_http_headers_mixed)) {
46
- wp_bb_spammer("Prohibited header 'X-Aaaaaaaaaa' or 'X-Aaaaaaaaaaaa' present");
47
- }
48
-
49
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bad-behavior-konqueror.php DELETED
@@ -1,23 +0,0 @@
1
- <?php
2
-
3
- // This file is included only when the user-agent is claiming to be Konqueror
4
- // (or some variant thereof). We check the HTTP headers to see if it really
5
- // is Konqueror.
6
-
7
- if (!defined('WP_BB_CWD'))
8
- die('');
9
-
10
- require_once(WP_BB_CWD . "/bad-behavior-accept.php");
11
-
12
- // CafeKelsa is a dev project at Yahoo which indexes job listings for
13
- // Yahoo! HotJobs. It identifies as Konqueror so we skip these checks.
14
- if (stripos($wp_bb_http_user_agent, "YahooSeeker/CafeKelsa") === FALSE ||
15
- matchCIDR($wp_bb_remote_addr, "209.73.160.0/19") === FALSE) {
16
- // Konqueror always sends the Accept: header.
17
- wp_bb_check_accept();
18
-
19
- // Konqueror always sends the Accept-Encoding: header.
20
- wp_bb_check_accept_encoding();
21
- }
22
-
23
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bad-behavior-lifetype.php ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ http://blog.markplace.net
4
+
5
+ Bad Behavior - LifeType Plugin
6
+ Copyright (C) 2006 Mark Wu http://blog.markplace.net
7
+
8
+ This program is free software; you can redistribute it and/or modify
9
+ it under the terms of the GNU General Public License as published by
10
+ the Free Software Foundation; either version 2 of the License, or
11
+ (at your option) any later version.
12
+
13
+ This program is distributed in the hope that it will be useful,
14
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ GNU General Public License for more details.
17
+
18
+ You should have received a copy of the GNU General Public License
19
+ along with this program; if not, write to the Free Software
20
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
+ */
22
+
23
+ // This file is the entry point for Bad Behavior in LifeType.
24
+
25
+ if (!defined('PLOG_CLASS_PATH')) die('No cheating!');
26
+
27
+ define('BB2_CWD', PLOG_CLASS_PATH );
28
+ define('BB2_EMERGENCY_EMAIL', "admin@yourblog.com" );
29
+
30
+ // Bad Behavior callback functions.
31
+
32
+ // Return current time in the format preferred by your database.
33
+ function bb2_db_date() {
34
+ return gmdate('Y-m-d H:i:s');
35
+ }
36
+
37
+ // Return affected rows from most recent query.
38
+ function bb2_db_affected_rows() {
39
+ include_once( PLOG_CLASS_PATH."class/database/db.class.php" );
40
+ $db =& Db::getDb();
41
+
42
+ return $db->Affected_Rows();
43
+ }
44
+
45
+ // Escape a string for database usage
46
+ function bb2_db_escape($string) {
47
+ include_once( PLOG_CLASS_PATH."class/database/db.class.php" );
48
+
49
+ return Db::qstr($string);
50
+ }
51
+
52
+ // Return the number of rows in a particular query.
53
+ function bb2_db_num_rows($result) {
54
+ return $result->RecordCount();
55
+ }
56
+
57
+ // Run a query and return the results, if any.
58
+ // Should return FALSE if an error occurred.
59
+ function bb2_db_query($query) {
60
+ include_once( PLOG_CLASS_PATH."class/database/db.class.php" );
61
+ $db =& Db::getDb();
62
+
63
+ $result = $db->Execute( $query );
64
+
65
+ if (!$result)
66
+ return false;
67
+
68
+ return $result;
69
+ }
70
+
71
+ // Return all rows in a particular query.
72
+ // Should contain an array of all rows generated by calling mysql_fetch_assoc()
73
+ // or equivalent and appending the result of each call to an array.
74
+ function bb2_db_rows($result) {
75
+ $rows = array();
76
+ while( $row = $result->FetchRow()) {
77
+ $rows[] = $row;
78
+ }
79
+
80
+ return $rows;
81
+ }
82
+
83
+ // Return emergency contact email address.
84
+ function bb2_email() {
85
+ return BB2_EMERGENCY_EMAIL;
86
+ }
87
+
88
+ // retrieve settings from lifetype config
89
+ function bb2_read_settings() {
90
+ include_once( PLOG_CLASS_PATH."class/database/db.class.php" );
91
+ include_once( PLOG_CLASS_PATH."class/config/config.class.php" );
92
+ $config =& Config::getConfig();
93
+ $prefix = Db::getPrefix();
94
+ $displayStats = $config->getValue( 'bb2_display_stats', true );
95
+ $verbose = $config->getValue( 'bb2_verbose', false );
96
+ $isInstalled = $config->getValue( 'bb2_installed', false );
97
+
98
+ return array('log_table' => $prefix . 'bad_behavior',
99
+ 'display_stats' => $displayStats,
100
+ 'verbose' => $verbose,
101
+ 'is_installed' => $isInstalled );
102
+ }
103
+
104
+ // write settings to lifetype config
105
+ function bb2_write_settings($settings) {
106
+ include_once( PLOG_CLASS_PATH."class/config/config.class.php" );
107
+ $config =& Config::getConfig();
108
+
109
+ $config->setValue( 'bb2_display_stats', $settings['display_stats'] );
110
+ $config->setValue( 'bb2_verbose', $settings['verbose'] );
111
+ $config->setValue( 'bb2_installed', $settings['is_installed'] );
112
+ $config->save();
113
+ }
114
+
115
+ // installation
116
+ function bb2_install() {
117
+ $settings = bb2_read_settings();
118
+ if( $settings['is_installed'] == false )
119
+ {
120
+ bb2_db_query(bb2_table_structure($settings['log_table']));
121
+ $settings['is_installed'] = true;
122
+ bb2_write_settings( $settings );
123
+ }
124
+ }
125
+
126
+ // Return the top-level relative path of wherever we are (for cookies)
127
+ function bb2_relative_path() {
128
+ include_once( PLOG_CLASS_PATH."class/config/config.class.php" );
129
+ $config =& Config::getConfig();
130
+
131
+ $url = parse_url( $config->getValue( 'base_url' ) );
132
+ if( empty($url['path']) )
133
+ return '/';
134
+ else {
135
+ if( substr( $url['path'], -1, 1 ) == '/' )
136
+ return $url['path'];
137
+ else
138
+ return $url['path'] . '/';
139
+ }
140
+ }
141
+
142
+ // Start Bad Behavior investigation
143
+ require_once(BB2_CWD . "/bad-behavior/version.inc.php");
144
+ require_once(BB2_CWD . "/bad-behavior/core.inc.php");
145
+ bb2_install();
146
+ $settings = bb2_read_settings();
147
+ bb2_start($settings);
148
+ ?>
bad-behavior-lynx.php DELETED
@@ -1,13 +0,0 @@
1
- <?php
2
-
3
- // Analyze user agents claiming to be Lynx
4
-
5
- if (!defined('WP_BB_CWD'))
6
- die('');
7
-
8
- require_once(WP_BB_CWD . "/bad-behavior-accept.php");
9
-
10
- wp_bb_check_accept();
11
- wp_bb_check_accept_encoding();
12
-
13
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
bad-behavior-mediawiki.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
  /*
3
- http://www.ioerror.us/software/bad-behavior/
4
 
5
  Bad Behavior - detects and blocks unwanted Web accesses
6
  Copyright (C) 2005 Michael Hampton
@@ -21,94 +21,134 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
  */
22
 
23
  // This file is the entry point for Bad Behavior.
24
- // See below to customize it for your particular CMS or PHP application.
25
- // Preferably by the time this file is loaded, everything in your app will
26
- // be initialized, but no output sent to the browser. If output has been
27
- // sent, Bad Behavior will fail.
28
 
29
- if (!defined('MEDIAWIKI'))
30
- die('');
31
 
32
- ###############################################################################
33
- ###############################################################################
 
 
 
 
 
34
 
35
- // Configuration
36
- // To change the following settings, override them in MediaWiki's
37
- // LocalSettings.php after including this file.
38
 
39
- // In some configurations the automatic table creation may fail.
40
- // You can create the table manually (see query in bad-behavior-database.php)
41
- // and add this line to your LocalSettings.php:
42
- //
43
- // define('WP_BB_NO_CREATE', true);
44
 
45
- // Log failed requests to the database.
46
- $wp_bb_logging = TRUE;
 
 
47
 
48
- // Log all requests to the database, not just failed requests.
49
- $wp_bb_verbose_logging = TRUE;
 
 
50
 
51
- // How long to keep the logs around (in days).
52
- // Lowering this may have profound negative effects!
53
- $wp_bb_logging_duration = 7;
 
 
54
 
55
- // Email address to contact you in case of problems
56
- // This will be shown to users on the error page, which means it will
57
- // be exposed to spammers! Bad Behavior will munge it automatically; you
58
- // should NOT munge it here!
59
- $wp_bb_email = $wgEmergencyContact;
60
 
61
- // The database table name to use.
62
- // You can customize the table name if necessary.
63
- define('WP_BB_LOG', $wgDBprefix . 'bad_behavior_log');
 
 
 
64
 
65
- ###############################################################################
 
 
 
 
 
 
 
 
 
66
 
67
- # DO NOT EDIT BELOW THIS LINE
 
 
 
 
68
 
69
- ###############################################################################
 
 
 
 
 
70
 
71
- define('WP_BB_CWD', dirname(__FILE__));
 
 
 
 
72
 
73
- // Callbacks
 
 
 
 
 
74
 
75
- // generic code; you should reimplement these if you want logging and
76
- // database functions
 
 
 
 
77
 
78
- // return a UTC date in the format preferred by your database
79
- function wp_bb_date() {
80
- return gmdate('Y-m-d H:i:s');
 
 
81
  }
82
 
83
- // run a SQL query and return # of rows affected, or FALSE if query failed
84
- function wp_bb_db_query($query) {
85
- $res = wfQuery($query, DB_WRITE);
86
- if (stristr($query, "select") !== FALSE ||
87
- stristr($query, "describe") !== FALSE)
88
- return wfNumRows($res);
89
- else
90
- return wfAffectedRows($res);
91
  }
92
 
93
- // Load core functions and do initial checks
94
- // This will be run during extension initialization at the end of Setup.php
95
- function wp_bb_mediawiki_run() {
96
- // globals defined here
97
- global $wp_bb_logging, $wp_bb_verbose_logging, $wp_bb_logging_duration, $wp_bb_email;
98
-
99
- // globals defined in core
100
- global $wp_bb_approved, $wp_bb_db_failure;
101
- global $wp_bb_remote_addr, $wp_bb_request_method, $wp_bb_http_host;
102
- global $wp_bb_request_uri, $wp_bb_server_protocol, $wp_bb_http_referer;
103
- global $wp_bb_http_user_agent, $wp_bb_server_signature;
104
- global $wp_bb_headers, $wp_bb_http_headers, $wp_bb_http_headers_mixed;
105
- global $wp_bb_request_entity;
106
-
107
- // Don't try to run for command-line maintenance scripts.
108
- if (php_sapi_name() != 'cli')
109
- require_once(WP_BB_CWD . "/bad-behavior-core.php");
110
  }
111
 
112
- $wgExtensionFunctions[] = 'wp_bb_mediawiki_run';
 
 
 
 
 
 
 
 
 
 
113
 
114
  ?>
1
  <?php
2
  /*
3
+ http://www.bad-behavior.ioerror.us/
4
 
5
  Bad Behavior - detects and blocks unwanted Web accesses
6
  Copyright (C) 2005 Michael Hampton
21
  */
22
 
23
  // This file is the entry point for Bad Behavior.
 
 
 
 
24
 
25
+ if (!defined('MEDIAWIKI')) die();
 
26
 
27
+ // Settings you can adjust for Bad Behavior.
28
+ $bb2_settings_defaults = array(
29
+ 'log_table' => $wgDBprefix . 'bad_behavior',
30
+ 'display_stats' => true,
31
+ 'strict' => false,
32
+ 'verbose' => false
33
+ );
34
 
35
+ define('BB2_CWD', dirname(__FILE__));
 
 
36
 
37
+ // Bad Behavior callback functions.
 
 
 
 
38
 
39
+ // Return current time in the format preferred by your database.
40
+ function bb2_db_date() {
41
+ return gmdate('Y-m-d H:i:s');
42
+ }
43
 
44
+ // Return affected rows from most recent query.
45
+ function bb2_db_affected_rows($result) {
46
+ return wfAffectedRows($result);
47
+ }
48
 
49
+ // Escape a string for database usage
50
+ function bb2_db_escape($string) {
51
+ // FIXME SECURITY: Get a straight answer from somebody on how MW escapes stuff
52
+ return addslashes($string);
53
+ }
54
 
55
+ // Return the number of rows in a particular query.
56
+ function bb2_db_num_rows($result) {
57
+ return wfNumRows($result);
58
+ }
 
59
 
60
+ // Run a query and return the results, if any.
61
+ // Should return FALSE if an error occurred.
62
+ function bb2_db_query($query) {
63
+ $bb2_last_query = wfQuery($query, DB_WRITE);
64
+ return $bb2_last_query;
65
+ }
66
 
67
+ // Return all rows in a particular query.
68
+ // Should contain an array of all rows generated by calling mysql_fetch_assoc()
69
+ // or equivalent and appending the result of each call to an array.
70
+ function bb2_db_rows($result) {
71
+ $rows = array();
72
+ while ($row = wfFetchRow($result)) {
73
+ $rows[] = $row;
74
+ }
75
+ return $rows;
76
+ }
77
 
78
+ // Return emergency contact email address.
79
+ function bb2_email() {
80
+ global $wgEmergencyContact;
81
+ return $wgEmergencyContact;
82
+ }
83
 
84
+ // This Bad Behavior-related function is a stub. You can help MediaWiki by expanding it.
85
+ // retrieve settings from database
86
+ function bb2_read_settings() {
87
+ global $bb2_settings_defaults;
88
+ return $bb2_settings_defaults;
89
+ }
90
 
91
+ // This Bad Behavior-related function is a stub. You can help MediaWiki by expanding it.
92
+ // write settings to database
93
+ function bb2_write_settings($settings) {
94
+ return;
95
+ }
96
 
97
+ // In some configurations automatic table creation may fail with the message
98
+ // You must update your load-balancing configuration.
99
+ // You can create the table manually (see query in
100
+ // bad-behavior/database.inc.php) and add this line to your LocalSettings.php:
101
+ //
102
+ // define('BB2_NO_CREATE', true);
103
 
104
+ // installation
105
+ function bb2_install() {
106
+ $settings = bb2_read_settings();
107
+ if (defined('BB2_NO_CREATE')) return;
108
+ bb2_db_query(bb2_table_structure($settings['log_table']));
109
+ }
110
 
111
+ // Return the top-level relative path of wherever we are (for cookies)
112
+ function bb2_relative_path() {
113
+ // TODO: This might not be the best way, but it seems to work
114
+ global $wgScript;
115
+ return dirname($wgScript) . "/";
116
  }
117
 
118
+ // Cute timer display
119
+ function bb2_mediawiki_timer(&$parser, &$text) {
120
+ global $bb2_timer_total;
121
+ $text = "<!-- Bad Behavior " . BB2_VERSION . " run time: " . number_format(1000 * $bb2_timer_total, 3) . " ms -->" . $text;
 
 
 
 
122
  }
123
 
124
+ function bb2_mediawiki_entry() {
125
+ global $bb2_timer_total;
126
+
127
+ $bb2_mtime = explode(" ", microtime());
128
+ $bb2_timer_start = $bb2_mtime[1] + $bb2_mtime[0];
129
+
130
+ if (php_sapi_name() != 'cli') {
131
+ require_once(BB2_CWD . "/bad-behavior/core.inc.php");
132
+ bb2_install(); // FIXME: see above
133
+ $settings = bb2_read_settings();
134
+ bb2_start($settings);
135
+ }
136
+
137
+ $bb2_mtime = explode(" ", microtime());
138
+ $bb2_timer_stop = $bb2_mtime[1] + $bb2_mtime[0];
139
+ $bb2_timer_total = $bb2_timer_stop - $bb2_timer_start;
 
140
  }
141
 
142
+ require_once(BB2_CWD . "/bad-behavior/version.inc.php");
143
+ $wgExtensionCredits['other'][] = array(
144
+ 'name' => 'Bad Behavior',
145
+ 'version' => BB2_VERSION,
146
+ 'author' => 'Michael Hampton',
147
+ 'description' => 'Detects and blocks unwanted Web accesses',
148
+ 'url' => 'http://www.bad-behavior.ioerror.us/'
149
+ );
150
+
151
+ $wgHooks['ParserAfterTidy'][] = 'bb2_mediawiki_timer';
152
+ $wgExtensionFunctions[] = 'bb2_mediawiki_entry';
153
 
154
  ?>
bad-behavior-movabletype.php DELETED
@@ -1,23 +0,0 @@
1
- <?php
2
-
3
- // Analyze user agents claiming to be MovableType
4
-
5
- if (!defined('WP_BB_CWD'))
6
- die('');
7
-
8
- // Is it a trackback? If so, do a quick check on the URI
9
- // It must resolve to the same IP as the blog sending it.
10
- // TODO: DNS lookups take too long; skip the check for now :(
11
- if (strcasecmp($wp_bb_request_method, "POST")) {
12
- if (strcmp($wp_bb_http_headers_mixed['Range'], "bytes=0-99999")) {
13
- wp_bb_spammer("Prohibited header 'Range' in POST request");
14
- }
15
- // $uri = parse_url($_POST['url']);
16
- // $host = $uri['host'];
17
- // $ip = gethostbyname($host);
18
- // if ($ip != $host && $ip != $wp_bb_remote_addr) {
19
- // wp_bb_spammer("Trackback did not originate from blog address");
20
- // }
21
- }
22
-
23
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bad-behavior-mozilla.php DELETED
@@ -1,27 +0,0 @@
1
- <?php
2
-
3
- // Analyze user agents claiming to be Mozilla
4
-
5
- // Bots:
6
- // Yahoo! Slurp passes these checks
7
-
8
- if (!defined('WP_BB_CWD'))
9
- die('');
10
-
11
- require_once(WP_BB_CWD . "/bad-behavior-accept.php");
12
-
13
- // First off, workaround for Google Desktop, until they fix it FIXME
14
- // Always check accept header for Mozilla user agents
15
- if (strpos($wp_bb_http_user_agent, "Google Desktop") === FALSE)
16
- wp_bb_check_accept();
17
-
18
- // AvantGo mobile browser needs a different check
19
- if (strpos($wp_bb_http_user_agent, "AvantGo") !== FALSE) {
20
- if (!array_key_exists('X-Avantgo-Screensize', $wp_bb_http_headers_mixed)) {
21
- wp_bb_spammer("User-Agent claimed to be AvantGo, claim appears false");
22
- }
23
- } else {
24
- wp_bb_check_accept_encoding();
25
- }
26
-
27
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bad-behavior-msie.php DELETED
@@ -1,31 +0,0 @@
1
- <?php
2
-
3
- // This file is included only when the user-agent is claiming to be MSIE
4
- // (or some variant thereof). We check the HTTP headers to see if it really
5
- // is MSIE.
6
-
7
- if (!defined('WP_BB_CWD'))
8
- die('');
9
-
10
- require_once(WP_BB_CWD . "/bad-behavior-accept.php");
11
-
12
- // MSIE always sends the Accept: header.
13
- wp_bb_check_accept();
14
-
15
- // MSIE 6.0+ always sends the Accept-Encoding: header.
16
- // BecomeBot does not.
17
- if (strpos($wp_bb_http_user_agent, "MSIE 6") !== FALSE) {
18
- if (stripos($wp_bb_http_user_agent, "BecomeBot") === FALSE ||
19
- matchCIDR($wp_bb_remote_addr, "64.124.85.0/24") === FALSE) {
20
- wp_bb_check_accept_encoding();
21
- }
22
- }
23
-
24
- // MSIE does NOT send "Windows ME" or "Windows XP" in the user agent
25
- if (strpos($wp_bb_http_user_agent, "Windows ME") !== FALSE ||
26
- strpos($wp_bb_http_user_agent, "Windows XP") !== FALSE ||
27
- strpos($wp_bb_http_user_agent, "Windows 2000") !== FALSE) {
28
- wp_bb_spammer("User-Agent claimed to be MSIE, with invalid Windows version");
29
- }
30
-
31
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bad-behavior-msnbot.php DELETED
@@ -1,18 +0,0 @@
1
- <?php
2
-
3
- // This file is included only when the user-agent is claiming to be msnbot
4
-
5
- if (!defined('WP_BB_CWD'))
6
- die('');
7
-
8
- // require_once(WP_BB_CWD . "/bad-behavior-accept.php");
9
-
10
- if (matchCIDR($wp_bb_remote_addr, "207.46.0.0/16") === FALSE &&
11
- matchCIDR($wp_bb_remote_addr, "65.52.0.0/14") === FALSE &&
12
- matchCIDR($wp_bb_remote_addr, "207.68.128.0/18") === FALSE &&
13
- matchCIDR($wp_bb_remote_addr, "207.68.192.0/20") === FALSE &&
14
- matchCIDR($wp_bb_remote_addr, "64.4.0.0/18") === FALSE) {
15
- wp_bb_spammer("User-Agent claimed to be msnbot, claim appears to be false");
16
- }
17
-
18
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bad-behavior-opera.php DELETED
@@ -1,13 +0,0 @@
1
- <?php
2
-
3
- // Analyze user agents claiming to be Opera
4
-
5
- if (!defined('WP_BB_CWD'))
6
- die('');
7
-
8
- require_once(WP_BB_CWD . "/bad-behavior-accept.php");
9
-
10
- wp_bb_check_accept();
11
- wp_bb_check_accept_encoding();
12
-
13
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
bad-behavior-php4.php DELETED
@@ -1,12 +0,0 @@
1
- <?php
2
- // Contains PHP 5 functions reimplemented for PHP 4
3
-
4
- // Helper functions
5
- // stripos() needed because stripos is only present on PHP 5
6
- if (!function_exists('stripos')) {
7
- function stripos($haystack,$needle,$offset = 0) {
8
- return(strpos(strtolower($haystack),strtolower($needle),$offset));
9
- }
10
- }
11
-
12
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
bad-behavior-referer.php DELETED
@@ -1,25 +0,0 @@
1
- <?php
2
-
3
- if (!defined('WP_BB_CWD'))
4
- die('');
5
-
6
- // Analyze the Referer: field
7
-
8
- function wp_bb_referer() {
9
- global $wp_bb_http_headers_mixed;
10
-
11
- // Referer, if it exists, must not be blank
12
- if (empty($wp_bb_http_headers_mixed['Referer'])) {
13
- wp_bb_spammer("Header 'Referer' present but blank");
14
- }
15
-
16
- // Referer, if it exists, must contain a :
17
- // While a relative URL is technically valid in Referer, all known
18
- // legit user-agents send an absolute URL
19
- if (strpos($wp_bb_http_headers_mixed['Referer'], ":") === FALSE) {
20
- wp_bb_spammer("Header 'Referer' is corrupt");
21
- }
22
- return;
23
- }
24
-
25
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bad-behavior-safari.php DELETED
@@ -1,12 +0,0 @@
1
- <?php
2
-
3
- // Analyze user agents claiming to be Safari
4
-
5
- if (!defined('WP_BB_CWD'))
6
- die('');
7
-
8
- require_once(WP_BB_CWD . "/bad-behavior-accept.php");
9
-
10
- wp_bb_check_accept();
11
-
12
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
bad-behavior-user-agent.php DELETED
@@ -1,70 +0,0 @@
1
- <?php
2
-
3
- if (!defined('WP_BB_CWD'))
4
- die('');
5
-
6
- // Is the user-agent a known spambot?
7
- // Occurs at the beginning of the string
8
- $wp_bb_spambots_str0 = array(
9
- "8484 Boston Project", // video poker/porn spam
10
- "autoemailspider", // spam harvester
11
- "Digger", // spam harvester
12
- "ecollector", // spam harvester
13
- "EmailCollector", // spam harvester
14
- "Email Extractor", // spam harvester
15
- "Email Siphon", // spam harvester
16
- "EmailSiphon", // spam harvester
17
- "grub crawler", // misc comment/email spam
18
- // "Java 1.", // Some doubt about this one
19
- "libwww-perl", // spambot scripts
20
- "LWP", // exploited boxes
21
- "Microsoft URL", // spam harvester
22
- "Missigua", // spam harvester
23
- "Mozilla ", // forum exploits
24
- "Shockwave Flash", // spam harvester
25
- "User-Agent: ", // spam harvester
26
- "Wordpress Hash Grabber",// malicious software
27
- "www.weblogs.com", // referrer spam (not the real www.weblogs.com)
28
- );
29
- // Occurs anywhere in the string
30
- $wp_bb_spambots_str = array(
31
- "Bad Behavior Test", // Add this to your user-agent to test BB
32
- "compatible ; MSIE", // misc comment/email spam
33
- "DTS Agent", // misc comment/email spam
34
- "Gecko/25", // revisit this in 500 years
35
- "grub-client", // search engine ignores robots.txt
36
- "Indy Library", // misc comment/email spam
37
- ".NET CLR 1)", // free poker, etc.
38
- "POE-Component-Client", // free poker, etc.
39
- "WISEbot", // spam harvester
40
- "WISEnutbot", // spam harvester
41
- );
42
- // Regex matching
43
- $wp_bb_spambots_reg = array(
44
- "/^[A-Z]{10}$/", // misc email spam
45
- "/^Mozilla...0$/i", // fake user agent/email spam
46
- // "/MSIE.*Windows XP/", // misc comment spam
47
- );
48
-
49
- if (empty($wp_bb_http_user_agent)) {
50
- wp_bb_spammer("A User-Agent is required but none was provided.");
51
- }
52
-
53
- foreach ($wp_bb_spambots_str0 as $wp_bb_spambot) {
54
- $pos = stripos($wp_bb_http_user_agent, $wp_bb_spambot);
55
- if ($pos !== FALSE && $pos == 0) {
56
- wp_bb_spammer("User-Agent beginning with '" . $wp_bb_spambot . "' prohibited"); // does not return
57
- }
58
- }
59
- foreach ($wp_bb_spambots_str as $wp_bb_spambot) {
60
- if (stripos($wp_bb_http_user_agent, $wp_bb_spambot) !== FALSE) {
61
- wp_bb_spammer("User-Agent containing '" . $wp_bb_spambot . "' prohibited"); // does not return
62
- }
63
- }
64
- foreach ($wp_bb_spambots_reg as $wp_bb_spambot) {
65
- if (preg_match($wp_bb_spambot, $wp_bb_http_user_agent)) {
66
- wp_bb_spammer("User-Agent matching regex '" . $wp_bb_spambot . "' prohibited"); // does not return
67
- }
68
- }
69
-
70
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bad-behavior-whitelist.php DELETED
@@ -1,128 +0,0 @@
1
- <?php
2
-
3
- if (!defined('WP_BB_CWD'))
4
- die('');
5
-
6
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
7
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
8
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
9
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
10
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
11
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
12
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
13
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
14
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
15
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
16
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
17
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
18
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
19
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
20
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
21
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
22
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
23
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
24
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
25
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
26
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
27
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
28
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
29
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
30
-
31
- // Inappropriate whitelisting WILL expose you to spam, or cause Bad Behavior
32
- // to stop functioning entirely! DO NOT WHITELIST unless you are 100% CERTAIN
33
- // that you should.
34
-
35
- // IP address ranges use the CIDR format.
36
-
37
- // Includes four examples of whitelisting by IP address and netblock.
38
- // All are commented out.
39
- $wp_bb_whitelist_ip_ranges = array(
40
- // "10.0.0.0/8",
41
- // "172.16.0.0/12",
42
- // "192.168.0.0/16",
43
- // "127.0.0.1",
44
- );
45
-
46
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
47
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
48
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
49
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
50
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
51
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
52
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
53
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
54
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
55
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
56
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
57
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
58
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
59
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
60
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
61
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
62
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
63
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
64
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
65
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
66
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
67
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
68
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
69
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
70
-
71
- // Inappropriate whitelisting WILL expose you to spam, or cause Bad Behavior
72
- // to stop functioning entirely! DO NOT WHITELIST unless you are 100% CERTAIN
73
- // that you should.
74
-
75
- // You should not whitelist search engines by user agent. Use IP netblock
76
- // instead. See http://whois.arin.net/ to locate the netblocks for an IP.
77
-
78
- // User agents are matched by exact match only.
79
-
80
- // Includes one example of whitelisting by user agent.
81
- // All are commented out.
82
- $wp_bb_whitelist_user_agents = array(
83
- // "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) It's me, let me in",
84
- );
85
-
86
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
87
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
88
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
89
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
90
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
91
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
92
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
93
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
94
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
95
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
96
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
97
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
98
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
99
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
100
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
101
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
102
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
103
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
104
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
105
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
106
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
107
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
108
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
109
- // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
110
-
111
- // Do not edit below this line
112
-
113
- function wp_bb_check_whitelist() {
114
- global $wp_bb_whitelist_ip_ranges, $wp_bb_whitelist_user_agents;;
115
- global $wp_bb_remote_addr;
116
-
117
- if (!empty($wp_bb_whitelist_ip_ranges)) {
118
- foreach ($wp_bb_whitelist_ip_ranges as $wp_bb_whitelist_ip_range) {
119
- if (matchCIDR($wp_bb_remote_addr, $wp_bb_whitelist_ip_range)) return true;
120
- }
121
- }
122
- if (!empty($wp_bb_whitelist_user_agents)) {
123
- foreach ($wp_bb_whitelist_user_agents as $wp_bb_whitelist_user_agent) {
124
- if (!strcmp($wp_bb_http_user_agent, $wp_bb_whitelist_user_agent)) return true;
125
- }
126
- }
127
- return false;
128
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bad-behavior-wordpress.php CHANGED
@@ -1,11 +1,11 @@
1
  <?php
2
  /*
3
  Plugin Name: Bad Behavior
4
- Version: 1.2.2
5
- Plugin URI: http://www.ioerror.us/software/bad-behavior/
6
- Description: Stop comment spam before it starts by trapping and blocking spambots before they have a chance to post comments.
7
  Author: Michael Hampton
8
- Author URI: http://www.ioerror.us/
9
  License: GPL
10
 
11
  Bad Behavior - detects and blocks unwanted Web accesses
@@ -16,6 +16,11 @@ it under the terms of the GNU General Public License as published by
16
  the Free Software Foundation; either version 2 of the License, or
17
  (at your option) any later version.
18
 
 
 
 
 
 
19
  This program is distributed in the hope that it will be useful,
20
  but WITHOUT ANY WARRANTY; without even the implied warranty of
21
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@@ -25,58 +30,55 @@ You should have received a copy of the GNU General Public License
25
  along with this program; if not, write to the Free Software
26
  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27
 
28
-
29
- This is beta software so please report any problems to
30
- badbots AT ioerror DOT us
31
  */
32
 
33
  ###############################################################################
34
  ###############################################################################
35
 
36
- // Configuration
37
-
38
- // Log failed requests to the database.
39
- $wp_bb_logging = TRUE;
40
 
41
- // Log all requests to the database, not just failed requests.
42
- $wp_bb_verbose_logging = TRUE;
43
 
44
- // How long to keep the logs around (in days).
45
- // Lowering this may have profound negative effects!
46
- $wp_bb_logging_duration = 7;
47
 
48
- // Email address to contact you in case of problems
49
- // This will be shown to users on the error page, which means it will
50
- // be exposed to spammers! Bad Behavior will munge it automatically; you
51
- // should NOT munge it here!
52
- $wp_bb_email = get_bloginfo('admin_email');
53
- //$wp_bb_email = "badbots@ioerror.us";
54
 
55
- // The database table name to use.
56
- // You can customize the table name if necessary.
57
- define('WP_BB_LOG', $table_prefix . 'bad_behavior_log');
58
-
59
- ###############################################################################
60
 
61
- # DO NOT EDIT BELOW THIS LINE
 
 
62
 
63
- ###############################################################################
 
64
 
65
- $wp_bb_mtime = explode(' ', microtime());
66
- $wp_bb_timer_start = $wp_bb_mtime[1] + $wp_bb_mtime[0];
67
- define('WP_BB_CWD', dirname(__FILE__));
68
 
69
- // WordPress-specific code
 
70
 
71
- function wp_bb_date() {
72
- return get_gmt_from_date(current_time('mysql'));
 
 
 
73
  }
74
 
75
- function wp_bb_db_query($query) {
 
 
 
76
  global $wpdb;
77
 
78
  $wpdb->hide_errors();
79
- $result = $wpdb->query($query);
80
  $wpdb->show_errors();
81
  if (mysql_error()) {
82
  return FALSE;
@@ -84,18 +86,86 @@ function wp_bb_db_query($query) {
84
  return $result;
85
  }
86
 
87
- // Load core functions and do initial checks
88
- require_once(WP_BB_CWD . "/bad-behavior-core.php");
 
 
 
 
 
 
 
 
 
 
89
 
90
- $wp_bb_mtime = explode(' ', microtime());
91
- $wp_bb_timer_stop = $wp_bb_mtime[1] + $wp_bb_mtime[0];
92
- $wp_bb_timer_total = $wp_bb_timer_stop - $wp_bb_timer_start;
93
 
94
- function wp_bb_timer_display() {
95
- global $wp_bb_timer_total;
96
- echo "\n<!-- Bad Behavior " . WP_BB_VERSION . " run time: " . number_format($wp_bb_timer_total, 3) . " seconds -->\n";
 
97
  }
98
 
99
- add_action('wp_head', 'wp_bb_timer_display');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
 
101
  ?>
1
  <?php
2
  /*
3
  Plugin Name: Bad Behavior
4
+ Version: 2.0.11
5
+ Description: Deny automated spambots access to your PHP-based Web site.
6
+ Plugin URI: http://www.bad-behavior.ioerror.us/
7
  Author: Michael Hampton
8
+ Author URI: http://www.homelandstupidity.us/
9
  License: GPL
10
 
11
  Bad Behavior - detects and blocks unwanted Web accesses
16
  the Free Software Foundation; either version 2 of the License, or
17
  (at your option) any later version.
18
 
19
+ As a special exemption, you may link this program with any of the
20
+ programs listed below, regardless of the license terms of those
21
+ programs, and distribute the resulting program, without including the
22
+ source code for such programs: ExpressionEngine
23
+
24
  This program is distributed in the hope that it will be useful,
25
  but WITHOUT ANY WARRANTY; without even the implied warranty of
26
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30
  along with this program; if not, write to the Free Software
31
  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32
 
33
+ Please report any problems to badbots AT ioerror DOT us
 
 
34
  */
35
 
36
  ###############################################################################
37
  ###############################################################################
38
 
39
+ if (!defined('ABSPATH')) die("No cheating!");
 
 
 
40
 
41
+ $bb2_mtime = explode(" ", microtime());
42
+ $bb2_timer_start = $bb2_mtime[1] + $bb2_mtime[0];
43
 
44
+ define('BB2_CWD', dirname(__FILE__));
 
 
45
 
46
+ // Bad Behavior callback functions.
 
 
 
 
 
47
 
48
+ // Return current time in the format preferred by your database.
49
+ function bb2_db_date() {
50
+ return get_gmt_from_date(current_time('mysql'));
51
+ }
 
52
 
53
+ // Return affected rows from most recent query.
54
+ function bb2_db_affected_rows() {
55
+ global $wpdb;
56
 
57
+ return $wpdb->rows_affected;
58
+ }
59
 
60
+ // Escape a string for database usage
61
+ function bb2_db_escape($string) {
62
+ global $wpdb;
63
 
64
+ return $wpdb->escape($string);
65
+ }
66
 
67
+ // Return the number of rows in a particular query.
68
+ function bb2_db_num_rows($result) {
69
+ if ($result !== FALSE)
70
+ return count($result);
71
+ return 0;
72
  }
73
 
74
+ // Run a query and return the results, if any.
75
+ // Should return FALSE if an error occurred.
76
+ // Bad Behavior will use the return value here in other callbacks.
77
+ function bb2_db_query($query) {
78
  global $wpdb;
79
 
80
  $wpdb->hide_errors();
81
+ $result = $wpdb->get_results($query, ARRAY_A);
82
  $wpdb->show_errors();
83
  if (mysql_error()) {
84
  return FALSE;
86
  return $result;
87
  }
88
 
89
+ // Return all rows in a particular query.
90
+ // Should contain an array of all rows generated by calling mysql_fetch_assoc()
91
+ // or equivalent and appending the result of each call to an array.
92
+ // For WP this is pretty much a no-op.
93
+ function bb2_db_rows($result) {
94
+ return $result;
95
+ }
96
+
97
+ // Return emergency contact email address.
98
+ function bb2_email() {
99
+ return get_bloginfo('admin_email');
100
+ }
101
 
102
+ // retrieve settings from database
103
+ function bb2_read_settings() {
104
+ global $wpdb;
105
 
106
+ // Add in default settings when they aren't yet present in WP
107
+ $settings = get_settings('bad_behavior_settings');
108
+ if (!$settings) $settings = array();
109
+ return array_merge(array('log_table' => $wpdb->prefix . 'bad_behavior', 'display_stats' => true, 'strict' => false, 'verbose' => false), $settings);
110
  }
111
 
112
+ // write settings to database
113
+ function bb2_write_settings($settings) {
114
+ update_option('bad_behavior_settings', $settings);
115
+ }
116
+
117
+ // installation
118
+ function bb2_install() {
119
+ $settings = bb2_read_settings();
120
+ bb2_db_query(bb2_table_structure($settings['log_table']));
121
+ }
122
+
123
+ // Cute timer display; screener
124
+ function bb2_insert_head() {
125
+ global $bb2_timer_total;
126
+ global $bb2_javascript;
127
+ echo "\n<!-- Bad Behavior " . BB2_VERSION . " run time: " . number_format(1000 * $bb2_timer_total, 3) . " ms -->\n";
128
+ echo $bb2_javascript;
129
+ }
130
+
131
+ // Display stats?
132
+ function bb2_insert_stats($force = false) {
133
+ $settings = bb2_read_settings();
134
+
135
+ if ($force || $settings['display_stats']) {
136
+ $blocked = bb2_db_query("SELECT COUNT(*) FROM " . $settings['log_table'] . " WHERE `key` NOT LIKE '00000000'");
137
+ if ($blocked !== FALSE) {
138
+ echo sprintf('<p><a href="http://www.bad-behavior.ioerror.us/">%1$s</a> %2$s <strong>%3$s</strong> %4$s</p>', __('Bad Behavior'), __('has blocked'), $blocked[0]["COUNT(*)"], __('access attempts in the last 7 days.'));
139
+ }
140
+ }
141
+ }
142
+
143
+ // Return the top-level relative path of wherever we are (for cookies)
144
+ function bb2_relative_path() {
145
+ $url = parse_url(get_bloginfo('url'));
146
+ return $url['path'] . '/';
147
+ }
148
+
149
+ // FIXME: some sort of hack to run install on 1.5 (and older?) blogs
150
+ // FIXME: figure out what's wrong on 2.0 that this doesn't work
151
+ // register_activation_hook(__FILE__, 'bb2_install');
152
+ //add_action('activate_bb2/bad-behavior-wordpress.php', 'bb2_install');
153
+ add_action('wp_head', 'bb2_insert_head');
154
+ add_action('wp_footer', 'bb2_insert_stats');
155
+
156
+ // Calls inward to Bad Behavor itself.
157
+ require_once(BB2_CWD . "/bad-behavior/version.inc.php");
158
+ require_once(BB2_CWD . "/bad-behavior/core.inc.php");
159
+ bb2_install(); // FIXME: see above
160
+
161
+ if (is_admin() || strstr($_SERVER['PHP_SELF'], 'wp-admin/')) { // 1.5 kludge
162
+ require_once(BB2_CWD . "/bad-behavior/admin.inc.php");
163
+ }
164
+
165
+ bb2_start(bb2_read_settings());
166
+
167
+ $bb2_mtime = explode(" ", microtime());
168
+ $bb2_timer_stop = $bb2_mtime[1] + $bb2_mtime[0];
169
+ $bb2_timer_total = $bb2_timer_stop - $bb2_timer_start;
170
 
171
  ?>
bad-behavior/admin.inc.php ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (!defined('BB2_CORE')) die('I said no cheating!');
2
+
3
+ function bb2_admin_pages() {
4
+ if (function_exists('current_user_can')) {
5
+ // The new 2.x way
6
+ if (current_user_can('manage_options')) {
7
+ $bb2_is_admin = true;
8
+ }
9
+ } else {
10
+ // The old 1.x way
11
+ global $user_ID;
12
+ if (user_can_edit_user($user_ID, 0)) {
13
+ $bb2_is_admin = true;
14
+ }
15
+ }
16
+
17
+ if ($bb2_is_admin) {
18
+ add_options_page(__("Bad Behavior"), __("Bad Behavior"), 8, 'bb2_options', 'bb2_options');
19
+ }
20
+ }
21
+
22
+ function bb2_options()
23
+ {
24
+ $settings = bb2_read_settings();
25
+
26
+ if ($_POST) {
27
+ if ($_POST['display_stats']) {
28
+ $settings['display_stats'] = true;
29
+ } else {
30
+ $settings['display_stats'] = false;
31
+ }
32
+ if ($_POST['strict']) {
33
+ $settings['strict'] = true;
34
+ } else {
35
+ $settings['strict'] = false;
36
+ }
37
+ if ($_POST['verbose']) {
38
+ $settings['verbose'] = true;
39
+ } else {
40
+ $settings['verbose'] = false;
41
+ }
42
+ bb2_write_settings($settings);
43
+ ?>
44
+ <div id="message" class="updated fade"><p><strong><?php _e('Options saved.') ?></strong></p></div>
45
+ <?php
46
+ }
47
+ ?>
48
+ <div class="wrap">
49
+ <h2><?php _e("Bad Behavior"); ?></h2>
50
+ <form method="post" action="<?php echo $_SERVER['REQUEST_URI']; ?>">
51
+ <p>For more information please visit the <a href="http://www.bad-behavior.ioerror.us/">Bad Behavior</a> homepage.</p>
52
+ <p>If you find Bad Behavior valuable, please consider making a <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=error%40ioerror%2eus&item_name=Bad%20Behavior%20<?php echo BB2_VERSION; ?>%20%28From%20Admin%29&no_shipping=1&cn=Comments%20about%20Bad%20Behavior&tax=0&currency_code=USD&bn=PP%2dDonationsBF&charset=UTF%2d8">financial contribution</a> to further development of Bad Behavior.</p>
53
+
54
+ <fieldset class="options">
55
+ <legend><?php _e('Statistics'); ?></legend>
56
+ <?php bb2_insert_stats(true); ?>
57
+ <p><label><input type="checkbox" name="display_stats" value="true" <?php if ($settings['display_stats']) { ?>checked="checked" <?php } ?>/> <?php _e('Display statistics in blog footer'); ?></label></p>
58
+ </fieldset>
59
+
60
+ <fieldset class="options">
61
+ <legend><?php _e('Logging'); ?></legend>
62
+ <p><label><input type="checkbox" name="verbose" value="true" <?php if ($settings['verbose']) { ?>checked="checked" <?php } ?>/> <?php _e('Verbose HTTP request logging'); ?></label></p>
63
+ <legend><?php _e('Strict Mode'); ?></legend>
64
+ <p><label><input type="checkbox" name="strict" value="true" <?php if ($settings['strict']) { ?>checked="checked" <?php } ?>/> <?php _e('Strict checking (blocks more spam but may block some people)'); ?></label></p>
65
+ </fieldset>
66
+
67
+ <p class="submit"><input type="submit" name="submit" value="<?php _e('Update &raquo;'); ?>" /></p>
68
+ </form>
69
+ </div>
70
+ <?php
71
+ }
72
+
73
+ add_action('admin_menu', 'bb2_admin_pages');
74
+
75
+ ?>
bad-behavior/banned.inc.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (!defined('BB2_CORE')) die('I said no cheating!');
2
+
3
+ // Functions called when a request has been denied
4
+ // This part can be gawd-awful slow, doesn't matter :)
5
+
6
+ require_once(BB2_CORE . "/responses.inc.php");
7
+
8
+ function bb2_display_denial($settings, $key, $previous_key = false)
9
+ {
10
+ if (!$previous_key) $previous_key = $key;
11
+ if ($key == "e87553e1") {
12
+ // FIXME: lookup the real key
13
+ }
14
+ // Create support key
15
+ $ip = explode(".", $_SERVER['REMOTE_ADDR']);
16
+ $ip_hex = "";
17
+ foreach ($ip as $octet) {
18
+ $ip_hex .= str_pad(dechex($octet), 2, 0, STR_PAD_LEFT);
19
+ }
20
+ $support_key = implode("-", str_split("$ip_hex$key", 4));
21
+
22
+ // Get response data
23
+ $response = bb2_get_response($previous_key);
24
+ header("HTTP/1.1 " . $response['response'] . " Bad Behavior");
25
+ header("Status: " . $response['response'] . " Bad Behavior");
26
+ ?>
27
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
28
+ <html xmlns="http://www.w3.org/1999/xhtml">
29
+ <head>
30
+ <title>HTTP Error <?php echo $response['response']; ?></title>
31
+ </head>
32
+ <body>
33
+ <h1>Error <?php echo $response['response']; ?></h1>
34
+ <p>We're sorry, but we could not fulfill your request for
35
+ <?php echo htmlspecialchars($_SERVER['REQUEST_URI']) ?> on this server.</p>
36
+ <p><?php echo $response['explanation']; ?></p>
37
+ <p>Your technical support key is: <strong><?php echo $support_key; ?></strong></p>
38
+ <p>You can use this key to <a href="http://www.ioerror.us/bb2-support-key?key=<?php echo $support_key; ?>">fix this problem yourself</a>.</p>
39
+ <p>If you are unable to fix the problem yourself, please contact <a href="mailto:<?php echo htmlspecialchars(str_replace("@", "+nospam@nospam.", bb2_email())); ?>"><?php echo htmlspecialchars(str_replace("@", " at ", bb2_email())); ?></a> and be sure to provide the technical support key shown above.</p>
40
+ <?php
41
+ }
42
+
43
+ function bb2_log_denial($settings, $package, $key, $previous_key=false)
44
+ {
45
+ bb2_db_query(bb2_insert($settings, $package, $key));
46
+ }
47
+
48
+ ?>
bad-behavior/blackhole.inc.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (!defined('BB2_CORE')) die('I said no cheating!');
2
+
3
+ // Look up address on various blackhole lists.
4
+ // These cannot be used for GET requests under any circumstances!
5
+ function bb2_blackhole($package) {
6
+ // Only conservative lists
7
+ $bb2_blackhole_lists = array(
8
+ "sbl-xbl.spamhaus.org", // All around nasties
9
+ // "dnsbl.sorbs.net", // Old useless data.
10
+ // "list.dsbl.org", // Old useless data.
11
+ // "dnsbl.ioerror.us", // Bad Behavior Blackhole
12
+ );
13
+
14
+ // Things that shouldn't be blocked, from aggregate lists
15
+ $bb2_blackhole_exceptions = array(
16
+ "sbl-xbl.spamhaus.org" => array("127.0.0.4"), // CBL is problematic
17
+ "dnsbl.sorbs.net" => array("127.0.0.10",), // Dynamic IPs only
18
+ "list.dsbl.org" => array(),
19
+ "dnsbl.ioerror.us" => array(),
20
+ );
21
+
22
+ // Check the blackhole lists
23
+ $ip = $package['ip'];
24
+ $find = implode('.', array_reverse(explode('.', $ip)));
25
+ foreach ($bb2_blackhole_lists as $dnsbl) {
26
+ $result = gethostbynamel($find . "." . $dnsbl . ".");
27
+ if (!empty($result)) {
28
+ // Got a match and it isn't on the exception list
29
+ $result = @array_diff($result, $bb2_blackhole_exceptions[$dnsbl]);
30
+ if (!empty($result)) {
31
+ return '136673cd';
32
+ }
33
+ }
34
+ }
35
+ return false;
36
+ }
37
+ ?>
bad-behavior/blacklist.inc.php ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (!defined('BB2_CORE')) die('I said no cheating!');
2
+
3
+ function bb2_blacklist($package) {
4
+
5
+ // Blacklisted user agents
6
+ // These user agent strings occur at the beginning of the line.
7
+ $bb2_spambots_0 = array(
8
+ "<sc", // XSS exploit attempts
9
+ "8484 Boston Project", // video poker/porn spam
10
+ "adwords", // referrer spam
11
+ "autoemailspider", // spam harvester
12
+ "blogsearchbot-martin", // from honeypot
13
+ "Digger", // spam harvester
14
+ "ecollector", // spam harvester
15
+ "EmailCollector", // spam harvester
16
+ "Email Extractor", // spam harvester
17
+ "Email Siphon", // spam harvester
18
+ "EmailSiphon", // spam harvester
19
+ "grub crawler", // misc comment/email spam
20
+ "HttpProxy", // misc comment/email spam
21
+ "Internet Explorer", // XMLRPC exploits seen
22
+ "Jakarta Commons", // custommised spambots
23
+ "Java 1.", // definitely a spammer
24
+ "Java/1.", // definitely a spammer
25
+ "libwww-perl", // spambot scripts
26
+ "LWP", // spambot scripts
27
+ "Microsoft URL", // spam harvester
28
+ "Missigua", // spam harvester
29
+ "MJ12bot", // crawls MUCH too fast
30
+ "Movable Type", // customised spambots
31
+ "Mozilla ", // malicious software
32
+ "Mozilla/4.0(", // from honeypot
33
+ "Mozilla/4.0+(", // suspicious harvester
34
+ "MSIE", // malicious software
35
+ "NutchCVS", // unidentified robots
36
+ "Nutscrape/", // misc comment spam
37
+ "OmniExplorer", // spam harvester
38
+ "psycheclone", // spam harvester
39
+ "PussyCat ", // misc comment spam
40
+ "PycURL", // misc comment spam
41
+ "Shockwave Flash", // spam harvester
42
+ "TrackBack/", // trackback spam
43
+ "user", // suspicious harvester
44
+ "User Agent: ", // spam harvester
45
+ "User-Agent: ", // spam harvester
46
+ "Wordpress", // malicious software
47
+ "\"", // malicious software
48
+ );
49
+
50
+ // These user agent strings occur anywhere within the line.
51
+ $bb2_spambots = array(
52
+ "\r", // A really dumb bot
53
+ "; Widows ", // misc comment/email spam
54
+ "a href=", // referrer spam
55
+ "Bad Behavior Test", // Add this to your user-agent to test BB
56
+ "compatible ; MSIE", // misc comment/email spam
57
+ "compatible-", // misc comment/email spam
58
+ "DTS Agent", // misc comment/email spam
59
+ "Gecko/25", // revisit this in 500 years
60
+ "grub-client", // search engine ignores robots.txt
61
+ "hanzoweb", // very badly behaved crawler
62
+ "Indy Library", // misc comment/email spam
63
+ "larbin@unspecified", // stealth harvesters
64
+ "Murzillo compatible", // comment spam bot
65
+ ".NET CLR 1)", // free poker, etc.
66
+ "POE-Component-Client", // free poker, etc.
67
+ "Turing Machine", // www.anonymizer.com abuse
68
+ "WebaltBot", // spam harvester
69
+ "WISEbot", // spam harvester
70
+ "WISEnutbot", // spam harvester
71
+ "Windows NT 4.0;)", // wikispam bot
72
+ "Windows NT 5.0;)", // wikispam bot
73
+ "Windows NT 5.1;)", // wikispam bot
74
+ "Windows XP 5", // spam harvester
75
+ "\\\\)", // spam harvester
76
+ );
77
+
78
+ // These are regular expression matches.
79
+ $bb2_spambots_regex = array(
80
+ "/^[A-Z]{10}$/", // misc email spam
81
+ "/^Mozilla...[05]$/i", // fake user agent/email spam
82
+ "/[bcdfghjklmnpqrstvwxz ]{8,}/",
83
+ // "/(;\){1,2}$/", // misc spammers/harvesters
84
+ // "/MSIE.*Windows XP/", // misc comment spam
85
+ );
86
+
87
+ // Do not edit below this line.
88
+
89
+ $ua = $package['headers_mixed']['User-Agent'];
90
+
91
+ foreach ($bb2_spambots_0 as $spambot) {
92
+ $pos = stripos($ua, $spambot);
93
+ if ($pos !== FALSE && $pos == 0) {
94
+ return "17f4e8c8";
95
+ }
96
+ }
97
+
98
+ foreach ($bb2_spambots as $spambot) {
99
+ if (stripos($ua, $spambot) !== FALSE) {
100
+ return "17f4e8c8";
101
+ }
102
+ }
103
+
104
+ foreach ($bb2_spambots_regex as $spambot) {
105
+ if (preg_match($spambot, $ua)) {
106
+ return "17f4e8c8";
107
+ }
108
+ }
109
+
110
+ return FALSE;
111
+ }
112
+
113
+ ?>
bad-behavior/common_tests.inc.php ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (!defined('BB2_CORE')) die('I said no cheating!');
2
+
3
+ // Enforce adherence to protocol version claimed by user-agent.
4
+
5
+ function bb2_protocol($settings, $package)
6
+ {
7
+ // Is it claiming to be HTTP/1.0? Then it shouldn't do HTTP/1.1 things
8
+ // Always run this test; we should never see Expect:
9
+ if (array_key_exists('Expect', $package['headers_mixed']) && stripos($package['headers_mixed']['Expect'], "100-continue") !== FALSE) {
10
+ return "a0105122";
11
+ }
12
+
13
+ // Is it claiming to be HTTP/1.1? Then it shouldn't do HTTP/1.0 things
14
+ // Blocks some common corporate proxy servers in strict mode
15
+ if ($settings['strict'] && !strcmp($package['server_protocol'], "HTTP/1.1")) {
16
+ if (array_key_exists('Pragma', $package['headers_mixed']) && strpos($package['headers_mixed']['Pragma'], "no-cache") !== FALSE && !array_key_exists('Cache-Control', $package['headers_mixed'])) {
17
+ return "41feed15";
18
+ }
19
+ }
20
+ return false;
21
+ }
22
+
23
+ function bb2_misc_headers($settings, $package)
24
+ {
25
+ $ua = $package['headers_mixed']['User-Agent'];
26
+
27
+ if (!strcmp($package['request_method'], "POST") && empty($ua)) {
28
+ return "f9f2b8b9";
29
+ }
30
+
31
+ // Broken spambots send URLs with various invalid characters
32
+ // Some broken browsers send the #vector in the referer field :(
33
+ // if (strpos($package['request_uri'], "#") !== FALSE || strpos($package['headers_mixed']['Referer'], "#") !== FALSE) {
34
+ if (strpos($package['request_uri'], "#") !== FALSE) {
35
+ return "dfd9b1ad";
36
+ }
37
+
38
+ // Range: field exists and begins with 0
39
+ // Real user-agents do not start ranges at 0
40
+ // NOTE: this blocks the whois.sc bot. No big loss.
41
+ // Exceptions: MT (not fixable); LJ (refuses to fix; may be
42
+ // blocked again in the future)
43
+ if (array_key_exists('Range', $package['headers_mixed']) && strpos($package['headers_mixed']['Range'], "=0-") !== FALSE) {
44
+ if (strncmp($ua, "MovableType", 11) && strncmp($ua, "URI::Fetch", 10)) {
45
+ return "7ad04a8a";
46
+ }
47
+ }
48
+
49
+ // Content-Range is a response header, not a request header
50
+ if (array_key_exists('Content-Range', $package['headers_mixed'])) {
51
+ return '7d12528e';
52
+ }
53
+
54
+ // Lowercase via is used by open proxies/referrer spammers
55
+ // Exceptions: Clearswift uses lowercase via (refuses to fix;
56
+ // may be blocked again in the future)
57
+ if (array_key_exists('via', $package['headers']) &&
58
+ !strstr($package['headers']['via'],'Clearswift Web Policy Engine')) {
59
+ return "9c9e4979";
60
+ }
61
+
62
+ // pinappleproxy is used by referrer spammers
63
+ if (array_key_exists('Via', $package['headers_mixed'])) {
64
+ if (stripos($package['headers_mixed']['Via'], "pinappleproxy") !== FALSE || stripos($package['headers_mixed']['Via'], "PCNETSERVER") !== FALSE || stripos($package['headers_mixed']['Via'], "Invisiware") !== FALSE) {
65
+ return "939a6fbb";
66
+ }
67
+ }
68
+
69
+ // TE: if present must have Connection: TE
70
+ // RFC 2616 14.39
71
+ // Blocks Microsoft ISA Server 2004 in strict mode. Contact Microsoft
72
+ // to obtain a hotfix.
73
+ if ($settings['strict'] && array_key_exists('Te', $package['headers_mixed'])) {
74
+ if (!preg_match('/\bTE\b/', $package['headers_mixed']['Connection'])) {
75
+ return "582ec5e4";
76
+ }
77
+ }
78
+
79
+ if (array_key_exists('Connection', $package['headers_mixed'])) {
80
+ // Connection: keep-alive and close are mutually exclusive
81
+ if (preg_match('/\bKeep-Alive\b/i', $package['headers_mixed']['Connection']) && preg_match('/\bClose\b/i', $package['headers_mixed']['Connection'])) {
82
+ return "a52f0448";
83
+ }
84
+ // Close shouldn't appear twice
85
+ if (preg_match('/\bclose,\s?close\b/i', $package['headers_mixed']['Connection'])) {
86
+ return "a52f0448";
87
+ }
88
+ // Keey-Alive shouldn't appear twice either
89
+ if (preg_match('/\bkeep-alive,\s?keep-alive\b/i', $package['headers_mixed']['Connection'])) {
90
+ return "a52f0448";
91
+ }
92
+ }
93
+
94
+
95
+ // Headers which are not seen from normal user agents; only malicious bots
96
+ if (array_key_exists('X-Aaaaaaaaaaaa', $package['headers_mixed']) || array_key_exists('X-Aaaaaaaaaa', $package['headers_mixed'])) {
97
+ return "b9cc1d86";
98
+ }
99
+ if (array_key_exists('Proxy-Connection', $package['headers_mixed'])) {
100
+ return "b7830251";
101
+ }
102
+
103
+ if (array_key_exists('Referer', $package['headers_mixed'])) {
104
+ // Referer, if it exists, must not be blank
105
+ if (empty($package['headers_mixed'])) {
106
+ return "69920ee5";
107
+ }
108
+
109
+ // Referer, if it exists, must contain a :
110
+ // While a relative URL is technically valid in Referer, all known
111
+ // legit user-agents send an absolute URL
112
+ if (strpos($package['headers_mixed']['Referer'], ":") === FALSE) {
113
+ return "45b35e30";
114
+ }
115
+ }
116
+
117
+ return false;
118
+ }
119
+
120
+ ?>
bad-behavior/core.inc.php ADDED
@@ -0,0 +1,203 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (!defined('BB2_CWD')) die("I said no cheating!");
2
+
3
+ // Bad Behavior entry point is start_bad_behavior().
4
+ // If you're reading this, you are probably lost.
5
+ // Go read the bad-behavior-generic.php file.
6
+
7
+ define('BB2_CORE', dirname(__FILE__));
8
+ define('BB2_COOKIE', 'bb2_screener_');
9
+
10
+ require_once(BB2_CORE . "/functions.inc.php");
11
+
12
+ // Our log table structure
13
+ function bb2_table_structure($name)
14
+ {
15
+ // It's not paranoia if they really are out to get you.
16
+ $name_escaped = bb2_db_escape($name);
17
+ return "CREATE TABLE IF NOT EXISTS `$name_escaped` (
18
+ `id` INT(11) NOT NULL auto_increment,
19
+ `ip` TEXT NOT NULL,
20
+ `date` DATETIME NOT NULL default '0000-00-00 00:00:00',
21
+ `request_method` TEXT NOT NULL,
22
+ `request_uri` TEXT NOT NULL,
23
+ `server_protocol` TEXT NOT NULL,
24
+ `http_headers` TEXT NOT NULL,
25
+ `user_agent` TEXT NOT NULL,
26
+ `request_entity` TEXT NOT NULL,
27
+ `key` TEXT NOT NULL,
28
+ INDEX (`ip`(15)),
29
+ INDEX (`user_agent`(10)),
30
+ PRIMARY KEY (`id`) );"; // TODO: INDEX might need tuning
31
+ }
32
+
33
+ // Insert a new record
34
+ function bb2_insert($settings, $package, $key)
35
+ {
36
+ $ip = bb2_db_escape($package['ip']);
37
+ $date = bb2_db_date();
38
+ $request_method = bb2_db_escape($package['request_method']);
39
+ $request_uri = bb2_db_escape($package['request_uri']);
40
+ $server_protocol = bb2_db_escape($package['server_protocol']);
41
+ $user_agent = bb2_db_escape($package['user_agent']);
42
+ $headers = "$request_method $request_uri $server_protocol\n";
43
+ foreach ($package['headers'] as $h => $v) {
44
+ $headers .= bb2_db_escape("$h: $v\n");
45
+ }
46
+ $request_entity = "";
47
+ if (!strcasecmp($request_method, "POST")) {
48
+ foreach ($package['request_entity'] as $h => $v) {
49
+ $request_entity .= bb2_db_escape("$h: $v\n");
50
+ }
51
+ }
52
+ return "INSERT INTO `" . bb2_db_escape($settings['log_table']) . "`
53
+ (`ip`, `date`, `request_method`, `request_uri`, `server_protocol`, `http_headers`, `user_agent`, `request_entity`, `key`) VALUES
54
+ ('$ip', '$date', '$request_method', '$request_uri', '$server_protocol', '$headers', '$user_agent', '$request_entity', '$key')";
55
+ }
56
+
57
+ // Kill 'em all!
58
+ function bb2_banned($settings, $package, $key, $previous_key=false)
59
+ {
60
+ // Some spambots hit too hard. Slow them down a bit.
61
+ sleep(2);
62
+
63
+ require_once(BB2_CORE . "/banned.inc.php");
64
+ bb2_display_denial($settings, $key, $previous_key);
65
+ bb2_log_denial($settings, $package, $key, $previous_key);
66
+ if (is_callable('bb2_banned_callback')) {
67
+ bb2_banned_callback($settings, $package, $key);
68
+ }
69
+ // Penalize the spammers some more
70
+ require_once(BB2_CORE . "/housekeeping.inc.php");
71
+ bb2_housekeeping($settings, $package);
72
+ die();
73
+ }
74
+
75
+ function bb2_approved($settings, $package)
76
+ {
77
+ // Dirk wanted this
78
+ if (is_callable('bb2_approved_callback')) {
79
+ bb2_approved_callback($settings, $package);
80
+ }
81
+
82
+ // Decide what to log on approved requests.
83
+ if ($settings['verbose'] || empty($package['user_agent'])) {
84
+ bb2_db_query(bb2_insert($settings, $package, "00000000"));
85
+ }
86
+ }
87
+
88
+ // Check the results of a particular test; see below for usage
89
+ // Returns FALSE if test passed (yes this is backwards)
90
+ function bb2_test($settings, $package, $result)
91
+ {
92
+ if ($result !== FALSE)
93
+ {
94
+ bb2_banned($settings, $package, $result);
95
+ return TRUE;
96
+ }
97
+ return FALSE;
98
+ }
99
+
100
+
101
+ // Let God sort 'em out!
102
+ function bb2_start($settings)
103
+ {
104
+ // Gather up all the information we need, first of all.
105
+ $headers = bb2_load_headers();
106
+ // Postprocess the headers to mixed-case
107
+ // FIXME: get the world to stop using PHP as CGI
108
+ $headers_mixed = array();
109
+ foreach ($headers as $h => $v) {
110
+ $headers_mixed[uc_all($h)] = $v;
111
+ }
112
+
113
+ // We use these frequently. Keep a copy close at hand.
114
+ $ip = $_SERVER['REMOTE_ADDR'];
115
+ $request_method = $_SERVER['REQUEST_METHOD'];
116
+ $request_uri = $_SERVER['REQUEST_URI'];
117
+ $server_protocol = $_SERVER['SERVER_PROTOCOL'];
118
+ $user_agent = $_SERVER['HTTP_USER_AGENT'];
119
+
120
+ // Reconstruct the HTTP entity, if present.
121
+ $request_entity = array();
122
+ if (!strcasecmp($request_method, "POST") || !strcasecmp($request_method, "PUT")) {
123
+ foreach ($_POST as $h => $v) {
124
+ $request_entity[$h] = $v;
125
+ }
126
+ }
127
+
128
+ $package = array('ip' => $ip, 'headers' => $headers, 'headers_mixed' => $headers_mixed, 'request_method' => $request_method, 'request_uri' => $request_uri, 'server_protocol' => $server_protocol, 'request_entity' => $request_entity, 'user_agent' => $user_agent, 'is_browser' => false);
129
+
130
+ // Please proceed to the security checkpoint and have your
131
+ // identification and boarding pass ready.
132
+
133
+ // First check the whitelist
134
+ require_once(BB2_CORE . "/whitelist.inc.php");
135
+ if (!bb2_whitelist($package)) {
136
+ // Now check the blacklist
137
+ require_once(BB2_CORE . "/blacklist.inc.php");
138
+ bb2_test($settings, $package, bb2_blacklist($package));
139
+
140
+ // Check for common stuff
141
+ require_once(BB2_CORE . "/common_tests.inc.php");
142
+ bb2_test($settings, $package, bb2_protocol($settings, $package));
143
+ bb2_test($settings, $package, bb2_misc_headers($settings, $package));
144
+
145
+ // Specific checks
146
+ $ua = $headers_mixed['User-Agent'];
147
+ // MSIE checks
148
+ if (stripos($ua, "MSIE") !== FALSE) {
149
+ $package['is_browser'] = true;
150
+ if (stripos($ua, "Opera") !== FALSE) {
151
+ require_once(BB2_CORE . "/opera.inc.php");
152
+ bb2_test($settings, $package, bb2_opera($package));
153
+ } else {
154
+ require_once(BB2_CORE . "/msie.inc.php");
155
+ bb2_test($settings, $package, bb2_msie($package));
156
+ }
157
+ } elseif (stripos($ua, "Konqueror") !== FALSE) {
158
+ $package['is_browser'] = true;
159
+ require_once(BB2_CORE . "/konqueror.inc.php");
160
+ bb2_test($settings, $package, bb2_konqueror($package));
161
+ } elseif (stripos($ua, "Opera") !== FALSE) {
162
+ $package['is_browser'] = true;
163
+ require_once(BB2_CORE . "/opera.inc.php");
164
+ bb2_test($settings, $package, bb2_opera($package));
165
+ } elseif (stripos($ua, "Safari") !== FALSE) {
166
+ $package['is_browser'] = true;
167
+ require_once(BB2_CORE . "/safari.inc.php");
168
+ bb2_test($settings, $package, bb2_safari($package));
169
+ } elseif (stripos($ua, "Lynx") !== FALSE) {
170
+ $package['is_browser'] = true;
171
+ require_once(BB2_CORE . "/lynx.inc.php");
172
+ bb2_test($settings, $package, bb2_lynx($package));
173
+ } elseif (stripos($ua, "MovableType") !== FALSE) {
174
+ require_once(BB2_CORE . "/movabletype.inc.php");
175
+ bb2_test($settings, $package, bb2_movabletype($package));
176
+ } elseif (stripos($ua, "msnbot") !== FALSE || stripos($ua, "MS Search") !== FALSE) {
177
+ require_once(BB2_CORE . "/msnbot.inc.php");
178
+ bb2_test($settings, $package, bb2_msnbot($package));
179
+ } elseif (stripos($ua, "Googlebot") !== FALSE || stripos($ua, "Mediapartners-Google") !== FALSE) {
180
+ require_once(BB2_CORE . "/google.inc.php");
181
+ bb2_test($settings, $package, bb2_google($package));
182
+ } elseif (stripos($ua, "Mozilla") !== FALSE && stripos($ua, "Mozilla") == 0) {
183
+ $package['is_browser'] = true;
184
+ require_once(BB2_CORE . "/mozilla.inc.php");
185
+ bb2_test($settings, $package, bb2_mozilla($package));
186
+ }
187
+
188
+ // More intensive screening applies to POST requests
189
+ if (!strcasecmp('POST', $package['request_method'])) {
190
+ require_once(BB2_CORE . "/post.inc.php");
191
+ bb2_test($settings, $package, bb2_post($settings, $package));
192
+ }
193
+ }
194
+
195
+ // Last chance screening.
196
+ require_once(BB2_CORE . "/screener.inc.php");
197
+ bb2_screener($settings, $package);
198
+
199
+ // And that's about it.
200
+ bb2_approved($settings, $package);
201
+ return true;
202
+ }
203
+ ?>
bad-behavior/functions.inc.php ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (!defined('BB2_CORE')) die("I said no cheating!");
2
+
3
+ // Miscellaneous helper functions.
4
+
5
+ // stripos() needed because stripos is only present on PHP 5
6
+ if (!function_exists('stripos')) {
7
+ function stripos($haystack,$needle,$offset = 0) {
8
+ return(strpos(strtolower($haystack),strtolower($needle),$offset));
9
+ }
10
+ }
11
+
12
+ // str_split() needed because str_split is only present on PHP 5
13
+ if (!function_exists('str_split')) {
14
+ function str_split($string, $split_length=1)
15
+ {
16
+ if ($split_length < 1) {
17
+ return false;
18
+ }
19
+
20
+ for ($pos=0, $chunks = array(); $pos < strlen($string); $pos+=$split_length) {
21
+ $chunks[] = substr($string, $pos, $split_length);
22
+ }
23
+ return $chunks;
24
+ }
25
+ }
26
+
27
+ // Convert a string to mixed-case on word boundaries.
28
+ function uc_all($string) {
29
+ $temp = preg_split('/(\W)/', str_replace("_", "-", $string), -1, PREG_SPLIT_DELIM_CAPTURE);
30
+ foreach ($temp as $key=>$word) {
31
+ $temp[$key] = ucfirst(strtolower($word));
32
+ }
33
+ return join ('', $temp);
34
+ }
35
+
36
+ // Determine if an IP address resides in a CIDR netblock or netblocks.
37
+ function match_cidr($addr, $cidr) {
38
+ $output = false;
39
+
40
+ if (is_array($cidr)) {
41
+ foreach ($cidr as $cidrlet) {
42
+ if (match_cidr($addr, $cidrlet)) {
43
+ $output = true;
44
+ }
45
+ }
46
+ } else {
47
+ list($ip, $mask) = explode('/', $cidr);
48
+ if (!$mask) $mask = 32;
49
+ $mask = pow(2,32) - pow(2, (32 - $mask));
50
+ $output = ((ip2long($addr) & $mask) == (ip2long($ip) & $mask));
51
+ }
52
+ return $output;
53
+ }
54
+
55
+ // Obtain all the HTTP headers.
56
+ // NB: on PHP-CGI we have to fake it out a bit, since we can't get the REAL
57
+ // headers. Run PHP as Apache 2.0 module if possible for best results.
58
+ function bb2_load_headers() {
59
+ if (!is_callable('getallheaders')) {
60
+ $headers = array();
61
+ foreach ($_SERVER as $h => $v)
62
+ if (ereg('HTTP_(.+)', $h, $hp))
63
+ $headers[str_replace("_", "-", uc_all($hp[1]))] = $v;
64
+ } else {
65
+ $headers = getallheaders();
66
+ }
67
+ return $headers;
68
+ }
69
+
70
+ ?>
bad-behavior/google.inc.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (!defined('BB2_CORE')) die('I said no cheating!');
2
+
3
+ // Analyze user agents claiming to be Googlebot
4
+
5
+ function bb2_google($package)
6
+ {
7
+ if (match_cidr($package['ip'], "66.249.64.0/19") === FALSE && match_cidr($package['ip'], "64.233.160.0/19") === FALSE) {
8
+ return "f1182195";
9
+ }
10
+ return false;
11
+ }
12
+
13
+ ?>
bad-behavior/housekeeping.inc.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (!defined('BB2_CORE')) die('I said no cheating!');
2
+
3
+ function bb2_housekeeping($settings, $package)
4
+ {
5
+ // FIXME Yes, the interval's hard coded (again) for now.
6
+ $query = "DELETE FROM `" . $settings['log_table'] . "` WHERE `date` < DATE_SUB('" . bb2_db_date() . "', INTERVAL 7 DAY)";
7
+ bb2_db_query($query);
8
+
9
+ // Waste a bunch more of the spammer's time, sometimes.
10
+ if (rand(1,1000) == 1) {
11
+ $query = "OPTIMIZE TABLE `" . $settings['log_table'] . "`";
12
+ bb2_db_query($query);
13
+ }
14
+ }
15
+
16
+ ?>
bad-behavior/index.html ADDED
File without changes
bad-behavior/konqueror.inc.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (!defined('BB2_CORE')) die('I said no cheating!');
2
+
3
+ // Analyze user agents claiming to be Konqueror
4
+
5
+ function bb2_konqueror($package)
6
+ {
7
+ // CafeKelsa is a dev project at Yahoo which indexes job listings for
8
+ // Yahoo! HotJobs. It identifies as Konqueror so we skip these checks.
9
+ if (stripos($package['headers_mixed']['User-Agent'], "YahooSeeker/CafeKelsa") === FALSE || match_cidr($package['ip'], "209.73.160.0/19") === FALSE) {
10
+ if (!array_key_exists('Accept', $package['headers_mixed'])) {
11
+ return "17566707";
12
+ }
13
+ }
14
+ return false;
15
+ }
16
+
17
+ ?>
bad-behavior/lynx.inc.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (!defined('BB2_CORE')) die('I said no cheating!');
2
+
3
+ // Analyze user agents claiming to be Lynx
4
+
5
+ function bb2_lynx($package)
6
+ {
7
+ if (!array_key_exists('Accept', $package['headers_mixed'])) {
8
+ return "17566707";
9
+ }
10
+ return false;
11
+ }
12
+
13
+ ?>
bad-behavior/movabletype.inc.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (!defined('BB2_CORE')) die('I said no cheating!');
2
+
3
+ function bb2_movabletype($package)
4
+ {
5
+ // Is it a trackback?
6
+ if (strcasecmp($package['request_method'], "POST")) {
7
+ if (strcmp($package['headers_mixed']['Range'], "bytes=0-99999")) {
8
+ return "7d12528e";
9
+ }
10
+ }
11
+ return false;
12
+ }
13
+
14
+ ?>
bad-behavior/mozilla.inc.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (!defined('BB2_CORE')) die('I said no cheating!');
2
+
3
+ // Analyze user agents claiming to be Mozilla
4
+
5
+ function bb2_mozilla($package)
6
+ {
7
+ // First off, workaround for Google Desktop, until they fix it FIXME
8
+ // Google Desktop fixed it, but apparently some old versions are
9
+ // still out there. :(
10
+ // Always check accept header for Mozilla user agents
11
+ if (strpos($package['headers_mixed']['User-Agent'], "Google Desktop") === FALSE) {
12
+ if (!array_key_exists('Accept', $package['headers_mixed'])) {
13
+ return "17566707";
14
+ }
15
+ }
16
+ return false;
17
+ }
18
+
19
+ ?>
bad-behavior/msie.inc.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (!defined('BB2_CORE')) die('I said no cheating!');
2
+
3
+ // Analyze user agents claiming to be MSIE
4
+
5
+ function bb2_msie($package)
6
+ {
7
+ if (!array_key_exists('Accept', $package['headers_mixed'])) {
8
+ return "17566707";
9
+ }
10
+
11
+ // MSIE does NOT send "Windows ME" or "Windows XP" in the user agent
12
+ if (strpos($package['headers_mixed']['User-Agent'], "Windows ME") !== FALSE || strpos($package['headers_mixed']['User-Agent'], "Windows XP") !== FALSE || strpos($package['headers_mixed']['User-Agent'], "Windows 2000") !== FALSE || strpos($package['headers_mixed']['User-Agent'], "Win32") !== FALSE) {
13
+ return "a1084bad";
14
+ }
15
+
16
+ // MSIE does NOT send Connection: TE
17
+ if (preg_match('/\bTE\b/i', $package['headers_mixed']['Connection'])) {
18
+ return "2b90f772";
19
+ }
20
+
21
+ return false;
22
+ }
23
+
24
+ ?>
bad-behavior/msnbot.inc.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (!defined('BB2_CORE')) die('I said no cheating!');
2
+
3
+ // Analyze user agents claiming to be msnbot
4
+
5
+ function bb2_msnbot($package)
6
+ {
7
+ if (match_cidr($package['ip'], "207.46.0.0/16") === FALSE && match_cidr($package['ip'], "65.52.0.0/14") === FALSE && match_cidr($package['ip'], "207.68.128.0/18") === FALSE && match_cidr($package['ip'], "207.68.192.0/20") === FALSE && match_cidr($package['ip'], "64.4.0.0/18") === FALSE) {
8
+ return "e4de0453";
9
+ }
10
+ return false;
11
+ }
12
+
13
+ ?>
bad-behavior/opera.inc.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (!defined('BB2_CORE')) die('I said no cheating!');
2
+
3
+ // Analyze user agents claiming to be Opera
4
+
5
+ function bb2_opera($package)
6
+ {
7
+ if (!array_key_exists('Accept', $package['headers_mixed'])) {
8
+ return "17566707";
9
+ }
10
+ return false;
11
+ }
12
+
13
+ ?>
bad-behavior/post.inc.php ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (!defined('BB2_CORE')) die('I said no cheating!');
2
+
3
+ // All tests which apply specifically to POST requests
4
+ function bb2_post($settings, $package)
5
+ {
6
+ // Check blackhole lists for known spam/malicious activity
7
+ require_once(BB2_CORE . "/blackhole.inc.php");
8
+ bb2_test($settings, $package, bb2_blackhole($package));
9
+
10
+ // MovableType needs specialized screening
11
+ if (stripos($package['headers_mixed']['User-Agent'], "MovableType") !== FALSE) {
12
+ if (strcmp($package['headers_mixed']['Range'], "bytes=0-99999")) {
13
+ return "7d12528e";
14
+ }
15
+ }
16
+
17
+ // Trackbacks need special screening
18
+ $request_entity = $package['request_entity'];
19
+ if (isset($request_entity['title']) && isset($request_entity['url']) && isset($request_entity['blog_name'])) {
20
+ require_once(BB2_CORE . "/trackback.inc.php");
21
+ return bb2_trackback($package);
22
+ }
23
+
24
+ // Catch a few completely broken spambots
25
+ foreach ($request_entity as $key => $value) {
26
+ $pos = strpos($key, " document.write");
27
+ if ($pos !== FAlSE) {
28
+ return "dfd9b1ad";
29
+ }
30
+ }
31
+
32
+ // Screen by cookie/JavaScript form add
33
+ if (isset($_COOKIE[BB2_COOKIE])) {
34
+ $screener1 = explode(" ", $_COOKIE[BB2_COOKIE]);
35
+ }
36
+ if (isset($_POST[BB2_COOKIE])) {
37
+ $screener2 = explode(" ", $_POST[BB2_COOKIE]);
38
+ }
39
+ $screener = max($screener1[0], $screener2[0]);
40
+
41
+ if ($screener > 0) {
42
+ // Posting too fast? 5 sec
43
+ // FIXME: even 5 sec is too intrusive
44
+ // if ($screener + 5 > time())
45
+ // return "408d7e72";
46
+ // Posting too slow? 48 hr
47
+ if ($screener + 172800 < time())
48
+ return "b40c8ddc";
49
+
50
+ // Screen by IP address
51
+ $ip = ip2long($package['ip']);
52
+ $ip_screener = ip2long($screener[1]);
53
+ // FIXME: This is b0rked, but why?
54
+ // if ($ip && $ip_screener && abs($ip_screener - $ip) > 256)
55
+ // return "c1fa729b";
56
+
57
+ if ($package['headers_mixed']['X-Forwarded-For']) {
58
+ $ip = $package['headers_mixed']['X-Forwarded-For'];
59
+ }
60
+ // Screen for user agent changes
61
+ // User connected previously with blank user agent
62
+ // $q = bb2_db_query("SELECT `ip` FROM " . $settings['log_table'] . " WHERE (`ip` = '" . $package['ip'] . "' OR `ip` = '" . $screener[1] . "') AND `user_agent` != '" . $package['user_agent'] . "' AND `date` > DATE_SUB('" . bb2_db_date() . "', INTERVAL 5 MINUTE)");
63
+ // Damnit, too many ways for this to fail :(
64
+ // if ($q !== FALSE && $q != NULL && bb2_db_num_rows($q) > 0)
65
+ // return "799165c2";
66
+ }
67
+
68
+ return false;
69
+ }
70
+
71
+ ?>
bad-behavior/responses.inc.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (!defined('BB2_CORE')) die('I said no cheating!');
2
+
3
+ // Defines the responses which Bad Behavior might return.
4
+
5
+ function bb2_get_response($key) {
6
+ $bb2_responses = array(
7
+ '00000000' => array('response' => 200, 'explanation' => '', 'log' => ''),
8
+ '136673cd' => array('response' => 403, 'explanation' => 'Your Internet Protocol address is listed on a blacklist of addresses involved in malicious or illegal activity. See the listing below for more details on specific blacklists and removal procedures.', 'log' => 'IP address found on external blacklist'),
9
+ '17566707' => array('response' => 403, 'explanation' => 'An invalid request was received from your browser. This may be caused by a malfunctioning proxy server or browser privacy software.', 'log' => 'Required header \'Accept\' missing'),
10
+ '17f4e8c8' => array('response' => 403, 'explanation' => 'You do not have permission to access this server.', 'log' => 'User-Agent was found on blacklist'),
11
+ '21f11d3f' => array('response' => 403, 'explanation' => 'An invalid request was received. You claimed to be a mobile Web device, but you do not actually appear to be a mobile Web device.', 'log' => 'User-Agent claimed to be AvantGo, claim appears false'),
12
+ '2b90f772' => array('response' => 403, 'explanation' => 'You do not have permission to access this server. If you are using the Opera browser, then Opera must appear in your user agent.', 'log' => 'Connection: TE present, not supported by MSIE'),
13
+ '408d7e72' => array('response' => 403, 'explanation' => 'You do not have permission to access this server. Before trying again, run anti-virus and anti-spyware software and remove any viruses and spyware from your computer.', 'log' => 'POST comes too quickly after GET'),
14
+ '41feed15' => array('response' => 400, 'explanation' => 'An invalid request was received. This may be caused by a malfunctioning proxy server. Bypass the proxy server and connect directly, or contact your proxy server administrator.', 'log' => 'Header \'Pragma\' without \'Cache-Control\' prohibited for HTTP/1.1 requests'),
15
+ '45b35e30' => array('response' => 403, 'explanation' => 'An invalid request was received from your browser. This may be caused by a malfunctioning proxy server or browser privacy software.', 'log' => 'Header \'Referer\' is corrupt'),
16
+ '57796684' => array('response' => 403, 'explanation' => 'You do not have permission to access this server. Before trying again, run anti-virus and anti-spyware software and remove any viruses and spyware from your computer.', 'log' => 'Prohibited header \'X-Aaaaaaaaaa\' or \'X-Aaaaaaaaaaaa\' present'),
17
+ '582ec5e4' => array('response' => 400, 'explanation' => 'An invalid request was received. If you are using a proxy server, bypass the proxy server or contact your proxy server administrator. This may also be caused by a bug in the Opera web browser.', 'log' => '"Header \'TE\' present but TE not specified in \'Connection\' header'),
18
+ '69920ee5' => array('response' => 403, 'explanation' => 'An invalid request was received from your browser. This may be caused by a malfunctioning proxy server or browser privacy software.', 'log' => 'Header \'Referer\' present but blank'),
19
+ '799165c2' => array('response' => 403, 'explanation' => 'You do not have permission to access this server.', 'log' => 'Rotating user-agents detected'),
20
+ '7a06532b' => array('response' => 400, 'explanation' => 'An invalid request was received from your browser. This may be caused by a malfunctioning proxy server or browser privacy software.', 'log' => 'Required header \'Accept-Encoding\' missing'),
21
+ '7ad04a8a' => array('response' => 400, 'explanation' => 'The automated program you are using is not permitted to access this server. Please use a different program or a standard Web browser.', 'log' => 'Prohibited header \'Range\' present'),
22
+ '7d12528e' => array('response' => 403, 'explanation' => 'You do not have permission to access this server.', 'log' => 'Prohibited header \'Range\' or \'Content-Range\' in POST request'),
23
+ '939a6fbb' => array('response' => 403, 'explanation' => 'The proxy server you are using is not permitted to access this server. Please bypass the proxy server, or contact your proxy server administrator.', 'log' => 'Banned proxy server in use'),
24
+ '9c9e4979' => array('response' => 403, 'explanation' => 'The proxy server you are using is not permitted to access this server. Please bypass the proxy server, or contact your proxy server administrator.', 'log' => 'Prohibited header \'via\' present'),
25
+ 'a0105122' => array('response' => 417, 'explanation' => 'Expectation failed. Please retry your request.', 'log' => 'Header \'Expect\' prohibited; resend without Expect'),
26
+ 'a1084bad' => array('response' => 403, 'explanation' => 'You do not have permission to access this server.', 'log' => 'User-Agent claimed to be MSIE, with invalid Windows version'),
27
+ 'a52f0448' => array('response' => 400, 'explanation' => 'An invalid request was received. This may be caused by a malfunctioning proxy server or browser privacy software. If you are using a proxy server, bypass the proxy server or contact your proxy server administrator.', 'log' => 'Header \'Connection\' contains invalid values'),
28
+ 'b40c8ddc' => array('response' => 403, 'explanation' => 'You do not have permission to access this server. Before trying again, close your browser, run anti-virus and anti-spyware software and remove any viruses and spyware from your computer.', 'log' => 'POST more than two days after GET'),
29
+ 'b7830251' => array('response' => 400, 'explanation' => 'Your proxy server sent an invalid request. Please contact the proxy server administrator to have this problem fixed.', 'log' => 'Prohibited header \'Proxy-Connection\' present'),
30
+ 'b9cc1d86' => array('response' => 403, 'explanation' => 'The proxy server you are using is not permitted to access this server. Please bypass the proxy server, or contact your proxy server administrator.', 'log' => 'Prohibited header \'X-Aaaaaaaaaa\' or \'X-Aaaaaaaaaaaa\' present'),
31
+ 'c1fa729b' => array('response' => 403, 'explanation' => 'You do not have permission to access this server. Before trying again, run anti-virus and anti-spyware software and remove any viruses and spyware from your computer.', 'log' => 'Use of rotating proxy servers detected'),
32
+ 'd60b87c7' => array('response' => 403, 'explanation' => 'You do not have permission to access this server. Before trying again, please remove any viruses or spyware from your computer.', 'log' => 'Trackback received via proxy server'),
33
+ 'dfd9b1ad' => array('response' => 403, 'explanation' => 'You do not have permission to access this server.', 'log' => 'Request contained a malicious JavaScript or SQL injection attack'),
34
+ 'e4de0453' => array('response' => 403, 'explanation' => 'An invalid request was received. You claimed to be a major search engine, but you do not appear to actually be a major search engine.', 'log' => 'User-Agent claimed to be msnbot, claim appears to be false'),
35
+ 'e87553e1' => array('response' => 403, 'explanation' => 'You do not have permission to access this server.', 'log' => 'I know you and I don\'t like you, dirty spammer.'),
36
+ 'f0dcb3fd' => array('response' => 403, 'explanation' => 'You do not have permission to access this server. Before trying again, run anti-virus and anti-spyware software and remove any viruses and spyware from your computer.', 'log' => 'Web browser attempted to send a trackback'),
37
+ 'f1182195' => array('response' => 403, 'explanation' => 'An invalid request was received. You claimed to be a major search engine, but you do not appear to actually be a major search engine.', 'log' => 'User-Agent claimed to be Googlebot, claim appears to be false.'),
38
+ 'f9f2b8b9' => array('response' => 403, 'explanation' => 'You do not have permission to access this server. This may be caused by a malfunctioning proxy server or browser privacy software.', 'log' => 'A User-Agent is required but none was provided.'),
39
+ );
40
+
41
+ if (array_key_exists($key, $bb2_responses)) return $bb2_responses[$key];
42
+ return array('00000000');
43
+ }
44
+ ?>
bad-behavior/safari.inc.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (!defined('BB2_CORE')) die('I said no cheating!');
2
+
3
+ // Analyze user agents claiming to be Safari
4
+
5
+ function bb2_safari($package)
6
+ {
7
+ if (!array_key_exists('Accept', $package['headers_mixed'])) {
8
+ return "17566707";
9
+ }
10
+ return false;
11
+ }
12
+
13
+ ?>
bad-behavior/screener.inc.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (!defined('BB2_CWD')) die("I said no cheating!");
2
+
3
+ // Bad Behavior browser screener
4
+
5
+ function bb2_screener_cookie($settings, $package, $cookie_name, $cookie_value)
6
+ {
7
+ // FIXME: Set the real cookie
8
+ setcookie($cookie_name, $cookie_value, 0, bb2_relative_path());
9
+ }
10
+
11
+ function bb2_screener_javascript($settings, $package, $cookie_name, $cookie_value)
12
+ {
13
+ global $bb2_javascript;
14
+
15
+ // FIXME: do something
16
+ $bb2_javascript = "<script type=\"text/javascript\">
17
+ <!--
18
+ function bb2_addLoadEvent(func) {
19
+ var oldonload = window.onload;
20
+ if (typeof window.onload != 'function') {
21
+ window.onload = func;
22
+ } else {
23
+ window.onload = function() {
24
+ oldonload();
25
+ func();
26
+ }
27
+ }
28
+ }
29
+
30
+ bb2_addLoadEvent(function() {
31
+ for ( i=0; i < document.forms.length; i++ ) {
32
+ if (document.forms[i].method == 'post') {
33
+ var myElement = document.createElement('input');
34
+ myElement.setAttribute('type', 'hidden');
35
+ myElement.name = '$cookie_name';
36
+ myElement.value = '$cookie_value';
37
+ document.forms[i].appendChild(myElement);
38
+ }
39
+ }
40
+ });
41
+ // --></script>
42
+ ";
43
+ }
44
+
45
+ function bb2_screener($settings, $package)
46
+ {
47
+ $cookie_name = BB2_COOKIE;
48
+
49
+ // Set up a simple cookie
50
+ $screener = array(time(), $package['ip']);
51
+ if (isset($package['headers_mixed']['X-Forwarded-For'])) {
52
+ array_push($screener, $package['headers_mixed']['X-Forwarded-For']);
53
+ }
54
+ if (isset($package['headers_mixed']['Client-Ip'])) {
55
+ array_push($screener, $package['headers_mixed']['Client-Ip']);
56
+ }
57
+
58
+ $cookie_value = implode(" ", $screener);
59
+
60
+ bb2_screener_cookie($settings, $package, BB2_COOKIE, $cookie_value);
61
+ bb2_screener_javascript($settings, $package, BB2_COOKIE, $cookie_value);
62
+ }
63
+ ?>
bad-behavior/trackback.inc.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (!defined('BB2_CORE')) die('I said no cheating!');
2
+
3
+ // Specialized screening for trackbacks
4
+ function bb2_trackback($package)
5
+ {
6
+ // Web browsers don't send trackbacks
7
+ if ($package['is_browser']) {
8
+ return 'f0dcb3fd';
9
+ }
10
+
11
+ // Proxy servers don't send trackbacks either
12
+ if (array_key_exists('Via', $package['headers_mixed']) || array_key_exists('Max-Forwards', $package['headers_mixed']) || array_key_exists('X-Forwarded-For', $package['headers_mixed']) || array_key_exists('Client-Ip', $package['headers_mixed'])) {
13
+ return 'd60b87c7';
14
+ }
15
+ return false;
16
+ }
17
+
18
+ ?>
bad-behavior/version.inc.php ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ <?php if (!defined('BB2_CWD')) die("I said no cheating!");
2
+ define('BB2_VERSION', "2.0.11");
3
+ ?>
bad-behavior/whitelist.inc.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (!defined('BB2_CORE')) die('I said no cheating!');
2
+
3
+ function bb2_whitelist($package)
4
+ {
5
+ // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
6
+
7
+ // Inappropriate whitelisting WILL expose you to spam, or cause Bad
8
+ // Behavior to stop functioning entirely! DO NOT WHITELIST unless you
9
+ // are 100% CERTAIN that you should.
10
+
11
+ // IP address ranges use the CIDR format.
12
+
13
+ // Includes four examples of whitelisting by IP address and netblock.
14
+ $bb2_whitelist_ip_ranges = array(
15
+ "10.0.0.0/8",
16
+ "172.16.0.0/12",
17
+ "192.168.0.0/16",
18
+ // "127.0.0.1",
19
+ );
20
+
21
+ // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
22
+
23
+ // Inappropriate whitelisting WILL expose you to spam, or cause Bad
24
+ // Behavior to stop functioning entirely! DO NOT WHITELIST unless you
25
+ // are 100% CERTAIN that you should.
26
+
27
+ // You should not whitelist search engines by user agent. Use the IP
28
+ // netblock for the search engine instead. See http://whois.arin.net/
29
+ // to locate the netblocks for an IP.
30
+
31
+ // User agents are matched by exact match only.
32
+
33
+ // Includes one example of whitelisting by user agent.
34
+ // All are commented out.
35
+ $bb2_whitelist_user_agents = array(
36
+ // "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) It's me, let me in",
37
+ );
38
+
39
+ // DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
40
+
41
+ // Do not edit below this line
42
+
43
+ if (!empty($bb2_whitelist_ip_ranges)) {
44
+ foreach ($bb2_whitelist_ip_ranges as $range) {
45
+ if (match_cidr($package['ip'], $range)) return true;
46
+ }
47
+ }
48
+ if (!empty($bb2_whitelist_user_agents)) {
49
+ foreach ($bb2_whitelist_user_agents as $user_agent) {
50
+ if (!strcmp($package['headers_mixed']['User-Agent'], $user_agent)) return true;
51
+ }
52
+ }
53
+ return false;
54
+ }
55
+
56
+ ?>
index.html ADDED
File without changes