Solution to Phlux’s keygenme kthx 1

As i was going around taking my coffee, i saw 1 of the guys in my office trying out a keygenme. So being the curious me, i looked over his shoulder and saw what he was trying to crack. It’s basically this very old keygenme, keygenme 1 by Phlux.

I quickly saw that he seems to have some problems with it and offered to give him a hand with it. When i load it up in OllyDbg, straight away i knew that this will be quite easy. But in order to teach him the basics…i made him to Search for references to GetDlgItemText or strcmp functions.

Immediately, he knew what to do and put in the breakpoints like the following image.


In the 2nd image, everyone can see the serial that was generated based on my nickname.

But how can we write the keygenme generator if we can’t understand the inner algorithm. A little before we reached the lstrcmpA function, there is the algorithm that generates the serial for each individual user.
However from the image, we can also deduce that a minimal of 3 characters are required for username.

Immediately with the algorithm, it’s fairly trivial for us to develop a Keygenme generator,

I’ve attached the source code & keygenme for the purpose of learning.
Hope someone learnt something out of this.
KeygenMe 1

Have Fun.

BR,
[ Gunther ]

Monday, October 17th, 2011 Coding, Puzzles, Reverse Engineering, Windows 2 Comments

Boring post by a boring man. :(

I’ve actually done this and several things yesterday while waiting for my wife to knock of from work.
All of it are boring but i will most probably write about 1-2 of those these few days.

Yesterday i was at Starbucks wondering what can i do with just my iPad.
So i tried my luck and check how many more Gmail could i register.
Then i realise i could no longer register any more without supplying a handphone number as indicated by this image.

But i don’t wish to supply my personal mobile number so i looked for alternatives and i found Tropo, https://www.tropo.com/
The description on the website seems great and i proceeded to registering myself an acct. with them.

Basically, it’s an application that maps my scripts to the phone numbers provided by them.
However, i needed to supply a dummy application and url. But it could be fake information.
But i chose “cr4zyserbians.r.us” cos i hang out too frequently with deroko and EvilCry recently. :P

After registration is done and i’ve created my dummy url. You will see something like the below image.

But where is the new phone number for me to register a new Gmail account?
If you look carefully at the above image, there is an option for me to add new phone numbers.
Clicking on that and i will get another new pop-up asking what sort of number do i need. So i picked Ann Arbor for demostration purposes.

After you added the new number, you will see that new number.

Now, head back to your Gmail registration page and enter your new phone number.
Alrighty, halfway done. Now how do i verify the SMS number that Google had sent me?
Go back to Tropo and you will realise that there is a “Application Debugger” link.
Click on that and you will see something like this.

Awesome, i can see the “Verification Number” sent by Google. Now let’s head back to the “Verification” page by Gmail and enter this new number.
W00t H00t…..I’ve successfully registered a brand new Gmail without using my real mobile number as shown here. :D

Well, although this is no rocket science and is seen as childish by most. So it’s just another boring post by boring old me. :P

BR,
[ Gunther ]

Wednesday, May 25th, 2011 Linux, Windows No Comments

[ Code Snippet ] Qt based linux process enumeration

Yesterday while I was working on a little private project, I’ve had the necessity
to enumerate, under Linux, processes in the form of Pid – Process Name.

Under Windows that issue can be solved by calling CreateToolhelp32Snapshot() API, that’s just one tons of possible methods.

Under Unix-like operating system we have to deal with procfs (process file system), around the various forums there are tons of hints about that issue, often involved in using libproc library that comes out from:

procps -> http://procps.sourceforge.net/

I don’t need entire processing capability given by that library, so coded my own enumerator, by using what Qt offers (i need this for portability issues) and by looking how these informations can be obtained.

Concept is easy and basically, all process listeners/etc. use the same system.

Inside /proc there are n subdirectories in the form of /proc/_pid_ and inside each subdirectory a set of additional informations. From a Qt point of view all that we need is a QDirIterator (to enumerate all PIDs) and a read access via QFile to obtain the process name from /proc/pid/cmdline.

So here a little code snippet that enumerates PIDs and Process Names and places them into a MultiColumn TreeWidget.

————————————————————————————————–

void keyRevealer::EnumerateProcesses() // Process Enumerator -recallable by Refresh
{
    QDirIterator iterProc("/proc", QDir::Dirs);
    int row = 0;
 
    while ( iterProc.hasNext() ){
        QString Pid = iterProc.fileInfo().baseName();
        if ( Pid.isEmpty() ){
            iterProc.next();
            continue;
        }else{
            if ( Pid.at(0).isDigit() ){
                QTreeWidgetItem *item = new QTreeWidgetItem();
                QString name;
                item->setText(0,Pid);
                ui->treeWidget->insertTopLevelItem(row,item);
                name = keyRevealer::getNameFromPid(Pid);
                if ( name.isEmpty() ){
                    item->setText(1, "-");
                    ui->treeWidget->insertTopLevelItem(row,item);
                    row++;
                    iterProc.next();
                    continue;
                }else{
                    item->setText(1, name);
                    ui->treeWidget->insertTopLevelItem(row,item);
 
                }
                row++;
                iterProc.next();
                continue;
            }
        }
        iterProc.next();
    }
}

————————————————————————————————

here getNameFromPid()

————————————————————————————————

QString keyRevealer::getNameFromPid(QString Pid){
    QString name = "";
    QFile file("/proc/" + Pid + "/cmdline");
 
    if ( ! file.open(QIODevice::ReadOnly | QIODevice::Text) )
        return( name );
 
    name = file.readLine();
    file.close();
 
    return( name );
}

————————————————————————————————

Additionally into getNameFromPid result can be refined by using a dot based ‘.’ split()
According to your necessity you can obtain tons of other additional informations, by checking here

http://linux.die.net/man/5/proc

Really nothing new, just wanted to add on my chronicles this issue :)

