From d1f793d95e474bd8f57f120fe4c8126cb4f45ac9 Mon Sep 17 00:00:00 2001 From: Adam Stasiak Date: Sat, 22 Feb 2014 07:30:02 -0500 Subject: [PATCH] Added linked USBHID filter/injector --- src/Filters/PacketFilter_UDPHID.cpp | 53 ++++++++++ src/Filters/PacketFilter_UDPHID.h | 42 ++++++++ src/Injectors/Injector_UDPHID.cpp | 148 ++++++++++++++++++++++++++++ src/Injectors/Injector_UDPHID.h | 57 +++++++++++ src/include/PacketFilter.h | 2 +- src/tools/usb-mitm.cpp | 15 ++- 6 files changed, 315 insertions(+), 2 deletions(-) create mode 100644 src/Filters/PacketFilter_UDPHID.cpp create mode 100644 src/Filters/PacketFilter_UDPHID.h create mode 100644 src/Injectors/Injector_UDPHID.cpp create mode 100644 src/Injectors/Injector_UDPHID.h diff --git a/src/Filters/PacketFilter_UDPHID.cpp b/src/Filters/PacketFilter_UDPHID.cpp new file mode 100644 index 00000000..934f9bc2 --- /dev/null +++ b/src/Filters/PacketFilter_UDPHID.cpp @@ -0,0 +1,53 @@ +/* + * Copyright 2013 Dominic Spill + * Copyright 2013 Adam Stasiak + * + * This file is part of USBProxy. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + * + * PacketFilter_UDPHID.cpp + * + * Created on: Feb 22, 2014 + */ +#include "PacketFilter_UDPHID.h" + +PacketFilter_UDPHID::PacketFilter_UDPHID(Injector_UDPHID* injector) { + this->interface.deviceClass=0xff; + this->interface.subClass=0x5d; + this->endpoint.address=0x80; + this->endpoint.addressMask=0x80; + this->packetHeaderMaskLength=2; + this->packetHeader[0]=0; + this->packetHeader[1]=20; + this->packetHeaderMask[0]=0xff; + this->packetHeaderMask[1]=0xff; + this->packetHeaderSetupIn=false; + this->packetHeaderSetupOut=false; + reportBuffer=injector->getReportBuffer(); +} + +void PacketFilter_UDPHID::filter_packet(Packet* packet) { + int i; + if (packet->wLength!=20) return; + packet->data[2]=packet->data[2]|reportBuffer[2]; + packet->data[3]=packet->data[3]|reportBuffer[3]; + for (i=4;i<=13;i++) { + if (reportBuffer[i]) packet->data[i]=reportBuffer[i]; + } +} +void PacketFilter_UDPHID::filter_setup_packet(SetupPacket* packet,bool direction) { +} diff --git a/src/Filters/PacketFilter_UDPHID.h b/src/Filters/PacketFilter_UDPHID.h new file mode 100644 index 00000000..72374a16 --- /dev/null +++ b/src/Filters/PacketFilter_UDPHID.h @@ -0,0 +1,42 @@ +/* + * Copyright 2013 Dominic Spill + * Copyright 2013 Adam Stasiak + * + * This file is part of USBProxy. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + * + * PacketFilter_UDPHID.h + * + * Created on: Feb 22, 2014 + */ +#ifndef PACKETFILTER_UDPHID_H_ +#define PACKETFILTER_UDPHID_H_ + +#include "PacketFilter.h" +#include "../Injectors/Injector_UDPHID.h" + +//writes all traffic to a stream +class PacketFilter_UDPHID : public PacketFilter { +private: + __u8* reportBuffer; +public: + PacketFilter_UDPHID(Injector_UDPHID* injector); + void filter_packet(Packet* packet); + void filter_setup_packet(SetupPacket* packet,bool direction); + virtual char* toString() {return (char*)"UDPHID Filter";} +}; +#endif /* PACKETFILTER_UDPHID_H_ */ diff --git a/src/Injectors/Injector_UDPHID.cpp b/src/Injectors/Injector_UDPHID.cpp new file mode 100644 index 00000000..510d59b6 --- /dev/null +++ b/src/Injectors/Injector_UDPHID.cpp @@ -0,0 +1,148 @@ +/* + * Copyright 2013 Dominic Spill + * Copyright 2013 Adam Stasiak + * + * This file is part of USBProxy. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + * + * InjectorUDPHID.cpp + * + * Created on: Feb 22, 2014 + */ +#include +#include +#include +#include +#include "errno.h" +#include "netinet/in.h" + +#include "Injector_UDPHID.h" +#include "Packet.h" +#include "HexString.h" + +Injector_UDPHID::Injector_UDPHID(__u16 _port) { + port=_port; + sck=0; + buf=NULL; + spoll.events=POLLIN; + this->interface.deviceClass=0xff; + this->interface.subClass=0x5d; + this->endpoint.address=0x80; + this->endpoint.addressMask=0x80; + reportBuffer[0]=0; + reportBuffer[1]=0x14; + reportBuffer[2]=0; + reportBuffer[3]=0; + reportBuffer[4]=0; + reportBuffer[5]=0; + reportBuffer[6]=0; + reportBuffer[7]=0; + reportBuffer[8]=0; + reportBuffer[9]=0; + reportBuffer[10]=0; + reportBuffer[11]=0; + reportBuffer[12]=0; + reportBuffer[13]=0; + reportBuffer[14]=0; + reportBuffer[15]=0; + reportBuffer[16]=0; + reportBuffer[17]=0; + reportBuffer[18]=0; + reportBuffer[19]=0; +} + +Injector_UDPHID::~Injector_UDPHID() { + if (sck) {close(sck);sck=0;} + if (buf) {free(buf);buf=NULL;} +} + +void Injector_UDPHID::start_injector() { + fprintf(stderr,"Opening injection UDP socket on port %d.\n",port); + sck=socket(AF_INET,SOCK_DGRAM | SOCK_CLOEXEC,IPPROTO_UDP); + spoll.fd=sck; + if (sck<0) { + fprintf(stderr,"Error creating socket.\n"); + sck=0; + } + struct sockaddr_in addr; + memset((char *)&addr,0,sizeof(addr)); + addr.sin_family=AF_INET; + addr.sin_addr.s_addr=htonl(INADDR_ANY); + addr.sin_port=htons(port); + if (bind(sck,(struct sockaddr*)&addr,sizeof(addr))<0) { + fprintf(stderr,"Error binding to port %d.\n",port); + sck=0; + } + //sized to handle ETHERNET less IP(20 byte)/UDP(8 byte) headers + buf=(__u8*)malloc(UDP_BUFFER_SIZE); +} + +int* Injector_UDPHID::get_pollable_fds() { + int* tmp=(int*)calloc(2,sizeof(int)); + tmp[0]=sck; + return tmp; +} + +void Injector_UDPHID::stop_injector() { + if (sck) {close(sck);sck=0;} + if (buf) {free(buf);buf=NULL;} +} +void Injector_UDPHID::get_packets(Packet** packet,SetupPacket** setup,int timeout) { + *packet=NULL; + *setup=NULL; + + if (!poll(&spoll, 1, timeout) || !(spoll.revents&POLLIN)) { + return; + } + + ssize_t len=recv(sck,buf,UDP_BUFFER_SIZE,0); + if (len>0) { + if (buf[0]) { + __u16 usblen=buf[2]<<8 | buf[3]; + __u8* usbbuf=(__u8*)malloc(usblen); + memcpy(usbbuf,buf+4,usblen); + *packet=new Packet(buf[0],usbbuf,usblen,buf[1]&0x01?false:true); + (*packet)->transmit=buf[1]&0x02?false:true; + if ((*packet)->wLength==20) { + __u8* data=(*packet)->data; + if (data[0]==0 && data[1]==20) {memcpy(reportBuffer+2,data+2,12);} + } + return; + } else { + struct usb_ctrlrequest ctrl_req; + memcpy(&ctrl_req,buf+3,8); + if (ctrl_req.bRequestType&0x80) { + *setup=new SetupPacket(ctrl_req,NULL,true); + } else { + __u8* usbbuf=(__u8*)malloc(ctrl_req.wLength); + memcpy(usbbuf,buf+11,ctrl_req.wLength); + *setup=new SetupPacket(ctrl_req,usbbuf,true); + } + (*setup)->filter_out=~(buf[1]&0x01); + (*setup)->transmit_out=~(buf[1]&0x02); + (*setup)->filter_in=~(buf[1]&0x04); + (*setup)->transmit_in=~(buf[1]&0x08); + return; + } + } + if (len<0) { + fprintf(stderr,"Socket read error [%s].\n",strerror(errno)); + } + return; +} + +void Injector_UDPHID::full_pipe(Packet* p) {fprintf(stderr,"Packet returned due to full pipe & buffer\n");} diff --git a/src/Injectors/Injector_UDPHID.h b/src/Injectors/Injector_UDPHID.h new file mode 100644 index 00000000..61d79eab --- /dev/null +++ b/src/Injectors/Injector_UDPHID.h @@ -0,0 +1,57 @@ +/* + * Copyright 2013 Dominic Spill + * Copyright 2013 Adam Stasiak + * + * This file is part of USBProxy. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + * + * InjectorUDPHID.h + * + * Created on: Feb 22, 2014 + */ +#ifndef INJECTORUDPHID_H_ +#define INJECTORUDPHID_H_ + +#include "Injector.h" +#include +#include + +#define UDP_BUFFER_SIZE 1472 + +class Injector_UDPHID: public Injector { +private: + __u16 port; + int sck; + __u8* buf; + struct pollfd spoll; + __u8 reportBuffer[20]; + +protected: + void start_injector(); + void stop_injector(); + int* get_pollable_fds(); + void full_pipe(Packet* p); + + void get_packets(Packet** packet,SetupPacket** setup,int timeout=500); + +public: + Injector_UDPHID(__u16 _port); + virtual ~Injector_UDPHID(); + __u8* getReportBuffer() {return reportBuffer;} +}; + +#endif /* INJECTORUDPHID_H_ */ diff --git a/src/include/PacketFilter.h b/src/include/PacketFilter.h index 50588b80..a0f3016a 100644 --- a/src/include/PacketFilter.h +++ b/src/include/PacketFilter.h @@ -39,7 +39,7 @@ #include "Criteria.h" class PacketFilter { -private: +protected: __u8 packetHeader[8]; __u8 packetHeaderMask[8]; __u8 packetHeaderMaskLength; diff --git a/src/tools/usb-mitm.cpp b/src/tools/usb-mitm.cpp index 0dbe1b33..52386b4f 100644 --- a/src/tools/usb-mitm.cpp +++ b/src/tools/usb-mitm.cpp @@ -46,6 +46,7 @@ #include "DeviceProxy_TCP.h" #include "DeviceProxy_Loopback.h" #include "Injector_UDP.h" +#include "Injector_UDPHID.h" #include "HostProxy_GadgetFS.h" #include "HostProxy_TCP.h" #include "PacketFilter_PcapLogger.h" @@ -53,6 +54,7 @@ #include "PacketFilter_ROT13.h" #include "PacketFilter_StreamLog.h" #include "PacketFilter_Python.h" +#include "PacketFilter_UDPHID.h" static int debug=0; @@ -70,6 +72,7 @@ void usage(char *arg) { printf("\t-c Client mode, connect to server at hostname or address\n"); printf("\t-l Enable stream logger (logs to stderr)\n"); printf("\t-i Enable UDP injector\n"); + printf("\t-x Enable Xbox360 UDPHID injector & filter\n"); printf("\t-k Keylogger with ROT13 filter (for demo)\n"); printf("\t-w Write to pcap file for viewing in Wireshark\n"); printf("\t-h Display this message\n"); @@ -121,14 +124,16 @@ extern "C" int main(int argc, char **argv) sigaction(SIGINT, &action, NULL); Injector_UDP* udpinjector; + Injector_UDPHID* xboxinjector; PacketFilter_StreamLog* logfilter; PacketFilter_ROT13* rotfilter; PacketFilter_KeyLogger* keyfilter; PacketFilter_PcapLogger* pcaplogger; + PacketFilter_UDPHID* xboxfilter; manager=new Manager(); - while ((c = getopt (argc, argv, "v:p:dsc:likw:h")) != EOF) { + while ((c = getopt (argc, argv, "v:p:dsc:likw:hx")) != EOF) { switch (c) { case 'v': vendorId = strtol(optarg, &end, 16); @@ -164,11 +169,19 @@ extern "C" int main(int argc, char **argv) pcaplogger=new PacketFilter_PcapLogger(optarg); manager->add_filter(pcaplogger); break; + case 'x': + xboxinjector=new Injector_UDPHID(12345); + manager->add_injector(xboxinjector); + xboxfilter=new PacketFilter_UDPHID(xboxinjector); + manager->add_filter(xboxfilter); + break; case 'h': default: usage(argv[0]); return 1; } + //manager->add_filter(pcaplogger); + } DeviceProxy_LibUSB::debugLevel=debug;