go学习-001

warning: 这篇文章距离上次修改已过478天,其中的内容可能已经有所变动。
沙箱是一个比较吊毛和比较讨人厌的东西(吐槽完毕)。是用于隔离正在运行的程序的安全机制。这个程序代码可能来自未经验证的或不受信任的第三方、供应商、用户或网站,而不会危害主机或操作系统。
这边搜集一些反沙箱调试的思路,配合写出一些代码

基于go语言

1、操作系统语言检测

沙箱大部分都是国外的英文,所以根据首选项操作系统来判断操作系统语言是不是中文来判断(但是)。使用golang.org/x/sys/windows包。

代码如下:

package src

import (
	"fmt"
	"golang.org/x/sys/windows"
	"os"
)

func CheckLanguage() { // 首字母大写,成为导出的函数
	a, err := windows.GetUserPreferredUILanguages(windows.MUI_LANGUAGE_NAME)
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(1)
	}
	if a[0] != "zh-CN" {
		fmt.Println("英文环境")
		os.Exit(1)
	} else {
		fmt.Println("中文环境")
	}

}

2、操作系统信息

执行wmic命令,返回操作系统信息,根据关键字来判断,也是略简单粗暴。但是这里会被沙箱直接检测到所以我们这边要做一下他的一些免杀,需要更改一些他的命令

package src

import (
	"os/exec"
	"strings"
)

func Check_Virtual() (bool, error) {
	// 检查计算机模型信息
	cmd := exec.Command("cmd", "/C", "wmic path Win32_ComputerSystem get Model")
	stdout, err := cmd.Output()
	if err != nil {
		return false, err
	}
	model := strings.ToLower(string(stdout))

	// 检查BIOS信息
	cmd = exec.Command("cmd", "/C", "wmic bios get serialnumber")
	biosOutput, err := cmd.Output()
	if err != nil {
		return false, err
	}
	bios := strings.ToLower(string(biosOutput))

	// 检查硬盘驱动器信息
	cmd = exec.Command("cmd", "/C", "wmic diskdrive get model")
	diskOutput, err := cmd.Output()
	if err != nil {
		return false, err
	}
	disk := strings.ToLower(string(diskOutput))

	// 增加更多判断条件,如检测常见虚拟机厂商的标识
	if strings.Contains(model, "virtual") || strings.Contains(model, "vmware") || strings.Contains(model, "kvm") || strings.Contains(model, "virtualbox") ||
		strings.Contains(bios, "virtual") || strings.Contains(bios, "vmware") || strings.Contains(disk, "vbox") || strings.Contains(disk, "virtual") {
		return true, nil
	}
	return false, nil
}

3、检测系统文件

根据虚拟机或沙箱可能存在的一些文件,来进行判断。

func PathExists(path string) (bool, error) { 
 _, err := os.Stat(path)
 if err == nil {
  return true, nil
 }
 if os.IsNotExist(err) {
  return false, nil
 }
 return false, err
}
func fack(path string) { 
 b, _ := PathExists(path)
 if b {
  os.Exit(1) 
 }
}
func check_file() {
 fack("C:\windows\System32\Drivers\Vmmouse.sys")
 fack("C:\windows\System32\Drivers\vmtray.dll")
 fack("C:\windows\System32\Drivers\VMToolsHook.dll")
 fack("C:\windows\System32\Drivers\vmmousever.dll")
 fack("C:\windows\System32\Drivers\vmhgfs.dll")
 fack("C:\windows\System32\Drivers\vmGuestLib.dll")
 fack("C:\windows\System32\Drivers\VBoxMouse.sys")
 fack("C:\windows\System32\Drivers\VBoxGuest.sys")
 fack("C:\windows\System32\Drivers\VBoxSF.sys")
 fack("C:\windows\System32\Drivers\VBoxVideo.sys")
 fack("C:\windows\System32\vboxdisp.dll")
 fack("C:\windows\System32\vboxhook.dll")
 fack("C:\windows\System32\vboxoglerrorspu.dll")
 fack("C:\windows\System32\vboxoglpassthroughspu.dll")
 fack("C:\windows\System32\vboxservice.exe")
 fack("C:\windows\System32\vboxtray.exe")
 fack("C:\windows\System32\VBoxControl.exe")
}

