Anda dapat dengan mudah mengekstrak kata sandi terenkripsi dengan awk. Anda kemudian perlu mengekstrak awalan $algorithm$salt$
(dengan anggapan bahwa sistem ini tidak menggunakan DES tradisional, yang sangat tidak digunakan lagi karena dapat menjadi kasar sekarang ini).
correct=$(</etc/shadow awk -v user=bob -F : 'user == $1 {print $2}')
prefix=${correct%"${correct#\$*\$*\$}"}
Untuk pemeriksaan kata sandi, fungsi C yang mendasarinya adalah crypt
, tetapi tidak ada perintah shell standar untuk mengaksesnya.
Pada baris perintah, Anda dapat menggunakan Perl satu-liner untuk memanggil crypt
kata sandi.
supplied=$(echo "$password" |
perl -e '$_ = <STDIN>; chomp; print crypt($_, $ARGV[0])' "$prefix")
if [ "$supplied" = "$correct" ]; then …
Karena ini tidak dapat dilakukan dalam alat shell murni, jika Anda memiliki Perl tersedia, Anda mungkin juga melakukan semuanya di Perl. (Atau Python, Ruby, ... apa pun yang Anda miliki yang dapat memanggil crypt
fungsi.) Peringatan, kode yang belum diuji.
#!/usr/bin/env perl
use warnings;
use strict;
my @pwent = getpwnam($ARGV[0]);
if (!@pwent) {die "Invalid username: $ARGV[0]\n";}
my $supplied = <STDIN>;
chomp($supplied);
if (crypt($supplied, $pwent[1]) eq $pwent[1]) {
exit(0);
} else {
print STDERR "Invalid password for $ARGV[0]\n";
exit(1);
}
Pada sistem tertanam tanpa Perl, saya akan menggunakan program C kecil yang berdedikasi. Peringatan, mengetik langsung ke browser, saya bahkan belum mencoba untuk mengkompilasi. Ini dimaksudkan untuk menggambarkan langkah-langkah yang diperlukan, bukan sebagai implementasi yang kuat!
/* Usage: echo password | check_password username */
#include <stdio.h>
#include <stdlib.h>
#include <pwd.h>
#include <shadow.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
char password[100];
struct spwd shadow_entry;
char *p, *correct, *supplied, *salt;
if (argc < 2) return 2;
/* Read the password from stdin */
p = fgets(password, sizeof(password), stdin);
if (p == NULL) return 2;
*p = 0;
/* Read the correct hash from the shadow entry */
shadow_entry = getspnam(username);
if (shadow_entry == NULL) return 1;
correct = shadow_entry->sp_pwdp;
/* Extract the salt. Remember to free the memory. */
salt = strdup(correct);
if (salt == NULL) return 2;
p = strchr(salt + 1, '$');
if (p == NULL) return 2;
p = strchr(p + 1, '$');
if (p == NULL) return 2;
p[1] = 0;
/*Encrypt the supplied password with the salt and compare the results*/
supplied = crypt(password, salt);
if (supplied == NULL) return 2;
return !!strcmp(supplied, correct);
}
Pendekatan yang berbeda adalah dengan menggunakan program yang ada seperti su
atau login
. Bahkan, jika Anda bisa, itu akan ideal untuk mengatur aplikasi web untuk melakukan apa pun yang dibutuhkan melalui su -c somecommand username
. Kesulitan di sini adalah untuk memberi makan kata sandi su
; ini membutuhkan terminal. Alat yang biasa untuk meniru terminal adalah yang diharapkan , tetapi itu adalah ketergantungan besar untuk sistem embedded. Selain itu, saat su
berada di BusyBox, sering kali dihilangkan karena banyak penggunaannya membutuhkan biner BusyBox untuk menjadi setuid root. Namun, jika Anda bisa melakukannya, ini adalah pendekatan yang paling kuat dari sudut pandang keamanan.