审计系统 (知识点)

 

 

 

 一. 简单开发:

yum install epel-release -y
yum install strace
chmod u+s `which strace`
yum install git

git clone https://github.com/317828332/LuffyAudit.git
git branch -a
git branch fangshaowei


python3 manage.py makemigrations
python3 manage.py migrate

python3 manage.py createsuperuser
python3 manage.py runserver 0.0.0.0:8000

数据库加数据

#openssh   

wget https://mirror.leaseweb.com/pub/OpenBSD/OpenSSH/portable/openssh-7.5p1.tar.gz
tar -zxvf openssh-7.5p1.tar.gz
cd openssh-7.5p1
修改源码

611    while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvxz:"
        "ACD:E:F:GI:J:KL:MNO:PQ:R:S:TVw:W:XYyZ:")) != -1) {

934  case 'Z':
        fprintf(stdout,"session_tag: %s\n" ,optarg);
        break;

./configure --prefix=/usr/local/openssh/
make
make install



#sshpass

tar -zxvf sshpass-1.06.tar.gz 
cd sshpass-1.06
./configure 
make
make install


317828332qq.com
View Code

 二. paramiko收集日志(vim table 等需要优化):

#把项目放在/usr/local/

#如果是普通用户安装的pip3 安装的各种包需要移动到 /usr/local/python3/lib/python3.6/site-packages目录下
    >>> sys.path
    /usr/local/python3/lib/python3.6/site-packages

#登陆堡垒机默认显示和执行脚本
    vim ~/.bashrc
        echo "-------welcome to oyoui system------"
        python3 /usr/local/LuffyAudit/audit_shell.py
        echo "-------bye..."
View Code
from django.contrib import admin
from audit import models
# Register your models here.

class AuditLogAdmin(admin.ModelAdmin):
    list_display = ['session','cmd','date']
    list_filter = ['date','session']

class SessionLogAdmin(admin.ModelAdmin):
    list_display = ['id','account','host_user_bind','start_date','end_date']
    list_filter = ['start_date','account']




admin.site.register(models.Host)
admin.site.register(models.HostUser)
admin.site.register(models.HostGroup)
admin.site.register(models.HostUserBind)
admin.site.register(models.Account)
admin.site.register(models.IDC)
admin.site.register(models.AuditLog,AuditLogAdmin)
admin.site.register(models.SessionLog,SessionLogAdmin)
audit/admin.py
#!/bin/bash


#for loop 30.get process id by  random tag 
#if got the process id , start strace command 

path=$0
echo $0
path_start=${path%audit/*}
path_end=log/ssh_audit_$2.log


for i  in $(seq 1 30);do
   #echo $i $1
   process_id=`ps -ef |grep $1 |grep -v sshpass |grep -v grep | grep -v 'session_tracker.sh' |awk '{print $2}'` # run cmd and set the result to variable cmd
   #echo "process:  $process_id"
   if [ ! -z "$process_id"  ];then
    echo 'start run strace....'
        #strace -fp $process_id -t -o $path_objlog/ssh_audit_$2.log;
        strace -fp $process_id -t -o $path_start$path_end;
        break;
   fi

   sleep 1 
done;

 
audit/session_tracker.sh
#!/usr/bin/env python

# Copyright (C) 2003-2007  Robey Pointer <robeypointer@gmail.com>
#
# This file is part of paramiko.
#
# Paramiko is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation; either version 2.1 of the License, or (at your option)
# any later version.
#
# Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Paramiko; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.


import base64
from binascii import hexlify
import getpass
import os
import select
import socket
import sys
import time
import traceback
from paramiko.py3compat import input
from audit import models
import paramiko

try:
    import interactive
except ImportError:
    from . import interactive


def manual_auth(t, username, password):
    t.auth_password(username, password)


def ssh_session(bind_host_user, user_obj):
    # now connect
    hostname = bind_host_user.host.ip_addr
    port = bind_host_user.host.port
    username = bind_host_user.host_user.username
    password = bind_host_user.host_user.password
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.connect((hostname, port))
    except Exception as e:
        print('*** Connect failed: ' + str(e))
        traceback.print_exc()
        sys.exit(1)

    try:
        t = paramiko.Transport(sock)
        try:
            t.start_client()
        except paramiko.SSHException:
            print('*** SSH negotiation failed.')
            sys.exit(1)

        try:
            keys = paramiko.util.load_host_keys(os.path.expanduser('~/.ssh/known_hosts'))
        except IOError:
            try:
                keys = paramiko.util.load_host_keys(os.path.expanduser('~/ssh/known_hosts'))
            except IOError:
                print('*** Unable to open host keys file')
                keys = {}

        # check server's host key -- this is important.
        key = t.get_remote_server_key()
        if hostname not in keys:
            print('*** WARNING: Unknown host key!')
        elif key.get_name() not in keys[hostname]:
            print('*** WARNING: Unknown host key!')
        elif keys[hostname][key.get_name()] != key:
            print('*** WARNING: Host key has changed!!!')
            sys.exit(1)
        else:
            print('*** Host key OK.')

        if not t.is_authenticated():
            manual_auth(t, username, password)
        if not t.is_authenticated():
            print('*** Authentication failed. :(')
            t.close()
            sys.exit(1)

        chan = t.open_session()
        chan.get_pty()  # terminal
        chan.invoke_shell()
        print('*** Here we go!\n')

        session_obj = models.SessionLog.objects.create(account=user_obj.account,
                                                       host_user_bind=bind_host_user)
        interactive.interactive_shell(chan, session_obj)
        chan.close()
        t.close()

    except Exception as e:
        print('*** Caught exception: ' + str(e.__class__) + ': ' + str(e))
        traceback.print_exc()
        try:
            t.close()
        except:
            pass
        sys.exit(1)
audit/ssh_interactive.py
__author__ = 'Administrator'
import subprocess,random,string
from django.contrib.auth import authenticate
from django.conf import settings 
from audit import models
from audit.backend import ssh_interactive



class UserShell(object):
    """用户登录堡垒机后的shell"""

    def __init__(self,sys_argv):
        self.sys_argv = sys_argv
        self.user = None

    def auth(self):

        count = 0
        while count < 3:
            username = input("username:").strip()
            password = input("password:").strip()
            user = authenticate(username=username,password=password)
            #None 代表认证不成功
            #user object ,认证对象 ,user.name
            if not user:
                count += 1
                print("Invalid username or password!")
            else:
                self.user = user
                return  True
        else:
            print("too many attempts.")

    def start(self):
        """启动交互程序"""

        if self.auth():
            #print(self.user.account.host_user_binds.all()) #select_related()
            while True:
                host_groups = self.user.account.host_groups.all()
                for index,group in enumerate(host_groups):
                    print("%s.\t%s[%s]"%(index,group,group.host_user_binds.count()))
                print("%s.\t未分组机器[%s]"%(len(host_groups),self.user.account.host_user_binds.count()))
                try:
                    choice = input("select group>:").strip()
                    if choice.isdigit():
                        choice = int(choice)
                        host_bind_list = None
                        if choice >=0 and choice < len(host_groups):
                            selected_group = host_groups[choice]
                            host_bind_list = selected_group.host_user_binds.all()
                        elif choice == len(host_groups): #选择的未分组机器
                            #selected_group = self.user.account.host_user_binds.all()
                            host_bind_list = self.user.account.host_user_binds.all()
                        if host_bind_list:
                            while True:
                                for index,host in enumerate(host_bind_list):
                                    print("%s.\t%s"%(index,host,))
                                choice2 = input("select host>:").strip()
                                if choice2.isdigit():
                                    choice2 = int(choice2)
                                    if choice2 >=0 and choice2 < len(host_bind_list):
                                        selected_host = host_bind_list[choice2]
                                        ssh_interactive.ssh_session(selected_host,self.user)



                                elif choice2 == 'b':
                                    break
                except KeyboardInterrupt as e:
                    pass
             
audit/user_interactive.py
# Copyright (C) 2003-2007  Robey Pointer <robeypointer@gmail.com>
#
# This file is part of paramiko.
#
# Paramiko is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation; either version 2.1 of the License, or (at your option)
# any later version.
#
# Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Paramiko; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.


import socket
import sys
from paramiko.py3compat import u
from audit import models
# windows does not have termios...
try:
    import termios
    import tty
    has_termios = True
except ImportError:
    has_termios = False


def interactive_shell(chan,session_obj):
    if has_termios: #
        posix_shell(chan,session_obj) #unix 通用协议标准
    else:
        windows_shell(chan)


def posix_shell(chan,session_obj):
    import select
    
    oldtty = termios.tcgetattr(sys.stdin)
    try:
        tty.setraw(sys.stdin.fileno())
        tty.setcbreak(sys.stdin.fileno())
        chan.settimeout(0.0)

        cmd = ''
        while True:
            r, w, e = select.select([chan, sys.stdin], [], [])
            if chan in r:#远程 由返回 命令结果
                try:
                    x = u(chan.recv(1024))
                    if len(x) == 0:
                        sys.stdout.write('\r\n*** EOF\r\n')
                        break
                    sys.stdout.write(x)
                    sys.stdout.flush()
                except socket.timeout:
                    pass
            if sys.stdin in r:
                x = sys.stdin.read(1)
                if len(x) == 0:
                    break
                if x == '\r':
                    models.AuditLog.objects.create(session=session_obj,cmd=cmd)
                    cmd = ''
                else:
                    cmd += x
                chan.send(x)

    finally:
        termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)

    
# thanks to Mike Looijmans for this code
def windows_shell(chan):
    import threading

    sys.stdout.write("Line-buffered terminal emulation. Press F6 or ^Z to send EOF.\r\n\r\n")
        
    def writeall(sock):
        while True:
            data = sock.recv(256)
            if not data:
                sys.stdout.write('\r\n*** EOF ***\r\n\r\n')
                sys.stdout.flush()
                break
            sys.stdout.write(data)
            sys.stdout.flush()
        
    writer = threading.Thread(target=writeall, args=(chan,))
    writer.start()
        
    try:
        while True:
            d = sys.stdin.read(1)
            if not d:
                break
            chan.send(d)
    except EOFError:
        # user hit ^Z or F6
        pass
audit/interactive.py

 

 

 

posted @ 2017-08-09 15:11  golangav  阅读(402)  评论(0编辑  收藏  举报