4、延迟运行

我们这里就当一次老六,因为大部分的检测运行资源有限,可以延迟等一会再进行真实操作。(杀敌一千自损八百)
func timeSleep() (int, error) {
 startTime := time.Now()
 time.Sleep(5 * time.Second)
 endTime := time.Now()
 sleepTime := endTime.Sub(startTime)
 if sleepTime >= time.Duration(5*time.Second) {
  return 1, nil
 } else {
  return 0, nil
 }
}

5、开机时间检测

因为沙箱检测完都会还原或者充值系统,因此可以通过检测开机事件来判断是否为真实的运行情况。
func bootTime() (int, error) {
 var kernel = syscall.NewLazyDLL("Kernel32.dll")
 GetTickCount := kernel.NewProc("GetTickCount")
 r, _, _ := GetTickCount.Call()
 if r == 0 {
  return 0, nil
 }
 ms := time.Duration(r * 1000 * 1000)
 tm := time.Duration(30 * time.Minute)
 if ms < tm {
  return 0, nil
 } else {
  return 1, nil
 }
}

6、检测物理内存大小

就跟前面赌沙箱耗费资源多少一样,这里笃定大部分物理机内存都在4gb以上,通过判断大于4来认定为是物理机。
func physicalMemory() (int, error) {
 var mod = syscall.NewLazyDLL("kernel32.dll")
 var proc = mod.NewProc("GetPhysicallyInstalledSystemMemory")
 var mem uint64
 proc.Call(uintptr(unsafe.Pointer(&mem)))
 mem = mem / 1048576
 if mem < 4 {
  return 0, nil
 }
 return 1, nil
}

7、检测cpu数目

跟前面一样,认定cpu数目大于4
func numberOfCPU() (int, error) {
 a := runtime.NumCPU()
 if a < 4 {
  return 0, nil
 } else {
  return 1, nil
 }
}

8、通过检测临时文件数目

正常的物理机中,用户日常的使用导致其肯定会再临时文件夹中存在一定数量的临时文件,因此临时文件夹内的文件数量可以被用来判定运行环境是否为沙箱。
func numberOfTempFiles() (int, error) {
 conn := os.Getenv("temp")
 var k int
 if conn == "" {
  return 0, nil
 } else {
  local_dir := conn
  err := filepath.Walk(local_dir, func(filename string, fi os.FileInfo, err error) error {
   if fi.IsDir() {
    return nil
   }
   k++
   return nil
  })
  if err != nil {
   return 0, nil
  }
 }
 if k < 30 {
  return 0, nil
 }
 return 1, nil
}

9、查询硬盘大小

一些恶意程序使用系统硬盘大小作为判断是否运行在虚拟机中的依据,因为虚拟机的硬盘大小通常比较小。你可以通过 Windows API 获取系统硬盘的大小。
package main

import (
	"fmt"
	"syscall"
	"unsafe"
)

func getDiskSize(path string) (uint64, error) {
	var freeBytesAvailable, totalBytes, totalFreeBytes uint64
	pathPtr, err := syscall.UTF16PtrFromString(path)
	if err != nil {
		return 0, err
	}

	kernel32 := syscall.NewLazyDLL("kernel32.dll")
	getDiskFreeSpaceExW := kernel32.NewProc("GetDiskFreeSpaceExW")
	_, _, err = getDiskFreeSpaceExW.Call(
		uintptr(unsafe.Pointer(pathPtr)),
		uintptr(unsafe.Pointer(&freeBytesAvailable)),
		uintptr(unsafe.Pointer(&totalBytes)),
		uintptr(unsafe.Pointer(&totalFreeBytes)),
	)

	if err != nil && err.Error() != "The operation completed successfully." {
		return 0, err
	}

	return totalBytes, nil
}

func main() {
	diskSize, err := getDiskSize("C:\\")
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
	fmt.Printf("Disk size: %d bytes\n", diskSize)
}

10、反逆向工程

检测内核调试器可以通过检查系统的调试标志来实现。以下是一个简单的示例,使用 NtQuerySystemInformation API 来检查系统是否启用了调试。
package main

