diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/bin/mcast-raw.c | 21 | ||||
-rw-r--r-- | src/bin/mcast.c | 26 | ||||
-rw-r--r-- | src/bin/supersu.c | 35 | ||||
-rw-r--r-- | src/libexec/socks4a-proxy.c | 105 |
4 files changed, 187 insertions, 0 deletions
diff --git a/src/bin/mcast-raw.c b/src/bin/mcast-raw.c new file mode 100644 index 0000000..81913d3 --- /dev/null +++ b/src/bin/mcast-raw.c @@ -0,0 +1,21 @@ +#include <stdio.h> +#include <sys/socket.h> +#include <netinet/in.h> + +int main(int argc,char *argv[]) { + int s=socket(AF_INET,SOCK_RAW,atoi(argv[2])); + char packet[1501];//mtu of an interface. including headers though. meh. + int n; + struct ip_mreq mreq; + struct sockaddr_in sa; + int one = sizeof(struct sockaddr_in); + setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); + mreq.imr_multiaddr.s_addr=inet_addr(argv[1]); + mreq.imr_interface.s_addr=htonl(INADDR_ANY); + setsockopt(s,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq)); + while((n=recvfrom(s,packet,sizeof(packet),0,(struct sockaddr *)&sa,&one)) > 0) { + printf("%s ",inet_ntoa(sa.sin_addr)); + fflush(stdout); + write(1,packet,n); + } +} diff --git a/src/bin/mcast.c b/src/bin/mcast.c new file mode 100644 index 0000000..e48c504 --- /dev/null +++ b/src/bin/mcast.c @@ -0,0 +1,26 @@ +#include <stdio.h> +#include <sys/socket.h> +#include <netinet/in.h> + +int main(int argc,char *argv[]) { + int s=socket(AF_INET,SOCK_DGRAM,0); + char packet[1501];//mtu of an interface. including headers though. meh. + int n; + struct ip_mreq mreq; + struct sockaddr_in sa; + int one = sizeof(struct sockaddr_in); + setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); + memset(&sa,0,sizeof(struct sockaddr_in)); + sa.sin_addr.s_addr=htonl(INADDR_ANY); + sa.sin_port=htons(atoi(argv[2])); + sa.sin_family=AF_INET; + bind(s,(struct sockaddr *)&sa,sizeof(struct sockaddr_in)); + mreq.imr_multiaddr.s_addr=inet_addr(argv[1]); + mreq.imr_interface.s_addr=htonl(INADDR_ANY); + setsockopt(s,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq)); + while((n=recvfrom(s,packet,sizeof(packet),0,(struct sockaddr *)&sa,&one)) > 0) { + printf("%s ",inet_ntoa(sa.sin_addr)); + fflush(stdout); + write(1,packet,n); + } +} diff --git a/src/bin/supersu.c b/src/bin/supersu.c new file mode 100644 index 0000000..d3f7fec --- /dev/null +++ b/src/bin/supersu.c @@ -0,0 +1,35 @@ +#include <stdio.h> + +int main(int argc,char *argv[]) { + int i; + if(argc < 4) { + fprintf(stderr,"usage: %s uid gid [secondary_gids] absolute-path-of-executable\n",argv[0]); + return 0; + } + if(getuid() && geteuid()) { + fprintf(stderr,"supersu: uid: %d, euid: %d... I have no idea how this is supposed to work. oh well.\n",getuid(),geteuid()); + } + int groups[argc-2]; + int ngroups=0; + char **name; + int here=0; + for(i=2;i<argc;i++) { + if(argv[i][0]=='/') { + here=i; + break; + } + } + if(here == 0) { + fprintf(stderr,"%s: I didn't find an absolute-path in the argument list.\n",argv[0]); + return 0; + } + ngroups=argc-(argc-here)-2; + for(i=2;i<here;i++) { + groups[i-2]=atoi(argv[i]); + } + name=argv+i; + setgroups(ngroups,groups); + setgid(atoi(argv[2])); + setuid(atoi(argv[1])); + execv(*name,name); +} diff --git a/src/libexec/socks4a-proxy.c b/src/libexec/socks4a-proxy.c new file mode 100644 index 0000000..a179d40 --- /dev/null +++ b/src/libexec/socks4a-proxy.c @@ -0,0 +1,105 @@ +#include <stdio.h> +#include <unistd.h> +#include <arpa/inet.h> +#include <errno.h> +#include <sys/wait.h> +#include <syslog.h> +#include <netdb.h> + +int main(int argc,char *argv[]) { + unsigned char vn;//version + unsigned char cd;//command + unsigned short dstport; + unsigned int dstip; + unsigned char in; + int i; + int status; + char *name[5]; + char user[256]; + char sport[10];//10 is more than enough. it is converted from a short with %d + char host[256];//https://blogs.msdn.microsoft.com/oldnewthing/20120412-00/?p=7873/ + read(0,&vn,1); + //fprintf(stderr,"version number: %d\n",vn); + if(vn != 4) { + //fprintf(stderr,"received wrong version number. needs to be 4.\n"); + write(1,"\x00\x5b\xde\xca\xf0\xc0\xff\xee",8);//the decaf0coffee is supposed to be ignored by clients. + return 1; + } + read(0,&cd,1); + //fprintf(stderr,"command code: %d\n",cd); + if(cd != 1) { + //fprintf(stderr,"only going to implement command code 1 (connect) atm.\n"); + write(1,"\x00\x5b\xde\xca\xf0\xc0\xff\xee",8);//the response is in the same format as the request. vn+cd+port+ip + return 2; + } + read(0,&dstport,2); + //fprintf(stderr,"dstport: %d\n",ntohs(dstport)); + read(0,&dstip,4); + //fprintf(stderr,"dstip: %d\n",ntohl(dstip)); + for(i=0;i<254;i++) { + read(0,user+i,1); + if(!user[i]) break;//we read a null, let's hop out. + } + if(user[i]) {//we didn't read the whole thing. truncate and just ignore the rest. + user[i]=0; + while(read(0,&in,1) > 0) { + if (in == 0) break; + } + } + //fprintf(stderr,"user: %s\n",user); + //do some sort of auth here... + //pass it off to a script? + if(argc>2) {//we have an argument for the script to run auth against. + //what do we need to pass? the port we're on, the port they connected from + switch(fork()) { + case -1: + return errno; + case 0://child. + name[0]=argv[2]; + name[1]=user; + name[2]=0; + execv(name[0],name); + return errno; + default: + break; + } + wait(&status); + } + if(WEXITSTATUS(status)) {//anything but 0 is an error. + write(1,"\x00\x5b\xde\xca\xf0\xc0\xff\xee",8); + return 3; + } + if(ntohl(dstip) < 256) { //this should match for an address that is 0.0.0.x where x could be anything. + //do what we did for user, but with a hostname now. + for(i=0;i<254;i++) { + read(0,host+i,1); + if(!host[i]) break; + } + if(host[i]) {//we didn't read the whole thing. truncate and just ignore the rest. + host[i]=0; + while(read(0,&in,1) > 0) { + if (in == 0) break; + } + } + //fprintf(stderr,"host: %s\n",host); + } + struct sockaddr_in6 sa6; + unsigned int sl=sizeof(sa6); + char h[NI_MAXHOST], s[NI_MAXSERV]; + if(getpeername(argc>1?atoi(argv[1]):0,(struct sockaddr *)&sa6,&sl) == -1) return 1; + if(getnameinfo((struct sockaddr *)&sa6,sl,h,sizeof(h),s,sizeof(s),NI_NUMERICHOST|NI_NUMERICSERV)) return 2; + + syslog(LOG_WARNING,"proxy request: %s@%s:%s => %s:%d",user,h,s,host,ntohs(dstport)); + //fprintf(stderr,"got passed all that shit...\n"); + write(1,"\x00\x5a\xde\xca\xf0\xc0\xff\xee",8); + snprintf(sport,sizeof(sport)-1,"%u",ntohs(dstport));//%u because ports are unsigned. + name[0]=argc>1?argv[1]:"/usr/pkg/bin/nc";//if you want the arguments in a different order either change this sauce or use a script. + name[1]=host;//WARNING: these two arguments aren't sanitized. they may contain flags set by the proxy's user that could wreak havok! + name[2]=sport;//not sure how many programs can be messed up using just a number though. + name[3]=0; + //fprintf(stderr,"running: %s %s %s %s\n",name[0],name[1],name[2],name[3]); + execv(name[0],name); + //fprintf(stderr,"execv failed. :/"); + //perror("execv"); + return errno;//if we get here something failed so we might as well return errno. +} |