Team LiB
Previous Section Next Section

5.3. Writing Exploits for MSF

Within the framework, each exploit module is a class. MSF dynamically creates an instance of the classes found in the exploits/ directory, as well as those found in $HOME/.msf/exploits/. These classes inherit from the Msf::Exploit class. The Msf::Exploit class has methods you can override in your exploit modules. Overriding a method is simple: declare a method with the same name as the method you want to override. The most common methods to override are Check() and Exploit( ) because these are the core actions your exploits will make. Exploit( ) is special because the framework will call it when a user requests that action from one of the MSF frontends. If the appropriate parameters are set, the payload will be generated using the selected payload, encoder, and NOP generator. Then the Exploit( ) method will be executed, followed by the payload handler, which is the only method that has special actions before and after execution. Check( ) acts in the same way, except it returns an appropriate error code. Table 5-4 provides a list of the methods available for overriding within your custom Exploit modules. These methods are aliases for key values you can set in either $info->Payload{} or $info->Nop{} hashes. If you have values that need to be chosen according to a variable situation, you might want to override the method instead of setting the hashes.

Table 5-4. Msf::Exploit methods that can be overridden

Method name

Method description

PayloadPrependEncoder

This is an alias for $info->{Payload}->{'PrependEncoder'}. This will be added to the final payload after the NOP sled, but before the decoder machine code.

PayloadPrepend

This is an alias for $info->{Payload}->{'Prepend'}. This will be added to the final payload directly before the shellcode, and before the encoding happens.

PayloadAppend

This is an alias for $info->{Payload}->{'Append'}. This will be added to the final payload directly after the shellcode, and before the encoding happens.

PayloadSpace

This is an alias for $info->{Payload}->{'Space'}. This is the total size of the payload: the NOP sled size plus the decoder size plus the encoded shellcode. The NOP sled will be adjusted according to the space size.

PayloadBadChars

This is an alias for $info->{Payload}->{'BadChars'}. These are the characters the encoder should avoid when generating an encoded payload. The encoder will always err on the side of safety by stopping the exploit if the characters cannot be avoided.

PayloadMinNops

This is an alias for $info->{Payload}->{'MinNops'}. This is the minimum size of the NOP sled. If an Encoder module attempts to generate a NOP sled smaller than this, the exploit will stop and will print an error.

PayloadMaxNops

This is an alias for $info->{Payload}->{'MaxNops'}. It is the maximum size of the NOP sled. If an Encoder module attempts to generate a NOP sled larger than this, the exploit will stop and will print an error.

NopSaveRegs

This is an alias for $info->{Nop}->{'SaveRegs'}. This is for the NOP modules to avoid generating NOP-equivalent instructions that affect the variables in this array. For example, if a socket file descriptor was being held in eax you wouldn't want to use the inc eax NOP equivalent.


As shown in the inheritance diagram in Figure 5-5, because your exploit modules will inherit from Msf::Exploit and its parent classes, you'll need to set %info and %advanced with metadata regarding what your exploit requires from the framework.

Figure 5-5. An inheritance diagram of major MSF components


For %info, you can set the following keys:


Name

Descriptive name for your module.


Version

Version number.


Authors

An array for listing the module's authors.


Arch

An array of the architectures your module supports.


OS

An array of the operating systems your module supports.


Priv

A Boolean that states whether your exploit yields privileged access on success.


UserOpts

A hash of arrays. The keys are the names of the options a user can set from a frontend. The first entry in the array is a Boolean that states whether the option is required or optional, the second entry is the variable type, the third is a short bit of descriptive text about the option, and the fourth is a default value. For example:

'UserOpts' =>{ 'RHOST' => [1, 'ADDR', 'The target address']}


Payload

A hash that contains options for the payload module. These options were detailed, along with the methods you can use to set them, in Table 5-4.


Nop

A hash. The SaveRegs key is an array of registers that the NOP generator should not damage when it uses NOP-equivalent generators.


Description

A description of your module: what it does, how reliable it is, warnings, and so on.


Refs

An array of references for you to exploit OSVDB pages, advisories, and so on.


Targets

An array of arrays for use in your exploit. The user will set the temporary environment variable TARGET to an integer you can use to index this array. The entries for the array are completely user-defined. If a specific target requires more or less information, you can modify the target accordingly. For example:

'Targets' => [ ['Linux Bruteforce', '0xbffffe13', '0xbfff0000']]


DefaultTarget

Sets the index in the info->{Targets} array that will be selected as the default.

The other important hash in your exploit modules is %advanced. This hash's keys are advanced options a user would not normally need to modify. Usually, these are for development or fine-grained, detailed configuration. The values comprise an array where the first entry is the default value and the second is a description of the value. Though the purpose of %UserOpts and %advanced is to set exploit parameters, they differ in terms of their behavior. The options in %UserOpts are given types (ADDR, PORT, etc.), and when the %UserOpts values are accessed, they are checked against their stated types for consistency. Because %advanced has no specific type declarations, any value can be set for it. Additionally, %advanced values are not required, and a given exploit should always execute regardless of advanced options being set.

Here is an example of how to declare user-controllable advanced options for an exploit that has a brute-forcing routine:

my $advanced = {
  'StackTop'     => ['', 'Start address for stack ret bruteforcing, empty for defaults from target'],
  'StackBottom'  => ['', 'End address for stack ret bruteforcing, empty for defaults from target'],
  'StackStep'    => [0, 'Step size for ret bruteforcing, 0 for auto calculation.'],
  'BruteWait'    => [.4, 'Length in seconds to wait between brute force attempts']}

An important concept in MSF is the environment system. This can be illustrated best with msfconsole. The variables that are created or modified using the set command are unique to each exploitthat is, they exist in a "temporary environment." Each exploit has a temporary and a global environment. The global variables are set using the setg command and persist across exploit module instantiation. To access these environment variables from exploit modules, use the GetVar() and GetLocal( ) methods. GetVar( ) will search for a variable in this order:

  1. The temporary environment

  2. The global environment

  3. SelfName::Variable (for making a module setting static within the context of an exploit module)

  4. A key in %advanced

  5. A key in %UserOpts

This hierarchy is important to remember. If a global environment variable exists, the temporary environment is searched first. If we explicitly want a module's local variable, we use GetLocal( ), because it has the same search order as GetVar( ) but does not search the global environment.

    Team LiB
    Previous Section Next Section