I already know that I can read the password structure (getpwnam etc.) but how can I alter the specific password. Do I have to lock the master.passwd and modify it directly or better make a copy from master.passwd modify this and make a file move after correct modifications?
At last, I don't want to make a system(usermod ...) because that invokes the shell and should be the last solution!
Thanks in advance
In C for Unix like Solaris or AIX , you can either :
Use PAM API if available. Here are some articles about it on Solaris.
Add a new password with putpwent
Change existing password with getpwent, crypt your new password and finish with endpwent
You'll see here a complete sample program to change a pasword for unix in C using putpwent & getpwent. AIX documentation seems to confirm it should also works on their OS.
Related
This question may be a little off topic. But I was wondering if there was a way for me to look at the descriptions of C functions using vim or neovim. Is it possible to look at their documentations by doing something like :help? This would really be helpful since I wouldn't need to lookup to my browser everytime.
I am unclear about these things:
Can :help be my friend here ?
Can I use LSPs to do something like this ?
I am using latest Neovim inside Ubunutu 20.04 in WSL. Is this helpful somehow ?
By pressing K, the keyword under the cursor is looked up using a configured keyword lookup program, the default being man. This works pretty much out of the box for the C standard library.
For C++, you might want to look at something like cppman.
Well yes, you can get the description of C functions by using a LSP (language server plugin)! Here is an image of me using clangd as my LSP:
You'd "just" need to install the LSP and start it. I don't know how familiar you're with neovim, but just in case if you don't know how to install a plugin or to be more specifique: If you don't know how you can install a LSP server, then you can do the following:
There're plenty videos how to set up a LSP-Server for your language. Here's an example.
If you don't want to set up on your own, you can pick up one of the preconfigured neovim setups (some of my friends are recommending lunarvim)
But yeah, that's it. If you have any further questions feel free to ask them in the comments.
Happy vimming c(^-^)c
Let's explain how "K" command works in more detail.
You can run external commands by prefixing them with :! command. So running man tool is as easy as
:!man <C-R><C-W>
Here <C-R><C-W> is a special key combination used to put word under cursor from text buffer down to command line.
Same for showing Vim's built-in help page
:help <C-R><C-W>
As it feels tedious to type that, Vim also defines K Normal mode command that does pretty much the same thing. Except the tool name is taken from value of an option named "keywordprg".
So doing set keywordprg=man (default for *nix systems) makes K to invoke !man tool; while set keywordprg=:help is for bultin help.
Also, the option :h 'keywordprg' is made global or local-to-buffer, so any Vim buffer is able to overwrite global setting. For example, this is already done by standard runtime for "vim" and "help" buffers, so they call ":help" instead of "man".
The problem with :!man command is that it shows "black console". It'd be nice if we could capture man's output and open it inside Vim just like a builtin help page. Then we could also apply some pretty highlighting, assign key macros and all such. This is a pretty common trick and it is already done by a standard plugin shipped with Vim/Neovim.
A command that the plugin provides is called :Man, so you can open :Man man instead of :!man man, for example. The plugin is preactivated in Neovim; for Vim you still need to source one file manually. So to make use of this plugin you'll need something like this
set keywordprg=:Man
if !has("nvim")
source $VIMRUNTIME/ftplugin/man.vim
endif
The previous answer recommending cppman is the way to go. There is no need to install a bulky language server just for the purpose of having the hover functionality. However, make sure you're caching the man pages via cppman -c. Otherwise, there will be a noticeable delay since cppman is fetching the page from cppreference.com on the fly.
If you like popups for displaying documentation, convert the uncompressed man pages (groff -t -e -mandoc -Tascii <man-page> | col -bx), and set keywordprg to your own wrapper to search for keywords according to your needs.
I'm trying to remove a file in a C program, but when I use the remove() function it completely removes the file and not sending it to the trash. How can I remove a file to trash?
Thanks in advance!
On Mac OS, you should use the recycleURLs:completionHandler: method in NSWorkspace.
Almost every operating system provides an API to perform a soft delete by moving files to the trash. Unfortunately there is no unified specification on how a trash / recycling bin should work. On Windows you can use IFileOperation, macOS has the NSFileManager and on Linux and BSD you either use a tool that implements the FreeDesktop.org trash specification such as gio trash (GNOME), kioclient5 move (KDE), trash-cli or implement your own.
Another solution is using a cross-platform library that allows to move files and directories to the trash / recycling bin like libtrashcan. This simplifies development because you only use a single function call without worrying about platform specific details.
For Windows See SHFileOperation with FOF_ALLOWUNDO.
http://msdn.microsoft.com/en-us/library/bb762164.aspx
On Mac OS X, you have to call FSMoveObjectToTrashSync (or its async friend) from CoreServices.
In linux i will do...
system("mv your_file.txt /home/username/.local/share/Trash/");
If you are on Windows try this.
Open a Command Prompt (DOS windows) and type
cd \$RECYCLE.BIN
dir \a
and you will get a list of all the trashes of all the users in your computer.
In your program move the file to the proper trash.
I've been reading about IFS exploitation and LD_PRELOAD Privilege escalation by overriding functions. Although these are two completely different questions, I've decided to post them together and hope that isn't a problem. Though both of these are very old, I've been told that they can both still be used for privilege escalation and I would love to look into that. However, I've ran into some problems.
So, let's begin by making the SUID file, /tmp/suid.
#include <unistd.h>
int main() {
system("/bin/date");
}
This calls /bin/date. The idea is that we can change the internal field separator and deceive the file into running something else with the privileges that it currently holds. This can be done (or can it?) by making a new file called bin contain the malicious code that the attacker put in a custom location. Then we change the $PATH variable and make it so that locations are first searched inside our custom path, where our malicious fake binary is located. Then by changing the internal field separator to '/', instead of running /bin/date the program will run /tmp/fakepath/bin with argument date, which can potentially trigger privilege escalation.
When I attempt the method described dankalia.com, it fails. /bin/date gets executed instead. If I just type bin date into the console the malicious binary does get started, but it doesn't when it's being invoked through /tmp/suid.
I thought that the vulnerability is patched and that it simply ignores the IFS variable, but then a post on stackoverflow got me interested. (C: IFS System() Vulnerability). Can anyone confirm to me if this works or not, and what I am doing wrong? Thanks.
As for the LD_PRELOAD, I'll keep it rather simple.
define _GNU_SOURCE
#include <stdio.h>
int puts(const char *str) {
printf("lel");
}
Use the following command line to compile:
gcc –Wall –fPIC –shared –o puts.so puts.c –ldl
Then, override the function puts with preload tricks:
LD_PRELOAD=./puts.so ./vuln_program_that_uses_puts
This works quite well. However, when dealing with a SUID file and when we're talking about privilege escalation, this ain't happening. LD_PRELOAD doesn't work well with SUID files and for a good reason. I've been told that "you can get it to work but that it's hard". Ideas?
Thanks in advance, and sorry for the long questions.
I've been told that "you can get it to work but that it's hard". Ideas?
The operating system is wise to these sorts of tricks, and most are remediated now. Te general idea is setuid, sudo and friends don't use an unprivileged user's environment.
The following offers more reading:
suid-binary vulnerabilities
Breaking the links: Exploiting the linker
If all you want is a setuid binary to break into the system:
shutdown the computer
mount the hard drive
rename ls (or other program like date)
copy sudo to ls (or other program like date)
unmount and reboot
Say I have a command line C program which is currently executing, and I want to read a file or execute another binary in the same directory - how can I find out what directory that is?
Note that I'm not looking for the current working directory. The user may have invoked my original program in any of the following ways (and possibly others I don't know about).
../../program
/home/matt/program
PATH=$PATH:/home/matt program
Ideally I'm looking for something which will work on a unix system and windows via MinGW.
http://c-faq.com/osdep/exepath.html
According to the C FAQ it can't be done reliably
Finding current executable's path without /proc/self/exe
Concat getcwd() and dirname(argv[0])
In C programming how do you get the current user and the current working directory.
I'm trying to print something like this:
asmith#mycomputer:~/Desktop/testProgram:$
(user) (computerName) (current directory)
I have the following code, but the username is showing as NULL. Any ideas what I'm doing wrong?
void prompt()
{
printf("%s#shell:~%s$", getenv("LOGNAME"), getcwd(currentDirectory, 1024));
}
Aside from the fact that you should be using the environment variable USER instead of LOGNAME, you shouldn't be using environment variables for this in the first place. You can get the current user ID with getuid(2) and the current effective user ID with geteuid(2), and then use getpwuid(3) to get the user name from the user ID from the passwd file:
struct passwd *p = getpwuid(getuid()); // Check for NULL!
printf("User name: %s\n", p->pw_name);
To get the current computer name, use gethostname(2):
char hostname[HOST_NAME_MAX+1];
gethostname(hostname, sizeof(hostname)); // Check the return value!
printf("Host name: %s\n", hostname);
On unix-like systems use the function getlogin from unistd.h.
This is not a C question but is more like a UNIX question. There is no portable way of getting the username and current working directory in C language.
However, by viewing your example, I can tell you are trying to print the current UNIX user name and current working directory.
If you need current working directory in UNIX check getcwd function.
If you need current user name you can either call a separate whoami process within your C program, or check the getuid function call.
This is going to be platform specific, as there is no intrinsic way in the C programming language to do this.
It looks like you're on a Unix-based system, so you'll probably want to get the environment variable USER which is usually the logon name.
you can also use
#include<stdlib.h>
main()
{
system("echo %username%"); /* This is for Windows
* instead use system("echo $USER"); for UNIX
*/
}
Note that this will work on a unix system only.
may be LOGNAME was not set as your environment variable
you can see the environment variables using the printenv command
printf("%s#shell:%s$", getenv("USER"),getenv("PWD"))
Also does the job.
but as mentioned you shouldn't rely on environment variables, rather use the standard c functions.If you really want to use them, first make sure it is set.