首页
社区
课程
招聘
捕获桌面-扫描受害人的.lnk文件[翻译]
发表于: 2006-5-24 16:58 6799

捕获桌面-扫描受害人的.lnk文件[翻译]

2006-5-24 16:58
6799
【文章标题】: 捕获桌面-扫描受害人的.lnk文件
【文章作者】: [原著]DiA/rrlf/29A.8.008 [翻译]:kkbing
【作者邮箱】: kkbing@gmail.com
【下载地址】: 自己搜索下载
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  目录:
  1.引言
  2.LNK的格式
  3.怎样获得连接的文件,理论
  4.怎样获得连接的文件,列表
  5.怎样获得连接的文件, 代码
  6..lnk文件更多的东西
  7.尾言
  声明:
  对你所做的事情我将不负任何责任。如果你运用或改写这里的代码,那么你将对你所做的事负责。
  请务必小心!
  1.引言
  有些人有一个干净的桌面,而另外一些人的桌面却很混乱。我讲述的是关于"Windows Shortcut Files",
  也就是.LNK文件。它是应用程序,文档及其他文件的捷径。大多数电脑有这样桌面和快捷方式。在安装应用程序是,它经常在桌面安装一个快捷方式。所以这是一个寻找牺牲者并去感染(如PE EXE 文件),如果快捷方式文件(.lnk)知道连接的应用程序,文档文件在哪里,那么我们也就知道了(当然必须扫描.lnk文件)。
  谢谢BlueOwl的帮助。
  
  2.LNK格式
  这只是一个.lnk文件格式的简略图,要更多的信息请参阅"The Windows Shortcut File Format as reverse-engineered by Jesse Hager"。
  
   .lnk文件格式的简略图:
    *********************************************************
           段             |          大小(16进制)
    **********************|**********************************
    File Header           |  4Ch
    ----------------------|----------------------------------
    Shell Item ID List    |  ??h  ;??h 意味我们不知道它的静态大小
    ----------------------|----------------------------------
    File Location Info    |  22h
    ----------------------|----------------------------------
    Local Volume Table    |  10h + Volume Label (ASCIZ)
    ----------------------|----------------------------------
    Network Volume Table  |  14h + Network share name (ASCIZ)
    ----------------------|----------------------------------
    Description String    |  ??h
    ----------------------|----------------------------------
    Relative Path String  |  ??h
    ----------------------|----------------------------------
    Working Directory     |  ??h
    ----------------------|----------------------------------
    Commandline String    |  ??h
    ----------------------|----------------------------------
    Icon Filename String  |  ??h
    ----------------------|----------------------------------
    Extra stuff           |  ??h
    *********************************************************
  
   File Header:
    *********************************************************
    偏移   |  大小   |               内容    *******|*********|***************************************
     00h   | 1 dword | 0000004Ch "L" identifies the .lnk file
    -------|---------|---------------------------------------
     04h   | 16 byte | 快捷文件的 GUID
    -------|---------|---------------------------------------
     14h   | 1 dword | 标志
    -------|---------|---------------------------------------
     18h   | 1 dword | 文件属性
    -------|---------|---------------------------------------
     1Ch   | 1 qword | Time 1
    -------|---------|---------------------------------------
     24h   | 1 qword | Time 2
    -------|---------|---------------------------------------
     2Ch   | 1 qword | Time 3
    -------|---------|---------------------------------------
     34h   | 1 dword | 文件长度   
  -------|---------|---------------------------------------
     38h   | 1 dword | 图表编号
    -------|---------|---------------------------------------
     3Ch   | 1 dword | ShowWnd Value
    -------|---------|---------------------------------------
     40h   | 1 dword | 热键
    -------|---------|---------------------------------------
     44h   | 2 dword |不清楚,一直是0
    *********************************************************
  Shell Item ID List:
  The Shell Item List 段没有静态大小,它是一个可变值。但是这不是一个困难的问题,因为第一个无符号整型(在文件开始处4Ch)指出了整个Item List的大小,我们仅仅要做的就是读取这个大小值并加上4Ch;这样我们就到达了“File Location Info”段。
  
  File Location Info:
    *********************************************************
      偏移  |  大小  |               内容   
