Closed physics-sec closed 1 year ago
Thanks for the Issue. Do you have some code we could use to reproduce this error you are receiving?
Sure thing, I just created a dummy program to be injected:
using System;
using System.IO;
using System.Text;
namespace Program
{
class Program
{
public static void Main(string[] args)
{
string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\newfile.txt";
using (FileStream fs = File.Create(path))
{
byte[] info = new UTF8Encoding(true).GetBytes("some text");
fs.Write(info, 0, info.Length);
}
}
}
}
Compiled it with:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe /nologo /warn:0 /platform:x64 /t:exe .\createfile.cs
Transformed the .NET assembly into shellcode with:
./donut -a2 createfile.exe
(compiled donut with make
, in a linux machine, if you use the python module, you will get the same result)
When I inject the resulting loader.bin into a remote process (sublime text) with the simple Alloc, Write, CreateRemoteThread technique (I can provide the injector if you like, is just a little long for a comment) the process dies instantly.
The same thing but with a:
git checkout a260ea09f0149f4c9ca1a63744c3f977a2d0947f
works perfectly and the file is created both the donut binary and the python module (the python module has a small issue with the "sys" import, easy to fix with: sed -i 's/, sys/\nimport sys/' setup.py
)
Note that the following commit to that one, changed the LOADER_EXE_X64 shellcode, probably some instruction is bogus or something.
Let me know if you want the injector and if you need any more information. Thank you for this amazing tool! 😃
Which branch of donut is this from? master
or dev
?
master
Did you end up resolving this? If not, could you try it with what's in dev
now?
Sure thing, I will try it when I find a little time and let you know
Still doesn't work, (I also re-tested the old commit referenced before to make sure I wasn't making a mistake while testing and it works fine) plus, if I try to install the python module, I get this error:
Building wheels for collected packages: donut-shellcode
Building wheel for donut-shellcode (setup.py) ... error
ERROR: Command errored out with exit status 1:
command: /usr/bin/python3 -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-req-build-m2wearij/setup.py'"'"'; __file__='"'"'/tmp/pip-req-build-m2wearij/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' bdist_wheel -d /tmp/pip-wheel-e3grnimx
cwd: /tmp/pip-req-build-m2wearij/
Complete output (59 lines):
running bdist_wheel
running build
running build_ext
building 'donut' extension
creating build
creating build/temp.linux-x86_64-3.9
creating build/temp.linux-x86_64-3.9/loader
gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -fno-semantic-interposition -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -fPIC -Iinclude -I/usr/include/python3.9 -c donut.c -o build/temp.linux-x86_64-3.9/donut.o
donut.c: In function ‘read_file_info’:
donut.c:573:19: warning: comparison of integer expressions of different signedness: ‘ULONG64’ {aka ‘long unsigned int’} and ‘int’ [-Wsign-compare]
573 | if (ofs != -1) {
| ^~
donut.c:578:22: warning: comparison of integer expressions of different signedness: ‘ULONG64’ {aka ‘long unsigned int’} and ‘int’ [-Wsign-compare]
578 | if(ofs != -1) {
| ^~
donut.c: In function ‘gen_random_string’:
donut.c:674:15: warning: comparison of integer expressions of different signedness: ‘int’ and ‘uint64_t’ {aka ‘long unsigned int’} [-Wsign-compare]
674 | for(i=0; i<len; i++) {
| ^
donut.c: In function ‘is_dll_export’:
donut.c:1444:16: warning: comparison of integer expressions of different signedness: ‘ULONG64’ {aka ‘long unsigned int’} and ‘int’ [-Wsign-compare]
1444 | if(ofs != -1) {
| ^~
In function ‘build_module’,
inlined from ‘DonutCreate’ at donut.c:1553:17:
donut.c:775:7: warning: ‘strncpy’ output may be truncated copying 255 bytes from a string of length 255 [-Wstringop-truncation]
775 | strncpy(mod->method, c->method, DONUT_MAX_NAME-1);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
donut.c:753:9: warning: ‘strncpy’ output may be truncated copying 8 bytes from a string of length 255 [-Wstringop-truncation]
753 | strncpy(mod->domain, c->domain, DONUT_DOMAIN_LEN);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
donut.c:760:9: warning: ‘strncpy’ output may be truncated copying 255 bytes from a string of length 255 [-Wstringop-truncation]
760 | strncpy(mod->cls, c->cls, DONUT_MAX_NAME-1);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
donut.c:763:9: warning: ‘strncpy’ output may be truncated copying 255 bytes from a string of length 255 [-Wstringop-truncation]
763 | strncpy(mod->method, c->method, DONUT_MAX_NAME-1);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
donut.c:770:7: warning: ‘strncpy’ output may be truncated copying 255 bytes from a string of length 255 [-Wstringop-truncation]
770 | strncpy(mod->runtime, c->runtime, DONUT_MAX_NAME-1);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
donut.c:799:7: warning: ‘strncat’ output may be truncated copying 250 bytes from a string of length 255 [-Wstringop-truncation]
799 | strncat(mod->args, c->args, DONUT_MAX_NAME-6);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -fno-semantic-interposition -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -fPIC -Iinclude -I/usr/include/python3.9 -c donutmodule.c -o build/temp.linux-x86_64-3.9/donutmodule.o
donutmodule.c: In function ‘Donut_Create’:
donutmodule.c:135:16: error: ‘DONUT_CONFIG’ {aka ‘struct _DONUT_CONFIG’} has no member named ‘param’
135 | strncpy(c.param, params, DONUT_MAX_NAME - 1);
| ^
donutmodule.c:169:15: error: ‘DONUT_ERROR_SUCCESS’ undeclared (first use in this function); did you mean ‘DONUT_ERROR_FILE_ACCESS’?
169 | if(err != DONUT_ERROR_SUCCESS) {
| ^~~~~~~~~~~~~~~~~~~
| DONUT_ERROR_FILE_ACCESS
donutmodule.c:169:15: note: each undeclared identifier is reported only once for each function it appears in
donutmodule.c: At top level:
donutmodule.c:186:9: warning: initialization of ‘PyObject * (*)(PyObject *, PyObject *)’ {aka ‘struct _object * (*)(struct _object *, struct _object *)’} from incompatible pointer type ‘PyObject * (*)(PyObject *, PyObject *, PyObject *)’ {aka ‘struct _object * (*)(struct _object *, struct _object *, struct _object *)’} [-Wincompatible-pointer-types]
186 | Donut_Create, // C wrapper function
| ^~~~~~~~~~~~
donutmodule.c:186:9: note: (near initialization for ‘Donut_FunctionsTable[0].ml_meth’)
error: command '/usr/bin/gcc' failed with exit code 1
----------------------------------------
ERROR: Failed building wheel for donut-shellcode
Running setup.py clean for donut-shellcode
Failed to build donut-shellcode
Installing collected packages: donut-shellcode
Attempting uninstall: donut-shellcode
Found existing installation: donut-shellcode 0.9.3
Uninstalling donut-shellcode-0.9.3:
Successfully uninstalled donut-shellcode-0.9.3
Running setup.py install for donut-shellcode ... error
ERROR: Command errored out with exit status 1:
command: /usr/bin/python3 -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-req-build-m2wearij/setup.py'"'"'; __file__='"'"'/tmp/pip-req-build-m2wearij/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-jobz3lsw/install-record.txt --single-version-externally-managed --user --prefix= --compile --install-headers /home/someuser/.local/include/python3.9/donut-shellcode
cwd: /tmp/pip-req-build-m2wearij/
Complete output (59 lines):
running install
running build
running build_ext
building 'donut' extension
creating build
creating build/temp.linux-x86_64-3.9
creating build/temp.linux-x86_64-3.9/loader
gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -fno-semantic-interposition -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -fPIC -Iinclude -I/usr/include/python3.9 -c donut.c -o build/temp.linux-x86_64-3.9/donut.o
donut.c: In function ‘read_file_info’:
donut.c:573:19: warning: comparison of integer expressions of different signedness: ‘ULONG64’ {aka ‘long unsigned int’} and ‘int’ [-Wsign-compare]
573 | if (ofs != -1) {
| ^~
donut.c:578:22: warning: comparison of integer expressions of different signedness: ‘ULONG64’ {aka ‘long unsigned int’} and ‘int’ [-Wsign-compare]
578 | if(ofs != -1) {
| ^~
donut.c: In function ‘gen_random_string’:
donut.c:674:15: warning: comparison of integer expressions of different signedness: ‘int’ and ‘uint64_t’ {aka ‘long unsigned int’} [-Wsign-compare]
674 | for(i=0; i<len; i++) {
| ^
donut.c: In function ‘is_dll_export’:
donut.c:1444:16: warning: comparison of integer expressions of different signedness: ‘ULONG64’ {aka ‘long unsigned int’} and ‘int’ [-Wsign-compare]
1444 | if(ofs != -1) {
| ^~
In function ‘build_module’,
inlined from ‘DonutCreate’ at donut.c:1553:17:
donut.c:775:7: warning: ‘strncpy’ output may be truncated copying 255 bytes from a string of length 255 [-Wstringop-truncation]
775 | strncpy(mod->method, c->method, DONUT_MAX_NAME-1);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
donut.c:753:9: warning: ‘strncpy’ output may be truncated copying 8 bytes from a string of length 255 [-Wstringop-truncation]
753 | strncpy(mod->domain, c->domain, DONUT_DOMAIN_LEN);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
donut.c:760:9: warning: ‘strncpy’ output may be truncated copying 255 bytes from a string of length 255 [-Wstringop-truncation]
760 | strncpy(mod->cls, c->cls, DONUT_MAX_NAME-1);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
donut.c:763:9: warning: ‘strncpy’ output may be truncated copying 255 bytes from a string of length 255 [-Wstringop-truncation]
763 | strncpy(mod->method, c->method, DONUT_MAX_NAME-1);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
donut.c:770:7: warning: ‘strncpy’ output may be truncated copying 255 bytes from a string of length 255 [-Wstringop-truncation]
770 | strncpy(mod->runtime, c->runtime, DONUT_MAX_NAME-1);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
donut.c:799:7: warning: ‘strncat’ output may be truncated copying 250 bytes from a string of length 255 [-Wstringop-truncation]
799 | strncat(mod->args, c->args, DONUT_MAX_NAME-6);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -fno-semantic-interposition -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -fPIC -Iinclude -I/usr/include/python3.9 -c donutmodule.c -o build/temp.linux-x86_64-3.9/donutmodule.o
donutmodule.c: In function ‘Donut_Create’:
donutmodule.c:135:16: error: ‘DONUT_CONFIG’ {aka ‘struct _DONUT_CONFIG’} has no member named ‘param’
135 | strncpy(c.param, params, DONUT_MAX_NAME - 1);
| ^
donutmodule.c:169:15: error: ‘DONUT_ERROR_SUCCESS’ undeclared (first use in this function); did you mean ‘DONUT_ERROR_FILE_ACCESS’?
169 | if(err != DONUT_ERROR_SUCCESS) {
| ^~~~~~~~~~~~~~~~~~~
| DONUT_ERROR_FILE_ACCESS
donutmodule.c:169:15: note: each undeclared identifier is reported only once for each function it appears in
donutmodule.c: At top level:
donutmodule.c:186:9: warning: initialization of ‘PyObject * (*)(PyObject *, PyObject *)’ {aka ‘struct _object * (*)(struct _object *, struct _object *)’} from incompatible pointer type ‘PyObject * (*)(PyObject *, PyObject *, PyObject *)’ {aka ‘struct _object * (*)(struct _object *, struct _object *, struct _object *)’} [-Wincompatible-pointer-types]
186 | Donut_Create, // C wrapper function
| ^~~~~~~~~~~~
donutmodule.c:186:9: note: (near initialization for ‘Donut_FunctionsTable[0].ml_meth’)
error: command '/usr/bin/gcc' failed with exit code 1
----------------------------------------
Rolling back uninstall of donut-shellcode
Moving to /home/someuser/.local/lib/python3.9/site-packages/donut.cpython-39-x86_64-linux-gnu.so
from /tmp/pip-uninstall-4a201t17/donut.cpython-39-x86_64-linux-gnu.so
Moving to /home/someuser/.local/lib/python3.9/site-packages/donut_shellcode-0.9.3.dist-info/
from /home/someuser/.local/lib/python3.9/site-packages/~onut_shellcode-0.9.3.dist-info
ERROR: Command errored out with exit status 1: /usr/bin/python3 -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-req-build-m2wearij/setup.py'"'"'; __file__='"'"'/tmp/pip-req-build-m2wearij/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-jobz3lsw/install-record.txt --single-version-externally-managed --user --prefix= --compile --install-headers /home/someuser/.local/include/python3.9/donut-shellcode Check the logs for full command output.
I used the donut binary for generating the shellcode with:
$ ./donut -a2 --input:dummy.exe
I used dev
as you requested.
Thanks! I'll look into this for the next version.
Awesome, let me know how I can help.
Since this commit: https://github.com/TheWover/donut/commit/0c1d3d09e73a25c65ca7381385a9570c4994239c Donut is not working properly when it comes to a x64 .NET EXE.
previous to that commit, is working fine (except the python module, which got fixed in a later commit here: https://github.com/TheWover/donut/commit/e71cde14a7e0c715eea047eb8c8f58d87777a619)
Hope this helps fixing the issue, Regards.