fail2ban WordPress XMLRPC spammers

Poor SEO scripts kept spamming my wordpress install (via xmlrpc.php) and pegging my CPU. I got annoyed, so now they get banned.

The configuration in jail.conf:


enabled = true
port = http,https
filter = apache-xmlrpc
action = iptables[name=http, port=http, protocol=tcp]
logpath = /var/log/httpd/access_log
maxretry = 5

And the filter in filter.d/apache-xmlrpc.conf:

# Fail2Ban for xmlrpc.php spam
failregex = ^<HOST> - .*"POST /xmlrpc.php.*HTTP.*$
ignoreregex =

Posted in uncategorized | Leave a comment

Java URL Pattern Matching Gotchas

Many security features in Java rely on endpoint pattern matching which allow for URL pattern matching bypasses if not careful. Additionally Spring MVC and Spring Security together introduces are a few gotcha’s during implementation.

Security Constraint Matching

The most basic form of authentication within Java is using the <security-constraint/> tag. The following is an example constraint restricting access to /basic endpoint using Basic auth.

<!-- Basic Security -->
        <web-resource-name>baisc auth restriction</web-resource-name>

All official Java documentation uses the url-pattern /*, though details for <url-pattern/> can be found in section 12.2 of the 3.0 servlet specification. The following details mapping test-cases which have standard Java servlets mapped to /basic

Servlet Map <url-pattern/> Request Response Code
/basic /basic* GET /basic 200
/basic /basic/ GET /basic 200
/basic /basic/* GET /basic 401
/basic /basic GET /basic 401

Wild cards do not function as expected, and only by leaving out extensions for a literal matching or using /* can servlet patterns be correctly matched.

Security Constraints with Spring MVC

However if, for example, using the <security-restraint/> function to protect Spring MVC controllers the following is observed:

MVC Map <url-pattern/> Request Response Code
/mvcpoint /mvcpoint* GET /mvcpoint 200
/mvcpoint /mvcpoint/ GET /mvcpoint 200
/mvcpoint /mvcpoint/* GET /mvcpoint. 200
/mvcpoint /mvcpoint GET /mvcpoint/ 200
/mvcpoint /mvcpoint*/* GET /mvcpoint 200

The lesson here is never use standard <security-constraint/> methods when attempting to restrict endpoints which are not servlets. We will touch on the use of the . below.

Spring Security Pattern Matching

Security interceptors used by Spring Security use ANT pattern matching. This type of matching is different from Regex. See the ANT documentation on patterns for specifics.

The following is an example of a Spring Security URL pattern constraint:

    <intercept-url pattern="/welcome*" access="ROLE_USER" />
    <http-basic />

The following is a test table showing various patterns, and their bypass:

MVC Map <intercept-url/> Request Response Code
/mvcpoint /mvcpoint* GET /mvcpoint/ 200
/mvcpoint /mvcpoint/ GET /mvcpoint 200
/mvcpoint /mvcpoint/* GET /mvcpoint 200
/mvcpoint /mvcpoint** GET /mvcpoint/ 200
/mvcpoint /mvcpoint/** GET /mvcpoint. 200
/mvcpoint /mvcpoint GET /mvcpoint. 200
/mvcpoint /mvcpoint*/* GET /mvcpoint 200
/mvcpoint /mvcpoint**/* GET /mvcpoint 200
/mvcpoint /mvcpoint*/** GET /mvcpoint. 401