Regards,
Giuseppe ‘Evilcry’ Bonfa

Monday, February 7th, 2011 Coding, Linux No Comments

pyOLEScanner 1.3 Out

Yesterday I’ve released on github a new version of pyOLEScanner.

The essential aim of this script is to detect Malicious Office Files (basically doc, xls, ppt) and warn about suspect behaviours.

https://github.com/Evilcry/PythonScripts/raw/master/pyOLEScanner.zip

Version 1.3 contains:

  1. Bug Fix.
  2. More Shellcode Detection.
  3. More API Detection.
  4. SQLite Support.
  5. OLE2 Macro Scan.
  6. Office2007 (docx/pptx/xlsx) deflate and Macro checks.

Directory scan works too, in presence of encryption a ‘decrypted‘ copy.

USAGE: python pyOLEScanner.py _suspect_document

Compatibility with Windows and Linux is mantained.

Next Issue:

  1. Whole script will be OOP-ized.
  2. CVE Detector.
  3. Increase Performances of XOR Bruteforcer.
  4. Forensics Interface, to explore File Format Internals.
  5. Report.

Obviously I’m open for bug reporting.
Due to the fact that my research is actually not involved with any company or organisation (IT it’s only an hobby for me atm), I need to collect as much as I can infected samples, so feel free to submit at my mail address Office Infected (or suspected) files that you want to share, this will help me to cover a larger casuistry especially under a CVE Detection and Encryption point of view.

In the next weeks will be released a pyOLEScanner in WebApplication flavour:

  1. webpy based web interface.
  2. Analysis and Black/White listing DB.
  3. Report Production.

Regards,
Giuseppe ‘Evilcry’ Bonfa

Tags: , ,

Sunday, January 30th, 2011 Coding, Scripting 1 Comment

Who Uploaded that image at FB?

Today was another rainy day here. And i didn’t get to go to ShmooCon as CNY is near.
I have at numerous times been asked by people on who uploaded certain images at Facebook.

So i spent 10min and developed this time wasting web application.
Basically, users just need to enter the url containing the FB image and it will return the profile id of the person who uploaded that particular image.
Hopefully this will be useful to those people.
I made use of jQuery JavaScript Library v1.4.2 to return the results. :P
But none-the-less, here are the source code to the web application.
FB.Image

