fanotify gremlin---hard no-return fail (under gdb) - fanotify

this is almost the same example as in the man page. everything is updated to recent versions. gcc is 4.9.2. gdb is 7.8.1. linux kernel is 3.17.6-1 (64bit). the install is a recent arch bootstrap. here is the whittled down case:
#define _GNU_SOURCE /* Needed to get O_LARGEFILE definition */
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <poll.h>
#include <sys/fanotify.h>
int main(int argc, char *argv[]) {
int fd;
fd = fanotify_init(FAN_CLOEXEC | FAN_CLASS_CONTENT | FAN_NONBLOCK, O_RDONLY | O_LARGEFILE);
if (fd == -1) exit(1);
fprintf(stderr, "calling fanotify_mark: fd=%d\n", fd);
if (fanotify_mark(fd, FAN_MARK_ADD | FAN_MARK_MOUNT, FAN_OPEN_PERM | FAN_CLOSE_WRITE, -1, "/") == -1) exit(2);
fprintf(stderr, "in gdb step through with 'n' for repeat.\n");
fprintf(stderr, " (and sometimes otherwise), a ^C works, but a ^Z and then ^C does not.\n");
}
most of the time, this works fine, but sometimes it does not. I think this is when fanotify_mark never returns. on trying to debug this, I found that I can(not) replicate this for debugging. if I use gdb and try to step through with 'n', fanotify_mark() never returns and is uninterruptible (^C, ^Z).
is this replicable elsewhere, or am I doing something wrong?
/iaw

this happens because FAN_OPEN_PERM requires another program to grant permission. this is almost verbatim from the example in the fanotify man page---and this makes it rather unfortunate, because whittling down the program can induce a hard OS block. so watch it.
my actual intent was to monitor file accesses. for this, one uses FAN_OPEN, not FAN_OPEN_PERM.

Related

Untar and load to LD_PRELOAD

assume that I have a tar.gz archive that contains 1 shared library.
My intention, is to untar it "on-the-fly" and the .so (that is extracted), put it on LD_PRELOAD and the run my code.
So, I made a script:
#!/bin/bash
myTarLib=$1
tar -zxf $myTarLib --to-command "export LD_PRELOAD="
./run_the_func
The execution of the run_the_exec didn't use the .so from the tar.
I have the impression that the "--to-command" option creates another shell; is it correct?
Do you have any suggestion on how I could do it? The important part, is that i don't want to have the .so on the disk.
Thanks in advance!
I found a solution to the problem...
The use of memfd_create
The memfd_create creates a file descriptor. Then this can be used to store any data in it.
The manpage is here.
In order to use it, you need to create a C-Wrapper that takes care of the untar (in my case). The code is:
#include <linux/memfd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
int main()
{
int fd = memfd_create("my_test", MFD_CLOEXEC);
if (fd == -1)
{
fprintf(stderr, "Creation failed\n");
}
char command_1[128];
char *path="hiddenLibrary/libmy_func_real.tgz";
//feel free to modify it to the path of your encrypted library
sprintf(command_1, "tar -zxf %s --to-stdout > /proc/%ld/fd/%d", path, (long) getpid(), fd);
printf("Running decrypt command\n");
system(command_1);
printf("The untar-ed library is located at:/proc/%ld/fd/%d\nOnce you finished type a number and hit enter\n",(long) getpid(), fd);
float temp;
scanf("%f", &temp);
return 0;
}
Now the idea is that the C code above, will run the untar and will store the result to the fd. Once you have finished using it, you simply hit a number and the C code exits.
During the exit, all the fds are released, so the untar-ed library is "gone".

How to use SYSVIPC in MSYS2?

I'm using package msys2/gcc in a 64-bit MSYS2 installation, under Windows 10 64-bit.
Sample C program:
#include <stdio.h>
#include <errno.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/stat.h>
int main(void)
{
uint64_t key = ftok("shm.exe", 8);
printf("%llx\n", key);
int r = shmget(key, 1024, S_IRUSR|S_IWUSR|IPC_CREAT);
if ( r == -1 )
printf("FAIL %d\n", errno);
else
printf("OK\n");
}
When I run this from the MSYS2 shell I get FAIL 88 which is ENOSYS indicating that shmget is not implemented.
Is it possible to make the call work? The full program also uses semget and semop.
From googling it seems there is a lot of source code in MSYS2 related to SYSV IPC but perhaps something needs to be enabled somewhere.

Open /dev/rdisk0 gives “Operation not permitted” error despite using sudo