*  ******|*********|***************************************
     00h   | 1 dword | 整个结构长度
    -------|---------|---------------------------------------
     04h   | 1 dword | 1Ch处的第一个偏移
    -------|---------|---------------------------------------
     08h   | 1 dword | 标志   
    -------|---------|----------------------------------
     0Ch   | 1 dword | Local Volume Info的偏移
    -------|---------|---------------------------------------
     10h   | 1 dword | Base Pathname 的偏移
    -------|---------|---------------------------------------
     14h   | 1 dword | Network Volume Info的偏移  
    -------|---------|---------------------------------------
     18h   | 1 dword | Remaining Pathname的偏移
    *********************************************************
  
   Local Volume Table:
    *********************************************************
    偏移    |  大小  |              内容
    *******|*********|***************************************
     00h   | 1 dword | 结构的长度
    -------|---------|---------------------------------------
     04h   | 1 dword | 磁盘的类型
    -------|---------|---------------------------------------
     08h   | 1 dword | 磁盘序列号
    -------|---------|---------------------------------------
     0Ch   | 1 dword | 卷标名偏移
    -------|---------|---------------------------------------
     10h   | ASCIZ   | 卷标!!这就是我们想要的!!
    *********************************************************
  
   Network Volume Table:
    *********************************************************
    偏移   |  大小   |               内容
    *******|*********|***************************************
     00h   | 1 dword | 结构长度
    -------|---------|---------------------------------------
     04h   | 1 dword | 不清楚, 一直是 02h?!
    -------|---------|---------------------------------------
     08h   | 1 dword | Network Share Name (14h)的偏移
    -------|---------|---------------------------------------
     0Ch   | 1 dword | 不清楚, 一直是0?
    -------|---------|---------------------------------------
     10h   | 1 dword | 不清楚,一直是 20000h?
    -------|---------|---------------------------------------
     14h   | ASCIZ   | Network Share Name
    *********************************************************
  
   剩下的像Description String, Relative Path String, Working Directory,Commandline String, Icon Filename String and Extra stuff