The table shows that only a single spring-security pattern (*/**) is able to secure against unauthorized access. To discover why, we must dig deeper.

Spring MVC with Spring Security

The problem arises in spring-mvc and its handling of extensions. We are able to supply an incomplete extension (note the trailing . on the requests) to spring-security which results in the bypass of the rule. When the incomplete extension gets to spring-mvc however, the incomplete extension is treated as erroneous and automatically returns the original mapping.

private String getMatchingPattern(String pattern, String lookupPath) {
    if (pattern.equals(lookupPath)) {
        return pattern;
    if (this.useSuffixPatternMatch) {
        if (useSmartSuffixPatternMatch(pattern, lookupPath)) {
            for (String extension : this.fileExtensions) {
                if (this.pathMatcher.match(pattern + extension, lookupPath)) {
                    return pattern + extension;
        else {
            boolean hasSuffix = pattern.indexOf('.') != -1;
            if (!hasSuffix && this.pathMatcher.match(pattern + ".*", lookupPath)) {
                return pattern + ".*";
    if (this.pathMatcher.match(pattern, lookupPath)) {
        return pattern;
    boolean endsWithSlash = pattern.endsWith("/");
    if (this.useTrailingSlashMatch) {
        if (!endsWithSlash && this.pathMatcher.match(pattern + "/", lookupPath)) {
            return pattern +"/";
    return null;

private boolean useSmartSuffixPatternMatch(String pattern, String lookupPath) {
    return (!this.fileExtensions.isEmpty() && lookupPath.indexOf('.') != -1) ;
} starting at line 223

The code, upon being passed to spring mvc as such

getMatchingPattern("/basic2", "/basic2.")

Will end up in the following block because of useSmartSuffixPatternMatch evaluating to false.

boolean hasSuffix = pattern.indexOf('.') != -1;
if (!hasSuffix && this.pathMatcher.match(pattern + ".*", lookupPath)) {
    return pattern + ".*";

This results in the return of “/basic2.*” due to the pathMatcher automatically appending .* to the pattern. In the end this function will find the correct controller mapping in spite of the added period.


  • Only protect servlets with the <security-constraint/> element
  • Always use /* when defining <security-constraint/>  patterns
  • Always use */** when defining <intercept-url/> patterns
Posted in java, webapp | Leave a comment

Compiling iOS Libraries using Theos

If you want to compile a shared library for iOS, particularly for Mobile Substrate, here are some easy enough steps to do it all via CLI.


You need Theos installed, normally into /opt/theos. Follow the getting started guide

Then create a new Theo project. The following is named SampleCrack

user@myhost> $THEOS/bin/
NIC 2.0 - New Instance Creator
[1.] iphone/application
[2.] iphone/library
[3.] iphone/preference_bundle
[4.] iphone/tool
[5.] iphone/tweak
Choose a Template (required): 2
Project Name (required): SampleCrack
Package Name [com.yourcompany.samplecrack]:
Author/Maintainer Name [c0ffee]: 
Instantiating iphone/library in samplecrack/...

Then look about

user@myhost> cd samplecrack
user@myhost> ls
Makefile control        theos

We are going to be using captain hook. Check it out

user@myhost> git clone git://


Then let’s write the code, make sure you mod it to your liking, sadly there are no docs for CaptainHook.

user@myhost> cat > SampleCrack.h
#import <Foundation/Foundation.h>

@interface SampleCrack : NSObject
user@myhost> cat >
#import "SampleCrack.h"
#import "Foundation/Foundation.h"
#import "CaptainHook/CaptainHook.h"
#include "notify.h"

@implementation SampleCrack
    if ((self = [super init])){} return self;

@class SampleAppViewController;
CHOptimizedMethod(0, self, _Bool, SampleAppViewController, isDeviceRooted)
    NSLog(@"####### isJailBroken hooked"); // Logging saves lives
    return true;

CHConstructor {
    @autoreleasepool {
        CHHook(0, SampleAppViewController, isDeviceRooted); // register hook


Then we compile:

user@myhost> make

If you get an error that looks anything like the following:

./working/samplecrack/theos/include/IOSurface/IOSurface.h:20:10: fatal error: 'IOSurface/IOSurfaceAPI.h' file not found
#include <IOSurface/IOSurfaceAPI.h>

Then try including the IOSurfaceAPI.h in, I had to do this on lion.

> cp /System/Library/Frameworks/IOSurface.framework/Headers/IOSurfaceAPI.h ./theos/include/IOSurface/

You will probably need to comment out the following lines also:

    /* This call lets you get an xpcobject_t that holds a reference to the IOSurface.
    Note: Any live XPC objects created from an IOSurfaceRef implicity increase the IOSurface's global use
    count by one until the object is destroyed. */
    // xpc_object_t IOSurfaceCreateXPCObject(IOSurfaceRef aSurface)

    /* This call lets you take an xpcobject_t created via IOSurfaceCreatePort() and recreate an IOSurfaceRef from it. */
    // IOSurfaceRef IOSurfaceLookupFromXPCObject(xpc_object_t xobj)

See this stack overflow post if you want more detail.

You are also going to need a copy of ldid. If you have ports, try there. Brew doesn’t seem to hold a copy (They gave up on it because it fails with clang? Use llvm g++). If those fail check try making it yourself:

git clone git://
cd ldid
git submodule update --init
cp -f ./ldid $THEOS/bin/ldid

Make sure you drop it into $THEOS/bin/ldid

scp ./obj/SampleCrack.dylib root@iphone:/Library/MobileSubstrate/
ssh root@iphone
root@iphone's password: 
iphone:~ root# 
ldid -S SampleCrack.ldid

Now you’ve got the dependencies, make it

user@myhost> export SDKVERSION=7.0
user@myhost> make

And you’ve got yourself a nice library

> file obj/SampleCrack.dylib                                       ~/Documents/Customer/Documents/Elavon/working/samplecrack
obj/SampleCrack.dylib: Mach-O universal binary with 2 architectures: [arm_v7: Mach-O arm_v7 dynamically linked shared library] [arm subarchitecture=11: Mach-O arm subarchitecture=11 dynamically linked shared library]


Posted in iOS, mobile | 3 Comments