On Mac OSX Mojave 10.14.6, the following simple code does not work anymore :
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
int main(int argc, char** argv)
{
int fd = open ("/dev/rdisk0", O_RDONLY);
if (fd == -1)
{
fprintf(stdout, "open(%s) error = %s\n", "/dev/rdisk0", strerror(errno));
fflush(stdout);
return 1;
}
return 0;
}
It gives :
open(/dev/rdisk0) error = Operation not permitted
This happens even when running the executable using sudo.
This code used to work under 10.13 and earlier versions.
Thinking this might be due to SIP, I gave the Terminal and the executable Full Disk Access but it didn't help.
Is there another way to get around this issue? How do I open /dev/rdisk0 now ?
Thanks in advance

gdb cracking && cryptanalysis CTF

hello guys i am playing CTF and i have to crack a program to get shell the source code is :
/*
* gcc ch21.c -lcrypt -o ch21
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <crypt.h>
#include <sys/types.h>
#include <unistd.h>
int main (int argc, char *argv[]) {
char pid[16];
char *args[] = { "/bin/bash", "-p", 0 };
snprintf(pid, sizeof(pid), "%i", getpid());
if (argc != 2)
return 0;
printf("%s=%s",argv[1], crypt(pid, "$1$awesome"));
if (strcmp(argv[1], crypt(pid, "$1$awesome")) == 0) {
printf("WIN!\n");
execve(args[0], &args[0], NULL);
} else {
printf("Fail... :/\n");
}
return 0;
}
now i debugged it with gdb as i understood from the source i have to enter proccessid (PID) during runtime to get successful shell with GDB-PEDA i have tried getpid during breakpoint but how to continue with proccess id with gdb only run command pass input to the program any help !
any notify !
Not sure if I understood your question correctly, but PID is limited in range and cycle when there limit is reached and the max is usually around 2^15. You could simply run a loop that would run through the potential PID to match the one that will be assigned for the process.
Something like this would do:
import os, crypt, subprocess
pid = os.getpid()+50 #safe buffer for things created after python script was started
print "Selected: ",pid
for i in range(32768):
sp = subprocess.Popen(['./ch21', crypt.crypt(str(pid), "$1$awesome")], stdout=subprocess.PIPE)
output = sp.stdout.readline()
if "Fail" not in output:
print output
break

incorrect argc in win32 (in addition, the arguments are ignored)

I was coding in win32, and my program actually works in debug mode in vs, however not in release mode and not outside vs.
int _tmain(int argc, _TCHAR* argv[])
{
//assert that there are 3 parameters.
assert(argc==4);
LPCTSTR inputPath = argv[1];
LPCTSTR sharedName = argv[2];
LPCTSTR logPath = argv[3];
sometimes argc is not correct (over 300000, while it should be 4), and sometimes the
LPCTSTR sharedName = argv[2];
line is just ignored!
when debugging this program in release mode, it jumps over it, and when hoovering above the variable name nothing happens.
When right-clicking a variable and choosing Add Watch, I get the error logPath CXX0017: Error: symbol "logPath" not found
of course, I have set the command arguments in vs to be "a b c" (without the quotes)
What could it be?
running the simplified program:
// test.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "stdafx.h"
#include <windows.h>
#include <assert.h>
#include "conio.h"
int _tmain(int argc, _TCHAR* argv[])
{
assert(argc==4);
LPCTSTR inputPath = argv[1];
LPCTSTR sharedName = argv[2];
LPCTSTR logPath = argv[3];
_getch();
}
yields the same result. the debugger just jumps to the getch line, and if I try to add watch, I get logPath CXX0017: Error: symbol "logPath" not found
inputPath CXX0017: Error: symbol "inputPath" not found
sharedName CXX0017: Error: symbol "sharedName" not found
when debugging this program in release mode, it jumps over it, and when hoovering above the variable name nothing happens. When right-clicking a variable and choosing Add Watch, I get the error logPath CXX0017: Error: symbol "logPath" not found
These symptoms make sense. "Release" mode tells the compiler to turn optimizations on, and since you never use the variables that you declare, the compiler helpfully optimizes them out altogether. There's no point in going through the motions of creating and assigning something if you'll never use it again.
That's why it's telling you that the symbol is not found, because its definition was optimized out.
On the other hand, "Debug" mode it disables optimizations. Thus, it goes through the motions of creating these variables and assigning values to them, even though you may never use them. That's the whole point of debug mode—so you can debug your application without interference from the optimizing behavior of the compiler, even when it's not completely written yet.
If you're desperate to make it work like you expect with optimizations enabled (i.e., in "Release" mode), then you can simply use the values of the variables you assign. That will prevent the compiler from optimizing them out. For example, you can simply output the strings to the debugger:
#include "stdafx.h"
#include <windows.h>
#include <assert.h>
#include <conio.h>
int _tmain(int argc, _TCHAR* argv[])
{
assert(argc==4);
LPCTSTR inputPath = argv[1];
LPCTSTR sharedName = argv[2];
LPCTSTR logPath = argv[3];
OutputDebugString(inputPath);
OutputDebugString(sharedName);
OutputDebugString(logPath);
_getch();
}

Resources