section 等段在我们这片短文中都没有用处.
  
  
  3. 怎样获得连接的文件,理论
  ==================================
  好了,现在我们知道了.lnk文件的构造。我们真正所需要的是“Local Volume Label" 段段中的”Volume Label"。但是有一个问题,他没有静态偏移,因为"Shell Item ID List"段的大小是可变的。我们必须读取这个结构的大小并和"File Header"段相加,这时我们就到了 "File Location Info"段。从这个地方就很容易获得"Volume Label“的大小。用下面的图表更好描述:
  
   *****************************
   | File Begin            00h |
   *****************************
          +
   *****************************
   | File Header           4Ch |
   *****************************
          =
   *****************************
   | offset Shell Item ID List |
   *****************************
  现在我们拥有了"Shell Item ID List"的偏移。第一个无符号短整型整数指出了这个段的大小,我们读取这个大小,在这个图表中叫"ItemSize"(如 F5h) .
  *****************************
   | File Begin            00h |
   *****************************
          +
   *****************************
   | File Header           4Ch |
   *****************************
          +
   *****************************
   | ItemSize              F5h |
   *****************************
          =
   *****************************
   | offset File Location Info |
   *****************************
  
  现在已获得了"File Location Info"段,那么就非常容易获得"Volume Label"(相关联的文件)。"File Location Info"和"Local Volume Table"都有静态大小。在"Local Volume Table"之后是所关联文件的字符串,并结束于零。下来让我们获得这个字符串的第一个字符。
   *****************************
   | File Begin            00h |
   *****************************
          +
   *****************************
   | File Header           4Ch |
   *****************************
          +
   *****************************
   | ItemSize              F5h |
   *****************************
          +
   *****************************
   | File Location Info    22h |
   *****************************
          +
   *****************************
   | Local Volume Table    10h |
   *****************************
          =
   *****************************
   | offset to Volume Label    |
   *****************************
  
  好了,现在我们获得了所需字符串的偏移。因为它结束于0,所以我们一个字节一个字节的检测如果是0,那么就是这个字符串的结尾,最终也就获得了相关联应用程序的完整路径。这时理论的下面看看列表和代码....
  
 4.怎样获得连接的文件,列表
  以下是扫描.lnk文件的一般步骤:
     (1).从注册表中读桌面的路径
      (2).检测路径是否有效,如果无效,使他有效
      (3).把当前路径改为桌面路径
      (4).找第一个.lnk文件
      (5).没有更多的文件?那么到(17).
      (6).Map .lnk 文件取处理它
      (7).检测.lnk文件是否有效(第一个双字必须是“L”000000h)
      (8).获得"Shell Item ID List"段的偏移。
      (9).读"Shell Item ID List"的大小
      (10).跳过这个段(File Header + Shell Item ID List size)
      (11).获得"Volume Label"的偏移
      (12).获得路径字符串的结尾,并复制这个字符串
      (13).检测扩展路径是否有效,如果无效则到(15)
      (14).简单的一个消息框
      (15).unmap文件,并关闭句柄。
      (16).查找下一个.lnk文件,返回(5)
      (17).退出
  
  5.怎样获得连接的文件, 代码
  
  include "%fasminc%\win32ax.inc"                        
  
  LNKscan:
  ;-----从注册表获得桌面--------------------
          invoke RegOpenKeyEx,\                       
               HKEY_CURRENT_USER,\                  
               DesktopSubkey,\                        
               0,\                             
               ;security access mask
               RegHandle   
          cmp eax, 0                        ;错误?
          jnz ErrorMsg                      ;显示错误信息
  
          invoke RegQueryValueEx,\          ;读一个值
                 dword [RegHandle],\        ;handle of open key
                 DesktopValue,\             ;the value name "Desktop"
                 0,\                        ;reserved
                 Reg_SZ,\                   ;we want a string
                 DesktopPath,\              ;save here the desktop pat
                 DesktopSize                ;size of reserved place
  
          cmp eax, 0                       ;error?
          jnz ErrorMsg                     ;if so show a error message
  
          invoke RegCloseKey,\    ;we have the desktop path, close key
                 dword [RegHandle]         ;with the handle
  ;-----从注册表获得桌面---结束--------------
  
  
  ;-----检测路径是否有效,如无效,使他有效------
          mov edx, DesktopPath           ;address of string
  
  GetZero:
          cmp byte [edx], 0              ;check for end of the string
          je GotZero                     ;we have the zero
  
          inc edx                        ;address + 1
          jmp GetZero                    ;check next byte
  
  GotZero:
          dec edx                         ;address (,0) - 1
          cmp byte [edx], "\"             ;check for the slash
          je HaveSlash                    ;and dont place a slash
  
          inc edx                   ;jmp after last byte of the string
          mov byte [edx], "\"              ;place the \
          mov byte [edx + 1d], 0           ; "String",0 <-
  
  HaveSlash:
  ;-----检测路径是否有效,如无效,使他有效--结束-
  
  
  ;-----改变桌面路径目录------------------
          invoke SetCurrentDirectory,\      ;change directory
                 DesktopPath                ;to the desktop path
  
          cmp eax, 0                         ;error?
          je ErrorMsg                        ;no path, no victims
  ;-----改变桌面路径目录---结束------------
  
  
  ;-----在当前目录中找第一个文件--------------
          invoke FindFirstFile,\             ;the well known api
                 LnkFiles,\                  ;search for *.lnk
                 Win32FindData               ;structure
  
          mov dword [FindHandle], eax        ;save find handle
  
  FindMoreFiles:
          cmp eax, 0                         ;error? no more files?
          je Exit                            ;exit the application
  ;-----在当前目录中找第一个文件---结束--------
  
  
  ;-----map .lnk 文件取处理它--------------------
          invoke CreateFile,\                ;open the file
                 Win32FindData.cFileName,\   ;the lnk file
                 GENERIC_READ + GENERIC_WRITE,\;read and write access
                 FILE_SHARE_READ,\           ;open it when we can read
                 0,\                         ;no security attributes
                 OPEN_EXISTING,\             ;open only the file
                 FILE_ATTRIBUTE_NORMAL,\     ;all attributes
                 0                           ;no flag
  
          cmp eax, INVALID_HANDLE_VALUE       ;error?
          je FindNextLNK                      ;find next lnk file
  
          mov dword [FileHandle], eax         ;save file handle
  
          invoke CreateFileMapping,\          ;create the map
                 dword [FileHandle],\         ;handle of file
                 0,\                          ;no security attributes
                 PAGE_READWRITE,\             ;read and write mapping
                 0,\                          ;size high -> null
                 0,\           ;size low  -> null = size of whole file
                 0                            ;no mapping name
  
          cmp eax, 0                           ;error?!
          je CloseFile                 ;close the file and search next
  
          mov dword [MapHandle], eax          ;save mapping handle
  
          invoke MapViewOfFile,\              ;write map to address
                 dword [MapHandle],\          ;handle of created map
                 FILE_MAP_WRITE,\             ;read and write
                 0,\                          ;high offset
                 0,\                          ;low offset -> null,
                                         address is after call in eax
                 0                           ;how much bytes should   be mappep? 0-> all
  
          cmp eax, 0                          ;error?
          je CloseMap                         ;if so close the map,   search next file
  
          mov dword [MapAddress], eax        ;save address in memory where file begins
  ;-----map .lnk 文件取处理它---end--------------
  
  
  ;-----检测.lnk文件是否有效-----------------------
          mov esi, dword [MapAddress]        ;filebegin now in esi
  
          cmp dword [esi], "L"               ;first dword is a  4C000000h ?
          jne CloseMap                       ;close map, search more files
  ;-----检测.lnk文件是否有效---结束-----------------
  
  
  ;-----获得关联的应用程序----------------------------
          add esi, 4Ch                       ;jump over header
  
          mov edi, ItemSize                  ;to copy size of Shell Item List
          movsb                              ;copy one byte, the size (esi->edi)
  
  JumpOverItem:
          cmp byte [ItemSize], 0d            ;counter on zero?
          je JumpedOver                      ;then we jumped over the Shell Item List strcture
  
          inc esi                             ;address + 1
          dec byte [ItemSize]                 ;counter - 1
          jmp JumpOverItem                    ;next byte

  JumpedOver:
          add esi, 22h                        ;jump over FileLoationInfo
          add esi, 0Ch                        ;jump over Location Volume Table to the volume label (ASCIZ)
  
          mov edi, Victim                                 ;destination is Victim (esi->edi)
  
  CopyVictimString:
          cmp byte [esi], 0            ;0 -> end of the string (ASCIZ[ero])
          je HaveVictim                ;time to infect :)
  
          movsb                        ;move one byte from esi to edi
          jmp CopyVictimString         ;check again for end of string
  
  HaveVictim:
          mov dword [edi], 0           ;clear all after string
  ;-----过的关联的应用程序---end----------------------
  
  
  ;-----检测路径是否有效---------------------
          mov edx, Victim               ;get address
          cmp byte [edx + 1d], ":"      ;check for the : (eg C:)
          jne CloseMap                  ;if not then close map, search next file
  
  GetVictimZero:
          cmp byte [edx], 0              ;check for end of string
          je HaveVictimZero              ;we have it
  
          inc edx                        ;next byte
          jmp GetVictimZero              ;search for zero
  
  HaveVictimZero:
          cmp byte [edx - 4d], "."       ;check for dot (eg .exe)
          jne CloseMap                   ;search next
  ;-----检测路径是否有效---end---------------
  
  
  ;*******************************************************
  ;***** 显示信息 *****************************
  ;*******************************************************
          invoke MessageBox,\            ;only show a messagebox that it works
                 0,\                     ;now owner window
                 Victim,\                ;show full path of victim
                 Win32FindData.cFileName,\   ;caption: name of scanned .lnk file
                 MB_ICONINFORMATION                       ;information 4 u
  ;*******************************************************
  ;*****显示信息***END***********************
  ;*******************************************************
  
  
  ;-----unmap view of file--------------------------------
          invoke UnmapViewOfFile,\      ;unmap the file
                 dword [MapAddress]     ;with the address
  ;-----unmap view of file---end--------------------------
  
  
  ;-----close file and map handle-------------------------
  CloseMap:
          invoke CloseHandle,\          ;close
                 dword [MapHandle]      ;the map handle
  
  CloseFile:
          invoke CloseHandle,\         ;close the handle
                 dword [FileHandle]    ;file
  ;-----close file and map handle---end-------------------
  
  
  ;-----find next lnk file--------------------------------
  FindNextLNK:
          invoke FindNextFile,\         ;next lnk file
                 dword [FindHandle],\   ;via find handle
                 Win32FindData          ;and the structure
  
          jmp FindMoreFiles             ;get more!
  ;-----find next lnk file---end--------------------------
  
  
  ;-----get the hell out of here--------------------------
  Exit:
          invoke ExitProcess,\           ;exit
                 0                       ;current process
  ;-----get the hell out of here---end--------------------
  
  
  ;-----error message-------------------------------------
  ErrorMsg:
          invoke MessageBox,\             ;shit, some error
                 0,\                      ;no owner window
                 "Sorry, can't set desktop directory!",\  ;text
                 ".:: ERROR ::.",\                        ;caption
                 MB_ICONERROR             ;scary error icon ;)
  
          jmp Exit                       ;get out of here
  ;-----error message---end-------------------------------
  
  
  ;-----data's--------------------------------------------
          DesktopSubkey   db "Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders",0
          DesktopValue    db "Desktop",0
          DesktopPath     rb 255d
          DesktopSize     db 255d
          RegHandle       dd ?
          Reg_SZ          db "REG_SZ",0
  
          Win32FindData   FINDDATA            ;already defined by fasm
          LnkFiles        db "*.lnk",0
          FindHandle      dd ?
  
          FileHandle      dd ?
          MapHandle       dd ?
          MapAddress      dd ?
  
          ItemSize        db ?
          Victim          rb 255d
  ;-----data's---end---------------------------------------
  
  
  ;-----api's import, fasm will do-------------------------
          data import            ;only one section, fasm will do it :)
               library kernel32, "KERNEL32.DLL",\
                       user32, "USER32.DLL",\
                       advapi32, "ADVAPI32.DLL"
  
               import kernel32,\
                      SetCurrentDirectory, "SetCurrentDirectoryA",\
                      FindFirstFile, "FindFirstFileA",\
                      FindNextFile, "FindNextFileA",\
                      CreateFile, "CreateFileA",\
                      CreateFileMapping, "CreateFileMappingA",\
                      MapViewOfFile, "MapViewOfFile",\
                      UnmapViewOfFile, "UnmapViewOfFile",\
                      CloseHandle, "CloseHandle",\
                      ExitProcess, "ExitProcess"
  
               import advapi32,\
                      RegOpenKeyEx, "RegOpenKeyExA",\
                      RegQueryValueEx, "RegQueryValueExA",\
                      RegCloseKey, "RegCloseKey"
  
               import user32,\
                      MessageBox, "MessageBoxA"
          end data
  ;-----api's import, fasm will do---end-------------------
  
  6..lnk文件更多的东西。
  我们已经获得了相关联文件。在.lnk文件中其他有兴趣的事情(也许对于蠕虫病毒)是"Network Share Name"在"Network Volume Table".方法和上面的几乎一样,如下表:
  *****************************
   | File Begin            00h |
   *****************************
          +
   *****************************
   | File Header           4Ch |
   *****************************
          +
   *****************************
   | ItemSize              F5h |   
   *****************************
          +
   *****************************
   | File Location Info    22h |
   *****************************
          +
   *****************************
   | Local Volume Table    10h |
   *****************************
          +
   *****************************
   | size of Volume Label  0A  |   
   *****************************
          +
   *****************************
   | Network Volume Table  14h |
   *****************************
          =
   *****************************
   | offset Network Share Name |
   *****************************
  
  
  7.尾言
  
  这时本文的结束,希望能获得有用的东西。祝你好运!
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                 2006年05月24日 16:54:42

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 196
活跃值: (135)
能力值: ( LV10,RANK:170 )
在线值:
发帖
回帖
粉丝
2
kkbing辛苦了,
支持加灌水
2006-5-24 17:44
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
学习了。谢谢
2006-5-25 20:31
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
翻译太辛苦,要不我也帮忙的 :)
2006-5-25 21:58
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
Shell Item ID List段的大小究竟是由“第一个无符号整型”(dword?)还是“第一个无符号短整型整数”(word?)来指定呢?

The Shell Item List 段没有静态大小,它是一个可变值。但是这不是一个困难的问题,因为第一个无符号整型(在文件开始处4Ch)指出了整个Item List的大小,我们仅仅要做的就是读取这个大小值并加上4Ch;这样我们就到达了“File Location Info”段。


现在我们拥有了"Shell Item ID List"的偏移。第一个无符号短整型整数指出了这个段的大小,我们读取这个大小,在这个图表中叫"ItemSize"(如 F5h) .


2006-12-1 10:27
0
游客
登录 | 注册 方可回帖
返回
//