http分块传输小工具

前一阵子看到一篇文章说利用分块传输可以过waf,但是又没找到现成的工具,就只能自己写一个,考虑到抵御此类攻击太容易并且国外有防火墙早在14年就可以识别,所以没必要写的太复杂,加太多功能。

说明:将HTTP数据包变成分块传输包,可分成指定块,仅支持ascii编码和普通数据包。

主程序

import tools.Queue;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import javax.print.DocFlavor.READER;

/**
 * @author Elliot 
 *
 */
public class TransferEncoding {
	// 测试用硬编码
	private static String FileName = "E:\\sqlmap-dev\\post.txt"; // 要读取的文件名
	private static String pathname = "H:\\output.txt"; // 写入的文件名
	private static int mod = 13;

	/**
	 * @param FileName
	 * @param pathname
	 */
	private TransferEncoding(String FileName, String pathname) {

		this.FileName = FileName;
		this.pathname = pathname;

	}

	public static String getFileName() {
		return FileName;
	}

	public static void setFileName(String fileName) {
		FileName = fileName;
	}

	public static String getPathname() {
		return pathname;
	}

	public static void setPathname(String pathname) {
		TransferEncoding.pathname = pathname;
	}

	private static String EncodeString = "";

	// 按行读取文件并打印
	private static void readUsingBufferedReader(String fileName, String pathname, Charset cs) throws IOException {
		/** 准备BufferReader */
		File file = new File(fileName); // 准备读取的post包
		File writefile = new File(pathname); // 准备写入的post包
		FileInputStream fis = new FileInputStream(file);
		InputStreamReader isr = new InputStreamReader(fis, cs);
		BufferedReader br = new BufferedReader(isr); // 缓冲区读取
		BufferedWriter out = new BufferedWriter(new FileWriter(writefile)); // 缓冲区写入
		/** 准备结束 */
		String line;
		while ((line = br.readLine()) != null) { // 按行读取
			if (line.equals("")) { // 如果是空格分隔符
				out.write("Transfer-Encoding: chunked\r\n"); // 写入分块传输头
				out.write("\r\n");
				while ((line = br.readLine()) != null) { // 读取body
					EncodeString += line; // 将body拼接在一起
				}
			} else
				out.write(line + "\r\n"); // 否则按行写入
		}
		out.flush();
		out.close();
		br.close();

	}

	// 十进制整数转化为16进制
	public static String convert(int n) {
		return Integer.toHexString(n);
	}

	// 处理有ascii码的程序 按照最少三个字节切分
	/*
	 * 
	 * @mod 为输入的希望切割的分块数,带ascii码的分块值最少为3
	 */
	public static void EncodingAscii(int mod) throws IOException {
		File writefile = new File(pathname); // 准备写入的文件
		BufferedWriter out = new BufferedWriter(new FileWriter(writefile, true)); // 写入器
		byte[] buffer = EncodeString.getBytes(); // 把字符串转化为字节数组
		int i;
		for (i = 0; i < buffer.length && buffer.length - i > mod; i++) { // 逐字节读取,确保剩下的字节数大于分块数
			int count = i;
			int c = 0; // 每个分块数
			Queue<Character> queue = new Queue<Character>(); // 队列
			for (int j = count; j < count + mod; j++) { // 处理每个分块
				if (buffer[j] == 37) { // 如果读到的了%分号
					// 强制输出至少三次
					queue.enqueue((char) buffer[j++]);
					queue.enqueue((char) buffer[j++]);
					queue.enqueue((char) buffer[j]);
					c += 3;
				} else {
					queue.enqueue((char) buffer[j]); // 正常加入队列
					c++;
				}
				if (j >= count + mod - 1) {
					out.write(convert(c) + "\r\n"); // 写入分块数
					while (!queue.isEmpty()) // 将队列清空
						out.write(queue.dequeue());
					out.write("\r\n");
				}
				i = j;
			}

		}
		out.write((buffer.length - i) + "\r\n");
		while (i < buffer.length) // 打印剩下的元素
			out.write((char) buffer[i++]);
		out.write("\r\n0\r\n");
		out.flush();
		out.close();
	}

	public static void main(String[] args) throws Exception {
		// 把FileName和Pathname改成自己想要的的路径,mod为希望切割的份数
		TransferEncoding.readUsingBufferedReader(FileName, pathname, StandardCharsets.UTF_8);
		TransferEncoding.EncodingAscii(mod);

	}
}

import java.util.Iterator;
import java.util.NoSuchElementException;

/*
 * 队列类
 */

public class Queue<Item> implements Iterable<Item> {
	private Node<Item> first;		
	private Node<Item> last;
	private int n;
	
	private static class Node<Item>{
		private Item item;
		private Node<Item> next;
	}
	
	public Queue() {
		first = null;		
		last = null;
		n = 0;		
	}
	
	public boolean isEmpty() {
		return first == null;
	}
	
	public int size() {
		return n;
	}
	
	public Item peek() {
		if(isEmpty()) throw new NoSuchElementException("Queue underflow");
		return first.item;
	}
	
	public void enqueue(Item item) {
		Node<Item> oldlast = last;
		last = new Node<Item>();
		last.item = item;
		last.next = null;
		if(isEmpty()) first = last;
		else oldlast.next = last;
		n++;
	}
	
	public Item dequeue() {
		if(isEmpty()) throw new NoSuchElementException("Queue underflow");
		Item item = first.item;
		first = first.next;
		n--;
		if(isEmpty()) last = null;	
		return item;
	}
	
	public String toString() {
		StringBuilder s = new StringBuilder();
		for (Item item:this) {
			s.append(item);
			s.append(' ');
		}
		return s.toString();
	}
	
	// 迭代器
	public Iterator<Item> iterator(){
		return new ListIterator<Item>(first);
	}
	
	private class ListIterator<Item> implements Iterator<Item>{
		private Node<Item> current;
		
		public ListIterator(Node<Item> first) {
			current = first;
		}
		
		public boolean hasNext() { return current != null;}
		public void remove()	{ throw new UnsupportedOperationException();}
		
		public Item next() {
			if(!hasNext()) throw new NoSuchElementException();
			Item item = current.item;
			current = current.next;
			return item;
		}
	}
	
	
}

猜你喜欢

转载自blog.csdn.net/weixin_44555861/article/details/87874524
今日推荐