An interesting.Net Core collaborative development experience with C on Linux: Generating Linux standard user password strings

Recently, I encountered the problem of Linux user authentication in the process of the project. I thought about how to check the security of local Linux users, so I checked some data.

Password Storage for Linux

Looking at the data, we found that earlier Linux was stored in the / etc/password file, because the / etc/password permission control was weak and is no longer used, so we won't discuss this file here. For newer Linux distributions, the passwords are stored in the / etc/shadow file because / etc/shadow is administrator access and much more secure, so we can use commands toView files:

$ sudo cat /etc/shadow

Take my real user information (username inmount password 123456) for example:

......
inmount:$6$GTAgpXtw/YsqmaOJ$19/NZg8CVbQJB2BZBRFePGJj8f9Zme0s/VjmjdRjxJ9ItePem3h20tyGOk5Ytu5yIWio.0X.kwcsocfgIm2HY.:18211:0:99999:7:::
......

Among them, $6$GTAgpXtw/YsqmaOJ$19/NZg8CVbQJB2BZBRFePGJ8f9Zme0s/VjmjdRjxJ9ItePem3h20tyGOk5Ytu5yIWio.0X.kwcsocfgIm2HY.is the string encrypted by the user password, $6 represents a sha512-based encryption operation, $GTAgpXtw/YsqmaOJ is a random key string.

A simple attempt with.Net Core

After a simple observation of the string, using the sha512 and base64 attempts that come with.net core, the result of calculation differs greatly from the string queried, and it has once been embarrassed.

Password Functions in C Language

Since there are no ready-made tools in.Net Core, you lean back on the C language and a cryptographic function on Linux emerges:

char * crypt (const char *key,const char * salt);

Using this function, we can generate the password we need directly.

Explore dynamic link libraries on Linux

As a programmer who has been struggling in the.Net environment for a long time, and wants to call functions in the Linux C function library, it was a few years ago that he felt like he was crazy, but this.Net Core still gives us hope. After looking through the corefx library on Githud (that is, the framework source code of.Net Core), he found that he could call Linux so through DllImport.Dynamic Link Library.

So the idea came to mind that we would use C to compile so dynamic libraries - > call dynamic libraries with.Net Core to do what we want.

Making so dynamic link libraries

In this section, there are many online tutorials, so I won't say more. Paste the code:

library.h

#ifndef CRYPT_LIBRARY_H
#define CRYPT_LIBRARY_H

char *getpassword(const char *key, const char *slat);

#endif //CRYPT_LIBRARY_H

library.c

#include "library.h"
#include <crypt.h>

char *getpassword(const char *key, const char *slat) {
    return crypt(key, slat);
}

Compile the so library:

gcc library.c -fPIC -shared -o libcrypt.so -lcrypt

A standard dynamic connection library libcrypt.so file on Linux is obtained.

Call so file with.Net Core

Not to mention, just code:

using System;
using System.Runtime.InteropServices;

namespace App {

    class Program {

        [DllImport("libcrypt.so",
            EntryPoint = "getpassword",
            CallingConvention = CallingConvention.Cdecl,
            CharSet = CharSet.Ansi,
            SetLastError = true)]
        public static extern IntPtr getpassword(IntPtr key, IntPtr slat);

        [DllImport("libcrypt.so",
            EntryPoint = "getpassword",
            CallingConvention = CallingConvention.Cdecl,
            CharSet = CharSet.Ansi,
            SetLastError = true)]
        public static extern string getpassword(string key, string slat);

        static void Main(string[] args) {
            Console.WriteLine(getpassword("123456", "$6$GTAgpXtw/YsqmaOJ"));
            Console.WriteLine(Marshal.PtrToStringAnsi(getpassword(Marshal.StringToHGlobalAnsi("123456"), Marshal.StringToHGlobalAnsi("$6$GTAgpXtw/YsqmaOJ"))));
        }
    }
}

Depending on the characteristics of the character pointer in the original function definition, you can use either string or pointer type in the code. The result is the same. The following is the result of the run (you need to copy the libcrypt.so file to the execution directory and run it in Linux, running it in Windows will prompt errors):

$6$GTAgpXtw/YsqmaOJ$19/NZg8CVbQJB2BZBRFePGJj8f9Zme0s/VjmjdRjxJ9ItePem3h20tyGOk5Ytu5yIWio.0X.kwcsocfgIm2HY.
$6$GTAgpXtw/YsqmaOJ$19/NZg8CVbQJB2BZBRFePGJj8f9Zme0s/VjmjdRjxJ9ItePem3h20tyGOk5Ytu5yIWio.0X.kwcsocfgIm2HY.

Blow a wave.Net Core

Through this experience, I found that with C language.Net Core you can do almost anything on Linux. Before learning that.Net Core 3.0 only supports Windows windowing programming, I swept away the pity that GTK (as if Mono had something called GTK#which estimates the approximate principle) or WxWeight, re-encapsulating it in so form, I didn't find it difficult to develop windowing programs.Hard things (and of course the need for windowing on Linux is low), but in any case, there's growing confidence in the future of.Net Core.

Keywords: ASP.NET Linux C Windows sudo

Added by endersix on Mon, 11 Nov 2019 18:51:30 +0200