import (
	"fmt"
	"syscall"
	"unsafe"
)

const (
	SystemBasicInformation = 0
)

type SYSTEM_BASIC_INFORMATION struct {
	Reserved uint32
	TimerResolution uint32
	PageSize uint32
	NumberOfPhysicalPages uint32
	MinimumUserModeAddress uintptr
	MaximumUserModeAddress uintptr
	ActiveProcessorsAffinityMask uint32
	NumberOfProcessors uint32
}

var (
	modntdll = syscall.NewLazyDLL("ntdll.dll")
	procNtQuerySystemInformation = modntdll.NewProc("NtQuerySystemInformation")
)

func isDebuggerPresent() bool {
	var sysInfo SYSTEM_BASIC_INFORMATION
	ret, _, _ := procNtQuerySystemInformation.Call(
		uintptr(SystemBasicInformation),
		uintptr(unsafe.Pointer(&sysInfo)),
		uintptr(unsafe.Sizeof(sysInfo)),
		0,
	)
	return ret == 0
}

func main() {
	if isDebuggerPresent() {
		fmt.Println("Debugger detected")
	} else {
		fmt.Println("No debugger detected")
	}
}

11、静态文件特征

PE文件节的数量异常,可以使用 Go 的 pe 包来解析 PE 文件,并检查节的数量。这可以帮助检测 PE 文件是否被修改或加壳。
package main

import (
	"debug/pe"
	"fmt"
	"os"
)

func checkPESections(filePath string) error {
	file, err := os.Open(filePath)
	if err != nil {
		return err
	}
	defer file.Close()

	f, err := pe.NewFile(file)
	if err != nil {
		return err
	}

	sectionCount := len(f.Sections)
	fmt.Printf("Number of sections: %d\n", sectionCount)

	if sectionCount > 10 {
		fmt.Println("Warning: Abnormally high number of sections")
	}

	return nil
}

func main() {
	err := checkPESections("path_to_your_pe_file.exe")
	if err != nil {
		fmt.Println("Error:", err)
	}
}
none
最后修改于:2024年08月21日 16:20

已有 14 条评论

  1. zgwusrhlul

    博主真是太厉害了!!!

  2. ymtzyzlesd

    博主真是太厉害了!!!

  3. lzffgzzyze

    叼茂SEO.bfbikes.com

  4. jegtorvdvy

    想想你的文章写的特别好https://www.237fa.com/

  5. bgjqrsnank

    不错不错,我喜欢看 https://www.ea55.com/

  6. gvbmdoplsf

    不错不错,我喜欢看 www.jiwenlaw.com

  7. tffhebblzm

    文章的确不错啊https://www.cscnn.com/

  8. nyjwuhfszc

    真好呢

  9. gtnzknmfms

    选材新颖独特,通过细节描写赋予主题鲜活生命力。

  10. obtyhboyhw

    建议补充发展中国家案例,避免视角局限。

  11. nnzhewcden

    文章紧扣主题,观点鲜明,展现出深刻的思考维度。

  12. cljqovadle

    这篇文章提供了宝贵的经验和见解,对读者有很大的启发和帮助。

  13. hybvdoiobx

    新盘新盘 这个月刚上新盘 新车第一个吃螃蟹!

  14. qpielwyplt

    2025年10月新盘 做第一批吃螃蟹的人coinsrore.com
    新车新盘 嘎嘎稳 嘎嘎靠谱coinsrore.com
    新车首发,新的一年,只带想赚米的人coinsrore.com
    新盘 上车集合 留下 我要发发 立马进裙coinsrore.com
    做了几十年的项目 我总结了最好的一个盘(纯干货)coinsrore.com
    新车上路,只带前10个人coinsrore.com
    新盘首开 新盘首开 征召客户!!!coinsrore.com
    新项目准备上线,寻找志同道合 的合作伙伴coinsrore.com
    新车即将上线 真正的项目,期待你的参与coinsrore.com
    新盘新项目,不再等待,现在就是最佳上车机会!coinsrore.com
    新盘新盘 这个月刚上新盘 新车第一个吃螃蟹!coinsrore.com

添加新评论