├── SharpLoadImage
├── Resources
│ └── peanut.jpg
├── packages.config
├── Properties
│ └── AssemblyInfo.cs
├── SharpLoadImage.csproj
└── Program.cs
├── TestClass
├── Program.cs
├── Properties
│ └── AssemblyInfo.cs
└── TestClass.csproj
├── README.md
├── LICENSE
└── SharpLoadImage.sln
/SharpLoadImage/Resources/peanut.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/b4rtik/SharpLoadImage/HEAD/SharpLoadImage/Resources/peanut.jpg
--------------------------------------------------------------------------------
/SharpLoadImage/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/TestClass/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | public class TestClass
4 | {
5 | public static void Execute()
6 | {
7 | Console.WriteLine("Hello");
8 | }
9 | }
10 |
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SharpLoadImage
2 |
3 | Hide assembly into png images
4 |
5 | SharpImage small tool to embed .Net assembly on it, useful to hide traffic of an implant.
6 |
7 | The main code is a porting of [Invoke-PSImage](https://github.com/peewpw/Invoke-PSImage) .
8 |
9 | ```
10 | usage: SharpLoadImage -a [path to assembly] -i [path to image source] -o [path to output file]
11 | ```
12 |
13 | Image source can be most image types but output will be allways png.
14 |
15 | The tool generare the image with assembly embedded and test it's execution
16 |
17 |
--------------------------------------------------------------------------------
/SharpLoadImage/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | [assembly: AssemblyTitle("SharpLoadImage")]
6 | [assembly: AssemblyDescription("")]
7 | [assembly: AssemblyConfiguration("")]
8 | [assembly: AssemblyCompany("")]
9 | [assembly: AssemblyProduct("SharpLoadImage")]
10 | [assembly: AssemblyCopyright("Copyright © 2019")]
11 | [assembly: AssemblyTrademark("")]
12 | [assembly: AssemblyCulture("")]
13 |
14 | [assembly: ComVisible(false)]
15 |
16 | [assembly: Guid("46c1d828-0a2d-4d8a-833d-a19fc3e1539e")]
17 |
18 | [assembly: AssemblyVersion("1.0.0.0")]
19 | [assembly: AssemblyFileVersion("1.0.0.0")]
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 3-Clause License
2 |
3 | Copyright (c) 2019, b4rtik
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | 1. Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | 2. Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | 3. Neither the name of the copyright holder nor the names of its
17 | contributors may be used to endorse or promote products derived from
18 | this software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
--------------------------------------------------------------------------------
/TestClass/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // Le informazioni generali relative a un assembly sono controllate dal seguente
6 | // set di attributi. Modificare i valori di questi attributi per modificare le informazioni
7 | // associate a un assembly.
8 | [assembly: AssemblyTitle("TestClass")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("TestClass")]
13 | [assembly: AssemblyCopyright("Copyright © 2019")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Se si imposta ComVisible su false, i tipi in questo assembly non saranno visibili
18 | // ai componenti COM. Se è necessario accedere a un tipo in questo assembly da
19 | // COM, impostare su true l'attributo ComVisible per tale tipo.
20 | [assembly: ComVisible(false)]
21 |
22 | // Se il progetto viene esposto a COM, il GUID seguente verrà utilizzato come ID della libreria dei tipi
23 | [assembly: Guid("47baf37c-375e-4beb-8347-edf29342a7dc")]
24 |
25 | // Le informazioni sulla versione di un assembly sono costituite dai seguenti quattro valori:
26 | //
27 | // Versione principale
28 | // Versione secondaria
29 | // Numero di build
30 | // Revisione
31 | //
32 | // È possibile specificare tutti i valori oppure impostare valori predefiniti per i numeri relativi alla revisione e alla build
33 | // usando l'asterisco '*' come illustrato di seguito:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/SharpLoadImage.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.28307.645
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpLoadImage", "SharpLoadImage\SharpLoadImage.csproj", "{46C1D828-0A2D-4D8A-833D-A19FC3E1539E}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestClass", "TestClass\TestClass.csproj", "{47BAF37C-375E-4BEB-8347-EDF29342A7DC}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Debug|x64 = Debug|x64
14 | Release|Any CPU = Release|Any CPU
15 | Release|x64 = Release|x64
16 | EndGlobalSection
17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 | {46C1D828-0A2D-4D8A-833D-A19FC3E1539E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
19 | {46C1D828-0A2D-4D8A-833D-A19FC3E1539E}.Debug|Any CPU.Build.0 = Debug|Any CPU
20 | {46C1D828-0A2D-4D8A-833D-A19FC3E1539E}.Debug|x64.ActiveCfg = Debug|Any CPU
21 | {46C1D828-0A2D-4D8A-833D-A19FC3E1539E}.Debug|x64.Build.0 = Debug|Any CPU
22 | {46C1D828-0A2D-4D8A-833D-A19FC3E1539E}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {46C1D828-0A2D-4D8A-833D-A19FC3E1539E}.Release|Any CPU.Build.0 = Release|Any CPU
24 | {46C1D828-0A2D-4D8A-833D-A19FC3E1539E}.Release|x64.ActiveCfg = Release|Any CPU
25 | {46C1D828-0A2D-4D8A-833D-A19FC3E1539E}.Release|x64.Build.0 = Release|Any CPU
26 | {47BAF37C-375E-4BEB-8347-EDF29342A7DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27 | {47BAF37C-375E-4BEB-8347-EDF29342A7DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
28 | {47BAF37C-375E-4BEB-8347-EDF29342A7DC}.Debug|x64.ActiveCfg = Debug|x64
29 | {47BAF37C-375E-4BEB-8347-EDF29342A7DC}.Debug|x64.Build.0 = Debug|x64
30 | {47BAF37C-375E-4BEB-8347-EDF29342A7DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
31 | {47BAF37C-375E-4BEB-8347-EDF29342A7DC}.Release|Any CPU.Build.0 = Release|Any CPU
32 | {47BAF37C-375E-4BEB-8347-EDF29342A7DC}.Release|x64.ActiveCfg = Release|x64
33 | {47BAF37C-375E-4BEB-8347-EDF29342A7DC}.Release|x64.Build.0 = Release|x64
34 | EndGlobalSection
35 | GlobalSection(SolutionProperties) = preSolution
36 | HideSolutionNode = FALSE
37 | EndGlobalSection
38 | GlobalSection(ExtensibilityGlobals) = postSolution
39 | SolutionGuid = {DC0DC830-3EB5-432D-BE2D-055ED6231966}
40 | EndGlobalSection
41 | EndGlobal
42 |
--------------------------------------------------------------------------------
/SharpLoadImage/SharpLoadImage.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {46C1D828-0A2D-4D8A-833D-A19FC3E1539E}
8 | Exe
9 | SharpLoadImage
10 | SharpLoadImage
11 | v4.0
12 | 512
13 | true
14 |
15 |
16 | AnyCPU
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | AnyCPU
27 | pdbonly
28 | true
29 | bin\Release\
30 | TRACE
31 | prompt
32 | 4
33 | false
34 |
35 |
36 |
37 | ..\packages\NDesk.Options.0.2.1\lib\NDesk.Options.dll
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/TestClass/TestClass.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {47BAF37C-375E-4BEB-8347-EDF29342A7DC}
8 | Library
9 | TestClass
10 | TestClass
11 | v4.0
12 | 512
13 | true
14 |
15 |
16 | AnyCPU
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | AnyCPU
27 | pdbonly
28 | true
29 | bin\Release\
30 | TRACE
31 | prompt
32 | 4
33 |
34 |
35 |
36 |
37 |
38 | true
39 | bin\x64\Debug\
40 | DEBUG;TRACE
41 | full
42 | x64
43 | prompt
44 | MinimumRecommendedRules.ruleset
45 |
46 |
47 | bin\x64\Release\
48 | TRACE
49 | true
50 | pdbonly
51 | x64
52 | prompt
53 | MinimumRecommendedRules.ruleset
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/SharpLoadImage/Program.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Authosìr: B4rtik (@b4rtik)
3 | // Project: SharpLoadImage (https://github.com/b4rtik/SharpLoadImage)
4 | // License: BSD 3-Clause
5 |
6 | using System;
7 | using System.Text;
8 | using System.Drawing;
9 | using NDesk.Options;
10 | using System.IO;
11 | using System.Drawing.Imaging;
12 | using System.Runtime.InteropServices;
13 | using System.Reflection;
14 | using System.Linq;
15 |
16 | namespace SharpLoadImage
17 | {
18 | class Program
19 | {
20 | static void ShowHelp(OptionSet p)
21 | {
22 | Console.WriteLine("usage: SharpLoadImage -a [path to assembly] -i [path to image source] -o [path to output file]");
23 | Console.WriteLine();
24 | Console.WriteLine("Options:");
25 | p.WriteOptionDescriptions(Console.Out);
26 | }
27 |
28 | static void Main(string[] args)
29 | {
30 | string assemblypath = "";
31 | string image = "";
32 | string outputfile = "";
33 | bool showHelp = false;
34 |
35 | var p = new OptionSet() {
36 | { "a|assembly=", "Assembly to hide.\n", v => assemblypath = v },
37 | { "i|image=", "Image src.", v => image = v },
38 | { "o|output=", "Output file", v => outputfile = v },
39 | { "h|help", "Show this message and exit.", v => showHelp = v != null },
40 | };
41 |
42 | try
43 | {
44 | try
45 | {
46 | p.Parse(args);
47 | }
48 | catch (OptionException e)
49 | {
50 | Console.WriteLine(e.Message);
51 | Console.WriteLine("Try '--help' for more information.");
52 | return;
53 | }
54 |
55 | if (showHelp)
56 | {
57 | ShowHelp(p);
58 | return;
59 | }
60 |
61 | //Payload to work
62 | byte[] payload = File.ReadAllBytes(assemblypath);
63 |
64 | Bitmap img = new Bitmap(image);
65 |
66 | int width = img.Size.Width;
67 | int height = img.Size.Height;
68 |
69 | //Lock the bitmap in memory so it can be changed programmatically.
70 | Rectangle rect = new Rectangle(0, 0, width, height);
71 | BitmapData bmpData = img.LockBits(rect, ImageLockMode.ReadWrite, img.PixelFormat);
72 | IntPtr ptr = bmpData.Scan0;
73 |
74 | // Copy the RGB values to an array for easy modification
75 | int bytes = Math.Abs(bmpData.Stride) * img.Height;
76 | byte[] rgbValues = new byte[bytes];
77 | Marshal.Copy(ptr, rgbValues, 0, bytes);
78 |
79 | //Check that the payload fits in the image
80 | if(bytes/2 < payload.Length) {
81 | Console.Write("Image not large enough to contain payload!");
82 | img.UnlockBits(bmpData);
83 | img.Dispose();
84 | return;
85 | }
86 |
87 | //Generate a random string to use to fill other pixel info in the picture.
88 | string randstr = RandomString(128);
89 | byte[] randb = Encoding.ASCII.GetBytes(randstr);
90 |
91 | //loop through the RGB array and copy the payload into it
92 | for (int counter = 0; counter < (rgbValues.Length) / 3; counter++) {
93 | int paybyte1;
94 | int paybyte2;
95 | int paybyte3;
96 | if (counter < payload.Length){
97 | paybyte1 = (int)Math.Floor((decimal)(payload[counter] / 16));
98 | paybyte2 = (payload[counter] & 0x0f);
99 | paybyte3 = (randb[(counter + 2) % 109] & 0x0f);
100 | } else {
101 | paybyte1 = (randb[counter % 113] & 0x0f);
102 | paybyte2 = (randb[(counter + 1)% 67] & 0x0f);
103 | paybyte3 = (randb[(counter + 2)% 109] & 0x0f);
104 | }
105 | rgbValues[(counter * 3)] = (byte)((rgbValues[(counter * 3)] & 0xf0) | paybyte1);
106 | rgbValues[(counter * 3 + 1)] = (byte)((rgbValues[(counter * 3 + 1)] & 0xf0) | paybyte2);
107 | rgbValues[(counter * 3 + 2)] = (byte)((rgbValues[(counter * 3 + 2)] & 0xf0) | paybyte3);
108 | }
109 |
110 | //Copy the array of RGB values back to the bitmap
111 | Marshal.Copy(rgbValues, 0, ptr, bytes);
112 | img.UnlockBits(bmpData);
113 |
114 | //Write the image to a file
115 | img.Save(outputfile, ImageFormat.Png);
116 | img.Dispose();
117 |
118 | ExecuteAssembly(outputfile, payload.Length);
119 |
120 | }
121 | catch (Exception e)
122 | {
123 | Console.WriteLine("[x] error: " + e.Message);
124 | Console.WriteLine("[x] error: " + e.StackTrace);
125 | }
126 | }
127 |
128 | private static void ExecuteAssembly(string imgfile, int payloadlength)
129 | {
130 | Bitmap g = new Bitmap(imgfile);
131 |
132 | int width = g.Size.Width;
133 |
134 | int rows = (int)Math.Ceiling((decimal)payloadlength / width);
135 | int array = (rows * width);
136 | byte[] o = new byte[array];
137 |
138 | int lrows = rows;
139 | int lwidth = width;
140 | int lpayload = payloadlength;
141 |
142 | for (int i = 0; i < lrows; i++)
143 | {
144 | for (int x = 0; x < lwidth; x++)
145 | {
146 | Color pcolor = g.GetPixel(x, i);
147 | o[i * width + x] = (byte)(Math.Floor((decimal)(((pcolor.B & 15) * 16) | (pcolor.G & 15))));
148 | }
149 | }
150 |
151 | //o contain payload
152 | byte[] otrue = new byte[lpayload];
153 | Array.Copy(o, otrue, lpayload);
154 |
155 | Assembly assembly = Assembly.Load(otrue);
156 | assembly.GetTypes()[0].GetMethods()[0].Invoke(null, new Object[0]);
157 | }
158 |
159 | private static string RandomString(int length)
160 | {
161 | Random random = new Random();
162 | const string chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
163 | return new string(Enumerable.Repeat(chars, length)
164 | .Select(s => s[random.Next(s.Length)]).ToArray());
165 | }
166 | }
167 | }
168 |
--------------------------------------------------------------------------------