Michael,
if you remove <if_sid>, will it match anything? I am trying now to play with it a bit and it doesn't match. I created vulnerable cgi script. All 40x attempts are matched by 31101.
**Phase 1: Completed pre-decoding.
full event: '111.111.111.111 - - [07/Oct/2014:12:53:51 +0000] "GET /cgi-bin/test.cgi HTTP/1.1" 404 1666 "-" "() { test;};echo \\\"Content-type: text/plain\\\"; echo; echo; /bin/cat /etc/passwd"'
hostname: 'Ossec1'
program_name: '(null)'
log: '111.111.111.111 - - [07/Oct/2014:12:53:51 +0000] "GET /cgi-bin/test.cgi HTTP/1.1" 404 1666 "-" "() { test;};echo \\\"Content-type: text/plain\\\"; echo; echo; /bin/cat /etc/passwd"'
**Phase 2: Completed decoding.
decoder: 'web-accesslog'
srcip: '111.111.111.111'
url: '/cgi-bin/test.cgi'
id: '404'
**Rule debugging:
Trying rule: 4 - Generic template for all web rules.
*Rule 4 matched.
*Trying child rules.
Trying rule: 31100 - Access log messages grouped.
*Rule 31100 matched.
*Trying child rules.
Trying rule: 31108 - Ignored URLs (simple queries).
Trying rule: 31115 - URL too long. Higher than allowed on most browsers. Possible attack.
Trying rule: 31103 - SQL injection attempt.
Trying rule: 31104 - Common web attack.
Trying rule: 31105 - XSS (Cross Site Scripting) attempt.
Trying rule: 31110 - PHP CGI-bin vulnerability attempt.
Trying rule: 31109 - MSSQL Injection attempt (/ur.php, urchin.js)
Trying rule: 31164 - SQL injection attempt.
Trying rule: 31165 - SQL injection attempt.
Trying rule: 31501 - WordPress Comment Spam (coming from a fake search engine UA).
Trying rule: 31502 - TimThumb vulnerability exploit attempt.
Trying rule: 31503 - osCommerce login.php bypass attempt.
Trying rule: 31504 - osCommerce file manager login.php bypass attempt.
Trying rule: 31505 - TimThumb backdoor access attempt.
Trying rule: 31506 - Cart.php directory transversal attempt.
Trying rule: 31507 - MSSQL Injection attempt (ur.php, urchin.js).
Trying rule: 31508 - Blacklisted user agent (known malicious user agent).
Trying rule: 31511 - Blacklisted user agent (wget).
Trying rule: 31512 - Uploadify vulnerability exploit attempt.
Trying rule: 31513 - BBS delete.php exploit attempt.
Trying rule: 31514 - Simple shell.php command execution.
Trying rule: 31515 - PHPMyAdmin scans (looking for setup.php).
Trying rule: 31516 - Suspicious URL access.
Trying rule: 31550 - Anomaly URL query (attempting to pass null termination).
Trying rule: 31101 - Web server 400 error code.
*Rule 31101 matched.
*Trying child rules.
Trying rule: 31102 - Ignored extensions on 400 error codes.
Trying rule: 31140 - Ignoring google/msn/yahoo bots.
Trying rule: 31141 - Ignored 499's on nginx.
Trying rule: 31151 - Multiple web server 400 error codes from same source ip.
**Phase 3: Completed filtering (rules).
Rule id: '31101'
Level: '5'
Description: 'Web server 400 error code.'
**Alert to be generated.
There is even bigger issue. When status code is 200, rule 31108 matches and attack is ignored
**Phase 1: Completed pre-decoding.
full event: '111.111.111.111 - - [07/Oct/2014:12:53:51 +0000] "GET /cgi-bin/test.cgi HTTP/1.1" 200 1666 "-" "() { test;};echo \\\"Content-type: text/plain\\\"; echo; echo; /bin/cat /etc/passwd"'
log: '111.111.111.111 - - [07/Oct/2014:12:53:51 +0000] "GET /cgi-bin/test.cgi HTTP/1.1" 200 1666 "-" "() { test;};echo \\\"Content-type: text/plain\\\"; echo; echo; /bin/cat /etc/passwd"'
**Phase 2: Completed decoding.
Trying rule: 4 - Generic template for all web rules.
*Rule 4 matched.
*Trying child rules.
Trying rule: 31100 - Access log messages grouped.
*Rule 31100 matched.
*Trying child rules.
Trying rule: 31108 - Ignored URLs (simple queries).
*Rule 31108 matched.
*Trying child rules.
Trying rule: 31509 - CMS (WordPress or Joomla) login attempt.
**Phase 3: Completed filtering (rules).