AbstractInjectionMonobit.java

package com.jsql.model.injection.strategy.blind;

import com.jsql.model.InjectionModel;

import java.util.List;
import java.util.concurrent.CompletionService;
import java.util.concurrent.atomic.AtomicInteger;

public abstract class AbstractInjectionMonobit<T extends AbstractCallableBoolean<T>> extends AbstractInjectionBoolean<T> {

    protected AbstractInjectionMonobit(InjectionModel injectionModel, BooleanMode booleanMode) {
        super(injectionModel, booleanMode);
    }
    
    abstract T getCallableBitTest(String sqlQuery, int indexCharacter, int bit);

    public void initializeNextCharacters(
        String sqlQuery,
        List<char[]> bytes,
        AtomicInteger indexCharacter,
        CompletionService<T> taskCompletionService,
        AtomicInteger countTasksSubmitted
    ) {
        indexCharacter.incrementAndGet();
        
        // New undefined bits of the next character
        // Chars all have the last bit set to 0 in Ascii table
        bytes.add(new char[]{ '0', 'x', 'x', 'x', 'x', 'x', 'x', 'x' });
        
        // Test the 8 bits for the next character, save its position and current bit for later
        // Ignore last bit 128 and only check for first seven bits
        for (int bit: new int[]{ 1, 2, 4, 8, 16, 32, 64 }) {
            
            taskCompletionService.submit(
                this.getCallableBitTest(
                    sqlQuery,
                    indexCharacter.get(),
                    bit
                )
            );
            countTasksSubmitted.addAndGet(1);
        }
    }

    public char[] initializeBinaryMask(List<char[]> bytes, T currentCallable) {

        // Bits for current url
        char[] asciiCodeMask = bytes.get(currentCallable.getCurrentIndex() - 1);

        int positionInMask = (int) (
            8 - (Math.log(2) + Math.log(currentCallable.getCurrentBit()))
            / Math.log(2)
        );

        // Set current bit
        asciiCodeMask[positionInMask] = currentCallable.isTrue() ? '1' : '0';

        return asciiCodeMask;
    }
}