Anyway, have Phun coding.
/Me wish i was at ShmooCon. :(

BR,
[ Gunther ]

Friday, January 28th, 2011 Coding, Linux, Windows No Comments

Boring Application by a bored man. :(

The other day i was feeling kinda bored so i developed a simple application to fetch the rankings of the “Free” & “Paid” iPhone and iPad applications in iTunes Store.
It’s really nothing fancy but maybe someone would find it useful or further enhance it.

Basically, what i did was use Paros to sniff the traffic from iTunes to see where did it get the results.
Initially, i had a small hiccup. Then i realise it requires me to have the iTunes User Agent.

I have hereby attached the entire source code.
iTunes.Ranking

Until next time, Have Phun coding.

BR,
[ Gunther ]

Friday, January 28th, 2011 Coding, Linux, Windows No Comments

Simple Virustotal Checking Tool

Hi everyone, it’s been a long time since any of us blogged about anything here. But rest assured that we are coming up with some interesting stuff for some of you if not all of you.

Maybe, today’s topic seems slightly amateur-ish but it’s part of the modules EvilCry and myself are integrating into a system that we are developing and hope it will be useful.
This is just the Alpha version of a particular module. So to put it simply, what this module does is to allow user to do a quick MD5 hash of the binary that they have on hand and do a quick check against VirusTotal. Return the results if it’s submitted to VirusTotal before.

The plans we have for this is to add in 2 more options. Firstly being, “Update”, which we allow user(s) to add in the results into an internal DB, we are using SQLite. The other option is “Offline” such that the user(s) can do a quick check in his / her internal DB instead of querying VirusTotal. It will be useful if 1 got too many files to check and not sure whether it’s trusted or not.

In the meantime, we will try to write more quality stuff.

Have Phun everyone.

BR,
[ Gunther ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#!/usr/bin/python
import re, hashlib
import os, sys
import urllib, urllib2
 
# Usage
def help_menu(cmd):
    print("Usage: python %s [online] [binary]\n") % (cmd)
 
# Banner
def Banner():
    print("=================================================")
    print("MD5 Virustotal Checking Tool v0.2                ")
    print("=================================================")
 
def online_check(binary_md5):
    url = "http://www.virustotal.com/search.html"
    values = { 'chain' : binary_md5 }
    data = urllib.urlencode(values)
    req = urllib2.Request(url, data)
 
    try:
        response = urllib2.urlopen(req)
    except(URLError),e:
        print e.reason
    digit1 = ""
    digit2 = ""
    perc = ""
 
    while 1:
        data = response.read(65536)
        if (len(data) > 0):
            if data.find("The item you searched for was not") > 0:
                print("[+] No malware detected")
                sys.exit(1)
 
            retup = re.findall('(color: red">)(\\d+)(<\\/span>)', data)
            if len(retup) > 0:
                for element in retup:
                    digit1 = element[1]
 
            retup = re.findall('(\\/)(\\d+)( ).*?([+-]?\\d*\\.\\d+)(?![-+0-9\\.])', data)
            if len(retup) > 0:
                for element in retup:
                    digit2 = element[1]
                    perc = element[3]
            print("[+] Malware detected! [ %s/%s ] (%s%%)" % (digit1, digit2, perc))
            print("    [*] Report:")
 
            result = data.find("<th>Result</th>")
            retup = re.findall(r"(<td)([a-zA-Z0-9\/\!\@\:\<\>\=\.\"\-\_\~\+\]\[\(\) ]*)(</td>)", data[int(result):])
 
            i = 0
            while i < len(retup) and len(retup) > 0:
                if retup[i][1][1:].find("SHA256") > 0:
                    break
                if retup[i+3][1][1:] != "-":
                    print("        %s - %s" % (retup[i][1][1:], retup[i+3][1][18:]))
                i = i + 4
            print("[+] For more information, you may visit: %s") % (response.url)
        if not len(data):
            break
 
if __name__ == '__main__':
    Banner()
    if len(sys.argv) < 2:
        help_menu(sys.argv[0])
        sys.exit(1)
    binary_md5 = sys.argv[2]
 
    if len(sys.argv) > 2:
        md5 = hashlib.md5(open(sys.argv[2],'rb').read())
        binary_md5 = md5.hexdigest()
 
    try:
        if (sys.argv[1].lower() == "online") and len(sys.argv) > 2:
            # For testing purposes you may comment out the line below (md5 of a virus)
            #binary_md5 = "2bde56d8fb2df4438192fb46cd0cc9c9"
            print("[+] Online md5 check: %s (%s)") % (sys.argv[2], binary_md5)
            try:
                online_check(binary_md5)
            except KeyboardInterrupt:
                if sys.platform == 'linux-i386' or sys.platform == 'linux2':
                    os.system("clear")
                elif sys.platform == 'win32':
                    os.system("cls")
                else:
                    os.system("cls")
                Banner()
                print("[+] Bye...")
            except Exception:
                print("[+] Error: Check your internet connection or proxy configuration")
                sys.exit(1)
        else:
            help_menu(sys.argv[0])
            sys.exit(1)
    except KeyboardInterrupt:
        if sys.platform == 'linux-i386' or sys.platform == 'linux2':
            os.system("clear")
        elif sys.platform == 'win32':
            os.system("cls")
        else:
            os.system("cls")
        Banner()
        print("[+] Bye...")
Wednesday, January 12th, 2011 Coding, Linux, Windows 4 Comments

[ Concept ] Build your own Youtube Downloader

Hi everyone,

Today I’m going to write a short and simple concept post on how to “Build your own Youtube Downloader”.
The reason was that i find it amusing that some people still don’t know how to develop such a simple tool. But i won’t end it as just another simple youtube tool.
What i can do though is encourage development thru advanced code snippets or simple applications that solves someone’s problems in their real life.

One simple example would be looking at Youtube’s API.
You would have noticed that a simple GET to “http://gdata.youtube.com/feeds/api/users/” and you will get lots of information with regards to this particular user. So slowly expand from there, you can develop an application that will show information about that user in a nice GUI and you can download all the videos uploaded by that user. Other features which one can implement is adding proxy support.

And if there are network guys here, i’m sure you could developed your own Youtube downloader easily.
A normal youtube link would look like this, http://www.youtube.com/watch?v=
But if you watch the traffic, you could see this, http://www.youtube.com/v/
Further analysis would give you this results,

http://www.youtube.com/get_video_info?&video_id=uL691j65CAM&el=embedded&ps=default&eurl=&hl=en_US&hd=1

Then you can see within this file to get the link to the .MP4 and .flv file.

You can even develop in such a way that you can track down all the contacts of that particular user using this GET.

http://gdata.youtube.com/feeds/api/users//contacts?v=2

Have Phun. Come on, just try it. It’s just that simple. :P

BR,
[ Gunther ]

Monday, December 20th, 2010 Coding, Linux, Windows No Comments

OTW – Vortex Level 0

Today i had a great chat with E over more collaboration and imparting our “renewed” knowledge with everyone.
However, for everything that we learned, we think it’s best to start from the basics.
We’ve decided to embark on some “new” adventure. We will try to solve the challenges found in overthewire.org.

Today we shall take a look at the Vortex Level 0 first using Python:

Level Goal:
Your goal is to connect to port 5842 on vortex.labs.overthewire.org and read in 4 unsigned integers in host byte order. Add these integers together and send back the results to get a username and password for level 1.
Note: that vortex is on an x86 machine (meaning, a little endian architecture)

Basically the pre-requisite is to have some network programming knowledge.

Hope everyone had a great time solving this. Probably need a break now. Ciao.

BR,
[ Gunther ]

#!/usr/bin/env python

import struct
import socket
import sys

# Usage
def help_menu(cmd):
    print "Usage: ./%s" % cmd

# Main Program
def main():
    # Create socket and connect to vortex.labs.overthewire.org on port 5842.
    sock = socket.socket()
    sock.connect( ('vortex.labs.overthewire.org', 5842) )

    # Receive the 4 integers with the opened socket.
    iLen = struct.calcsize('I')
    pInputData = [sock.recv(iLen) for i in xrange(4)]

    #Unpack the input data and compute it.
    iResult = sum( struct.unpack( '<4I', ''.join(pInputData) ) )

    # Pack and send the computed result back.
    sock.send( struct.pack( '1:
        help_menu(sys.argv[0])
        sys.exit()
    main()
Saturday, August 28th, 2010 Coding, CTF, Puzzles No Comments

Quick overview of Lnk File Format and Ways of Information Extraction

Hi,

Long time no posting, due to severe busy issues.

In this post we will meet the famous .lnk file, that in the last period registered an high attention from Security Industry cause a vulnerability exploited by a rootkit.

“Windows Shell in Microsoft Windows XP SP3, Server 2003 SP2, Vista SP1 and SP2, Server 2008 SP2 and R2, and Windows 7 allows local users or remote attackers to execute arbitrary code via a crafted (1) .LNK or (2) .PIF shortcut file, which is not properly handled during icon display in Windows Explorer, as demonstrated in the wild in July 2010, and originally reported for malware that leverages CVE-2010-2772 in Siemens WinCC SCADA systems.”
The exploit uses a specially crafted LNK file. This file allows the attacker to execute an arbitrary file by carefully specifying its location – the LNK file in itself does not exploit any vulnerability such as buffer overflows, for example, so it is a legitimate LNK file. The LNK file used in targeted attacks was manually crafted as some fields that are normally present, such as CreationTime, AccessTime or WriteTime are all set to 0.
Should be clear that the basical spread vector is the malicious *.lnk file, what should be heavy market is that at the actual state of art, no autorun.inf is necessary, so we have to expect a new wave of infected USB Pen Drives.

Around here there are tons of post about SCADA Infection, so I no longer repeat the same things, very well discussed in other articles, due that I’m basically a reverser, in this post I’m going to give some fast and quick note on the Structure of Lnk File Format.

lnk vulnerability is listed as CVE-2010-2568

Lnk and Pif files are used for shortcutting, so executing on a Lnk or Pif file has the same result as executing directly the file specified by the shortcut the file that is specified on the shortcut target. The vulnerability involved in Lnk essentially executes a malicious Dll in the same context of Windows Control File.

Lnk and Pif are by design a Binary Based File Format, also called Shell Link. This file as previously exposed is used to store a link target namespace referred to a link target. As we will see in the prosecution of the post, lnk does not merely store only a link, but encapsulates a variety of informations, like:

  • Keyboard Shortcut that can be used to callback the link
  • Application Behavior
  • Extended Comment
  • Extra Data Section, that offers possibility to add Optional Data
Essentially lnk Bynary File Format inherits various characteristics from the two major file formats:
  • CFB – Compound File Format (used by MS-Office Files)
  • PROPOSTORE – Property Store Binary File Format
We can manipulate this file format via COM Objects, in this case the two major interfaces are:
  • IShellLink
  • IPersistStream
  • IPersistFile
Like in every File Format Reverse Engineering task, one of the best approach is to perform analysis by acting like a parser that works into two levels of abstraction, that I usually call:
  • TopLevel Parser
  • DownLevel Parser
TopLevel Parser is a shot of higher hierarchies, that keep track of lower hierarchy structures. Here a shot of higher structures:

ShellLinkHeader is placed at the beginning of .lnk file and provides the following informations:
  • Header Size
  • CLSID
  • LinkFlags
  • File Attributes
  • Creation Time
  • Last Access Time
  • Modification Time
  • Target Size
  • Icon Index
  • Show Command
  • Hotkey
  • Reserved1, Reserved2, Reserved3
Header Size field is 4 bytes long and must be 0x4C => 76
CLSID is 00021401-0000-0000-c000-000000000046
ShowCommand easily specifies how the Window is displayed Normal, Minimized, Maximized.
Hotkey is easly to understand, specifies the Hotkey that can be used to call the lnk

One of the most interesting field is LinkFlags, that specifies what link structures are present into the shortcut file, here the two possible values:

  • HasLinkTargetIDList -> value ‘A’
  • HasLinkInfo -> value ‘B’
  • HasName
  • HasRelativePath
  • HasWorkingDir
  • HasArguments
  • HasIconLocation
  • IsUnicode
  • ForceNoLinkInfo
  • HasExpString
  • RunInSeparateProcess
  • Unused
  • HasDarwinId
  • RunAsUser
  • etc.
One of the most important Flag is HasLinkTargetIDList that declares the presence of another important structure, LinkTargetIDList.
LinkTargetIDList is divided into two fields:
  • IDListSize
  • IDList
IDList specifies a list of ItemIDs, each ItemID contains the Effective Data. An ItemID is composed by two fields:
  • ItemIDSize
  • Data Block
IDList and associated ItemIDs are Object Identifiers necessary to locate and identify all Shell Objects, like:

  • Files
  • Directories
  • Servers
  • Workgroups
  • etc

Technically these Identifiers are represented by SHITEMID structure declared in Shtypes.h

typedef struct _SHITEMID {
USHORT cb;
BYTE abID[1];
} SHITEMID;

ItemID can be processed by using the interface IShellFolder or IShellLink::GetIDList() method.

The second important flag is HasLinkInfo, because declares the presence of LinkInfo structure. This structure specifies informations necessary to resolve the link target if is not found in its original location. Here the fields:

  • LinkInfoSize
  • LinkInfoHeaderSize
  • LinkInfoFlags
  • VolumeIDOffset
  • LocalBasePathOffset
  • CommonNetworkRelativeOffset
  • CommonNetworkRelativeLinkOffset
  • CommonPathSuffixOffset
  • LocalBasePathOffsetUnicode
  • CommonPathSuffixOffsetUnicode
Between the various fields one of the most interesting is the VolumeID, that specifies informations about the volume that a link target was on when link target was created.

The Third important structure is StringData that refers to a set of structures that contain path identification informations.

String Data = NameString – RelativePath – WorkingDir – CmdLineArguments – IconLocation

The last important structure, ExtraData that is appended at the end of lnk file, contains extra informations stored as Augmented Backus-Naur Form (ABNF -> rfc 5234 )

At this point we have a complete view of Shell Link binary structure, we can now how this file is used and how to manage it.

When an user executes a lnk file, Windows is going to perform a Link Resolution, essentially by using IShellLink::Resolve() method that attempts to find the target specified by the Shell Link, this operation is accomplished by using a pointer to the already seen structure IDList. When resolution fails system calls another service, called DLT ( Distributed Link Tracking and Object Identifiers ).

Should be clear that at this point lnk information carving could be performed at two level of abstraction:

  • Via COM Interfaces
  • Raw Parsing by Mapping lnk file
Via COM Interfaces can be used the methods listed here
http://msdn.microsoft.com/en-us/library/bb774950%28v=VS.85%29.aspx
IShellLink gives informations about Arguments, IDLists, Path and Working Directory.
IShellFolder gives some more detailed information on Objects and offers methods for Object Enumeration.
http://msdn.microsoft.com/en-us/library/bb775075%28VS.85%29.aspx
But as you can see something is missing, I’m talking about header informations, let’s see how appears from an hex dump:
In evidence the Header 4C bytes long, that obviously ends at offset 4C. HeaderSize is 4 bytes long, immediately after we have the 16 bytes long CLSID.
LinkFlags is immediately after CLSID, so 4bytes + 16 bytes = 20 bytes -> 0×14 is the offset of LinkFlags that’s 4bytes long.
FileAttributes-> 4bytes long and starts @offset 0×18
Now we have the three file time fields stored as FILETIME Struct
CreationTime-> 8bytes long @offset 0x1C
AccessTime-> 8bytes long @offset 0×24
ModificationTime-> 8bytes long @offset 0x2C
Now is trivial to build a python script, that show lnk characteristics; thanks to libforensics things are really easy, because there is a module that deals directly with Shell Link Binary Format, I’m talking about:
lf.win.shell.link module, here a quick sample that I’ve coded on fly, this script show header informations that are not given by COM Interfaces:
+————————————————————————–+
# Raw LNK Parser based on LibForensics library

from optparse import OptionParser
from datetime import datetime

from lf.dec import RawIStream, ByteIStream
from lf.win.shell.link import ShellLink

def main():
usage = “%prog lnkFileName”
description = “Displays Header Informations of an Lnk Binary File \n”

parser = OptionParser(usage = usage, description = description,
version = “0.1″)

(options, args) = parser.parse_args()

if len(args) < 1:
print(“You must specify a *.lnk file \n”)
else:
lnk = ShellLink(RawIStream(args[0]))

print(“Header Informations on: “,args[0], “\n”)

header = lnk.header
ctime = format_timestamp(header.btime)
atime = format_timestamp(header.atime)
mtime = format_timestamp(header.mtime)

print(“Header Size: “, header.size, “\n”)
print(“CLSID: “, header.clsid, “\n”)
print(“CreationTime: “, ctime, “\n”)
print(“AccessTime: “, atime, “\n”)
print(“ModificationTime: “, mtime, “\n”)
print(“Target Size:”, header.target_size, “\n”)
print(“Icon Index: “, header.icon_index, “\n”)

def format_timestamp(timestamp):
if isinstance(timestamp, datetime):
new_timestamp = timestamp.isoformat(” “)
else:
new_timestamp = timestamp
# end if

return new_timestamp

if __name__ == “__main__”:
main()
+————————————————————————–+
Let’s now observe the hex dump structure of LinkTargetIDList:
The Structure is clear we have the IDList size that specifies the whole size and successively it’s specified an ItemIDSize and immediately attached the Data, and after the next [ItemIDSize][Data]
IDList can be processed and enumerated by using again LibForensics by using ShellLink’s  idlist.
LinkInfo can be examined by using link_info
StringData can be examined by using string_data
ExtraData can be examined by using extra_data
Here the complete informations of the malicious lnk, obtained with linkinfo.py
+———————————————————————+
Command Line : test.lnk
File: test.lnk
Shell Link Header
=================
Header size: 76
CLSID: 00021401-0000-0000-c000-000000000046
Creation time: 1601-01-01 00:00:00
Access time: 1601-01-01 00:00:00
Modification time: 1601-01-01 00:00:00
Target size: 0
Icon index: 0
Show command: SW_SHOWNORMAL (0×1)
Hotkey: 0:0
Link Flags:
———–
Has link target idlist: True
Has link info: False
Has name: False
Has relative path: False
Has working directory: False
Has arguments: False
Has icon location: False
Is unicode: True
Force no link info: False
Has exp. string: False
Run in separate process: False
Has logo3 id: False
Has darwin id: False
Run as user: False
Has exp. icon: False
No pidl alias: False
Force UNC name: False
Run with shim layer: False
Force no link track: False
Enable target metadata: False
Disable link path tracking: False
Disable known folder tracking: False
Disable known folder alias: False
Allow link to link: False
Prefer environment path: False
Keep local idlist for UNC target: False
File Attributes:
—————-
Read only: False
Hidden: False
System: False
Directory: False
Archive: False
Normal: False
Temp: False
Sparse: False
Reparse point: False
Compressed: False
Offline: False
Not content indexed: False
Encrypted: False
Link Target IDList
==================
Byte count: 20
Data: b’\x1fP\xe0O\xd0 \xea:i\x10\xa2\xd8\x08\x00+’

Byte count: 20
Data: b’.\x1e  \xec!\xea:i\x10\xa2\xdd\x08\x00+’

Byte count: 268
Data: b’\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00j\x00\x00\x00′
Byte count: 0
Data: Not in file
+———————————————————————+
In red you can see the elements that constitutes evidences of the malicious nature of the lnk.
Microsoft decided to close the Specifications of Shell Link Format, this blog post is a little abstract of the structure of lnk files, with some other collateral information. Lnk need more and more analysis and research, with these informations and with the help of python scripting is also trivial to build a Lnk Fuzzer to further investigate new possible vulnerabilities.
See you to the next post,
Giuseppe ‘Evilcry’ Bonfa

Tags: , , , , ,

Friday, August 6th, 2010 Uncategorized No Comments