├── .gitignore
├── LICENSE
├── README.md
├── Sign-Sacker.py
├── favicon.ico
├── ico_sacker.exe
├── info_sacker.exe
└── requirements.txt
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | share/python-wheels/
24 | *.egg-info/
25 | .installed.cfg
26 | *.egg
27 | MANIFEST
28 |
29 | # PyInstaller
30 | # Usually these files are written by a python script from a template
31 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
32 | *.manifest
33 | *.spec
34 |
35 | # Installer logs
36 | pip-log.txt
37 | pip-delete-this-directory.txt
38 |
39 | # Unit test / coverage reports
40 | htmlcov/
41 | .tox/
42 | .nox/
43 | .coverage
44 | .coverage.*
45 | .cache
46 | nosetests.xml
47 | coverage.xml
48 | *.cover
49 | *.py,cover
50 | .hypothesis/
51 | .pytest_cache/
52 | cover/
53 |
54 | # Translations
55 | *.mo
56 | *.pot
57 |
58 | # Django stuff:
59 | *.log
60 | local_settings.py
61 | db.sqlite3
62 | db.sqlite3-journal
63 |
64 | # Flask stuff:
65 | instance/
66 | .webassets-cache
67 |
68 | # Scrapy stuff:
69 | .scrapy
70 |
71 | # Sphinx documentation
72 | docs/_build/
73 |
74 | # PyBuilder
75 | .pybuilder/
76 | target/
77 |
78 | # Jupyter Notebook
79 | .ipynb_checkpoints
80 |
81 | # IPython
82 | profile_default/
83 | ipython_config.py
84 |
85 | # pyenv
86 | # For a library or package, you might want to ignore these files since the code is
87 | # intended to run in multiple environments; otherwise, check them in:
88 | # .python-version
89 |
90 | # pipenv
91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
94 | # install all needed dependencies.
95 | #Pipfile.lock
96 |
97 | # poetry
98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
99 | # This is especially recommended for binary packages to ensure reproducibility, and is more
100 | # commonly ignored for libraries.
101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
102 | #poetry.lock
103 |
104 | # pdm
105 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
106 | #pdm.lock
107 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
108 | # in version control.
109 | # https://pdm.fming.dev/#use-with-ide
110 | .pdm.toml
111 |
112 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
113 | __pypackages__/
114 |
115 | # Celery stuff
116 | celerybeat-schedule
117 | celerybeat.pid
118 |
119 | # SageMath parsed files
120 | *.sage.py
121 |
122 | # Environments
123 | .env
124 | .venv
125 | env/
126 | venv/
127 | ENV/
128 | env.bak/
129 | venv.bak/
130 |
131 | # Spyder project settings
132 | .spyderproject
133 | .spyproject
134 |
135 | # Rope project settings
136 | .ropeproject
137 |
138 | # mkdocs documentation
139 | /site
140 |
141 | # mypy
142 | .mypy_cache/
143 | .dmypy.json
144 | dmypy.json
145 |
146 | # Pyre type checker
147 | .pyre/
148 |
149 | # pytype static type analyzer
150 | .pytype/
151 |
152 | # Cython debug symbols
153 | cython_debug/
154 |
155 | # PyCharm
156 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
157 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
158 | # and can be added to the global gitignore or merged into this file. For a more nuclear
159 | # option (not recommended) you can uncomment the following to ignore the entire idea folder.
160 | #.idea/
161 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 langsasec
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | # Sign-Sacker (签名掠夺者) - 2.0
9 |
10 | ## 介绍
11 |
12 | Sign-Sacker(签名掠夺者):一款数字签名复制器,可将其他官方exe中数字签名,图标,详细信息复制到没有签名的exe中,作为免杀,权限维持,伪装的一种小手段。
13 |
14 | ## 2024-1-4 项目停更
15 |
16 | 1. 微调了下代码,只允许了exe,dll文件
17 | 2. 项目停更,江湖再见
18 |
19 | ## 更新 2.0
20 |
21 | 分别导入含有签名和需要签名的文件,点击生成即可,玩免杀的可能会用到。
22 |
23 | 新增功能:
24 |
25 | 1. 掠夺高清图标,完美复刻。
26 | 2. 掠夺exe详细信息,以假乱真。
27 |
28 | 
29 |
30 | ## 效果对比
31 |
32 | ### 图标对比:
33 |
34 | 
35 |
36 | 
37 |
38 | ### 数字签名对比:
39 |
40 | 
41 |
42 | ### 详细信息对比
43 | 唯一的遗憾是语言暂未更改,文件版本号是由于飞书实际和显示有差别,大多数是一致的,因此我未做细微调整。
44 | 
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/Sign-Sacker.py:
--------------------------------------------------------------------------------
1 | import io
2 | import struct
3 | import subprocess
4 |
5 | from PyQt5.QtGui import QIcon
6 | from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QLineEdit, QPushButton, QFileDialog, QVBoxLayout, \
7 | QWidget, QMessageBox, QCheckBox
8 | import sys
9 | import os
10 | import shutil
11 | from PyQt5.QtWidgets import QDesktopWidget
12 |
13 |
14 |
15 | class SignSacker(QMainWindow):
16 | def __init__(self):
17 | super().__init__()
18 | self.setWindowTitle("Sign-Sacker(签名掠夺者) By 浪飒 (关注浪飒sec公众号)")
19 | self.setWindowIcon(QIcon('favicon.ico')) # 设置窗口图标
20 | self.resize(700, 400)
21 |
22 | # 设置窗口居中显示
23 | screen = QDesktopWidget().screenGeometry()
24 | window_size = self.geometry()
25 | x = int((screen.width() - window_size.width()) / 2)
26 | y = int((screen.height() - window_size.height()) / 2)
27 | self.move(x, y)
28 |
29 | widget = QWidget(self)
30 | layout = QVBoxLayout()
31 | widget.setLayout(layout)
32 | self.setCentralWidget(widget)
33 |
34 | self.file1_label = QLabel("受害者:", self)
35 | layout.addWidget(self.file1_label)
36 |
37 | self.file1_entry = QLineEdit(self)
38 | layout.addWidget(self.file1_entry)
39 |
40 | self.choose_button1 = QPushButton("选择含有签名的文件", self)
41 | layout.addWidget(self.choose_button1)
42 | self.choose_button1.clicked.connect(self.choose_file1)
43 |
44 | self.file2_label = QLabel("掠夺者:", self)
45 | layout.addWidget(self.file2_label)
46 |
47 | self.file2_entry = QLineEdit(self)
48 | layout.addWidget(self.file2_entry)
49 |
50 | self.choose_button2 = QPushButton("选择需要伪造签名的文件", self)
51 | layout.addWidget(self.choose_button2)
52 | self.choose_button2.clicked.connect(self.choose_file2)
53 |
54 | self.output_label = QLabel("生成文件名:", self)
55 | layout.addWidget(self.output_label)
56 |
57 | self.output_entry = QLineEdit(self)
58 | layout.addWidget(self.output_entry)
59 |
60 | self.icon_checkbox = QCheckBox("掠夺受害者高清图标(默认保存在'文件名_ico'路径下)", self)
61 | self.details_checkbox = QCheckBox("掠夺受害者所有详细信息(右键属性->详细信息。包括文件说明,文件版本等)", self)
62 | layout.addWidget(self.icon_checkbox)
63 | layout.addWidget(self.details_checkbox)
64 | self.output_label= QLabel("------------------------------------------------------------------------------------", self)
65 | layout.addWidget(self.output_label)
66 | self.output_label = QLabel("温馨提示:", self)
67 | layout.addWidget(self.output_label)
68 | self.output_label= QLabel("1.掠夺后语言默认为英语(美国)。", self)
69 | layout.addWidget(self.output_label)
70 | self.output_label= QLabel("2.掠夺后图标若无变化请粘贴到新的文件夹刷新即可。", self)
71 | layout.addWidget(self.output_label)
72 | self.output_label= QLabel("3.建议对掠夺者进行备份再执行程序。", self)
73 | layout.addWidget(self.output_label)
74 | self.output_label= QLabel("------------------------------------------------------------------------------------", self)
75 | layout.addWidget(self.output_label)
76 |
77 | self.process_button = QPushButton("生成文件", self)
78 | layout.addWidget(self.process_button)
79 | self.process_button.clicked.connect(self.process_files)
80 |
81 |
82 |
83 | self.setStyleSheet("""
84 | QLabel {
85 | font-size: 16px;
86 | color: #333;
87 | }
88 | QLineEdit, QPushButton {
89 | font-size: 14px;
90 | height: 30px;
91 | }
92 | QPushButton {
93 | background-color: #4CAF50;
94 | border: none;
95 | color: white;
96 | padding: 6px 12px;
97 | text-align: center;
98 | text-decoration: none;
99 | font-size: 14px;
100 | margin: 4px;
101 |
102 | border-radius: 4px;
103 | }
104 | QPushButton:hover {
105 | background-color: #45a049;
106 | }
107 | """)
108 |
109 |
110 | def choose_file1(self):
111 | file_name, _ = QFileDialog.getOpenFileName(self, "选择文件1", "", "Executable Files (*.exe *.dll)")
112 | if file_name:
113 | self.file1_entry.setText(file_name)
114 |
115 | def choose_file2(self):
116 | file_name, _ = QFileDialog.getOpenFileName(self, "选择文件2", "", "Executable Files (*.exe *.dll)")
117 | if file_name:
118 | self.file2_entry.setText(file_name)
119 | # 自动填充生成文件名的文本框
120 | base_name = os.path.basename(file_name)
121 | extension = os.path.splitext(base_name)[1]
122 | if extension.lower() == ".dll":
123 | output_file = os.path.splitext(base_name)[0] + "-Signed.dll"
124 | else:
125 | output_file = os.path.splitext(base_name)[0] + "-Signed.exe"
126 | self.output_entry.setText(os.getcwd().replace('\\','/')+'/'+output_file)
127 |
128 | def process_files(self):
129 | file1_path = self.file1_entry.text()
130 | file2_path = self.file2_entry.text()
131 | output_file = self.output_entry.text()
132 | # 验证文件的有效性
133 | if not os.path.exists(file1_path) or not os.path.isfile(file1_path):
134 | self.show_message_box("错误", "文件1无效!")
135 | return
136 | if not os.path.exists(file2_path) or not os.path.isfile(file2_path):
137 | self.show_message_box("错误", "文件2无效!")
138 | return
139 | icon = self.icon_checkbox.isChecked()
140 | version_info = self.details_checkbox.isChecked()
141 | if version_info:
142 | info_sacker(file1_path, file2_path)
143 | if icon:
144 | ico_sacker(file1_path,file2_path)
145 | writeCert(copyCert(file1_path), file2_path, output_file)
146 | message = f"签名已写入:{output_file}"
147 |
148 | self.show_message_box("生成文件", message)
149 |
150 | def show_message_box(self, title, message):
151 | msg_box = QMessageBox()
152 | msg_box.setWindowTitle(title)
153 | msg_box.setText(message)
154 | msg_box.exec_()
155 |
156 |
157 | # 获取可执行文件的一些信息,包括PE头中的各个字段的数值。
158 | def gather_file_info_win(binary):
159 | """
160 | Borrowed from BDF...
161 | I could just skip to certLOC... *shrug*
162 | """
163 | flItms = {}
164 | binary = open(binary, 'rb')
165 | binary.seek(int('3C', 16))
166 | flItms['buffer'] = 0
167 | flItms['JMPtoCodeAddress'] = 0
168 | flItms['dis_frm_pehdrs_sectble'] = 248
169 | flItms['pe_header_location'] = struct.unpack('