mirror of
https://github.com/rapid7/metasploit-framework
synced 2024-11-12 11:52:01 +01:00
Networkpug improvements
git-svn-id: file:///home/svn/framework3/trunk@10484 4d416f70-5f16-0410-b530-b9f4589650da
This commit is contained in:
parent
1392ef78d7
commit
784e355d93
@ -132,7 +132,7 @@ NetworkPug *allocate_networkpug(char *interface)
|
||||
* Needs to be active for cleanup to proceed.
|
||||
*/
|
||||
|
||||
void free_networkpug(NetworkPug *np, int close_channel)
|
||||
void free_networkpug(NetworkPug *np, int close_channel, int destroy_channel)
|
||||
{
|
||||
int cont;
|
||||
|
||||
@ -175,9 +175,14 @@ void free_networkpug(NetworkPug *np, int close_channel)
|
||||
if(close_channel == TRUE) {
|
||||
// Tell the remote side we've shut down for now.
|
||||
channel_close(np->channel, np->remote, NULL, 0, NULL);
|
||||
}
|
||||
|
||||
if(destroy_channel == TRUE) {
|
||||
// the channel handler code will destroy it.
|
||||
// if we destroy it, it will end up double freeing
|
||||
// and calling abort :~(
|
||||
channel_destroy(np->channel, NULL);
|
||||
}
|
||||
|
||||
channel_destroy(np->channel, NULL); // channel_destroy does not look at packet it seems
|
||||
}
|
||||
|
||||
if(np->interface) {
|
||||
@ -234,13 +239,24 @@ DWORD networkpug_channel_write(Channel *channel, Packet *request,
|
||||
DWORD networkpug_channel_close(Channel *channel, Packet *request, LPVOID context)
|
||||
{
|
||||
int result = ERROR_SUCCESS;
|
||||
NetworkPug *np;
|
||||
|
||||
dprintf("[%s] Channel shutdown requested. context = %p", __FUNCTION__, context);
|
||||
dprintf("[%s] pugs is at %p, and pugs[MAX_PUGS] is %p", __FUNCTION__, pugs, pugs + MAX_PUGS);
|
||||
lock_acquire(pug_lock);
|
||||
|
||||
free_networkpug((NetworkPug *)(context), FALSE);
|
||||
np = (NetworkPug *)(context);
|
||||
|
||||
dprintf("[%s] closed channel successfully", __FUNCTION__);
|
||||
if(np->active) {
|
||||
dprintf("[%s] Channel shutdown requested. context = %p", __FUNCTION__, context);
|
||||
dprintf("[%s] pugs is at %p, and pugs[MAX_PUGS] is %p", __FUNCTION__, pugs, pugs + MAX_PUGS);
|
||||
|
||||
free_networkpug((NetworkPug *)(context), FALSE, FALSE);
|
||||
|
||||
dprintf("[%s] closed channel successfully", __FUNCTION__);
|
||||
} else {
|
||||
dprintf("[%s] Already closed down context %p", __FUNCTION__, context);
|
||||
}
|
||||
|
||||
lock_release(pug_lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -342,7 +358,7 @@ DWORD request_networkpug_start(Remote *remote, Packet *packet)
|
||||
|
||||
if(result != ERROR_SUCCESS) {
|
||||
np->active = 1;
|
||||
free_networkpug(np, FALSE);
|
||||
free_networkpug(np, FALSE, TRUE);
|
||||
}
|
||||
|
||||
lock_release(pug_lock);
|
||||
@ -379,7 +395,7 @@ DWORD request_networkpug_stop(Remote *remote, Packet *packet)
|
||||
}
|
||||
|
||||
dprintf("[%s] calling free_networkpug", __FUNCTION__);
|
||||
free_networkpug(np, TRUE);
|
||||
free_networkpug(np, TRUE, FALSE);
|
||||
|
||||
result = ERROR_SUCCESS;
|
||||
} while(0);
|
||||
|
@ -20,9 +20,18 @@ class Console::CommandDispatcher::NetworkPug
|
||||
)
|
||||
|
||||
def initialize(shell)
|
||||
@thread_stuff = nil
|
||||
@tapdev = nil
|
||||
@channel = nil
|
||||
|
||||
super
|
||||
end
|
||||
|
||||
attr_accessor :thread_stuff
|
||||
attr_accessor :tapdev
|
||||
attr_accessor :channel
|
||||
|
||||
|
||||
#
|
||||
# List of supported commands.
|
||||
#
|
||||
@ -64,44 +73,47 @@ class Console::CommandDispatcher::NetworkPug
|
||||
return nil, nil, nil
|
||||
end
|
||||
|
||||
def proxy_packets(tapdev, channel)
|
||||
def proxy_packets()
|
||||
while 1
|
||||
# Ghetto :\
|
||||
|
||||
sd = Rex::ThreadSafe.select([ channel.lsock, tapdev ], nil, nil)
|
||||
sd = Rex::ThreadSafe.select([ @channel.lsock, @tapdev ], nil, nil)
|
||||
|
||||
sd[0].each { |s|
|
||||
if(s == channel.lsock) # Packet from remote host to local TAP dev
|
||||
len = channel.lsock.read(2)
|
||||
if(s == @channel.lsock) # Packet from remote host to local TAP dev
|
||||
len = @channel.lsock.read(2)
|
||||
len = len.unpack('n')[0]
|
||||
|
||||
# print_line("Got #{len} bytes from remote host's network")
|
||||
#print_line("Got #{len} bytes from remote host's network")
|
||||
|
||||
if(len > 1514 or len == 0)
|
||||
tapdev.close()
|
||||
@tapdev.close()
|
||||
print_line("length is invalid .. #{len} ?, de-synchronized ? ")
|
||||
end
|
||||
|
||||
packet = channel.lsock.read(len)
|
||||
packet = @channel.lsock.read(len)
|
||||
|
||||
# print_line("remote from remote host:\n" + Rex::Text.hexify(packet))
|
||||
print_line("packet from remote host:\n" + Rex::Text.hexify(packet))
|
||||
|
||||
tapdev.syswrite(packet)
|
||||
@tapdev.syswrite(packet)
|
||||
|
||||
elsif(s == tapdev)
|
||||
elsif(s == @tapdev)
|
||||
# Packet from tapdev to remote host network
|
||||
|
||||
packet = tapdev.sysread(1514)
|
||||
packet = @tapdev.sysread(1514)
|
||||
|
||||
# print_line("packet to remote host:\n" + Rex::Text.hexify(packet))
|
||||
print_line("packet to remote host:\n" + Rex::Text.hexify(packet))
|
||||
|
||||
channel.write(packet)
|
||||
@channel.write(packet)
|
||||
end
|
||||
} if(sd)
|
||||
|
||||
if(not sd)
|
||||
print_line("hmmm. ")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def cmd_networkpug_start(*args)
|
||||
# PKS - I suck at ruby ;\
|
||||
|
||||
@ -114,7 +126,6 @@ class Console::CommandDispatcher::NetworkPug
|
||||
end
|
||||
|
||||
@@options.parse(args) { |opt, idx, val|
|
||||
|
||||
# print_line("before: #{opt} #{idx} #{val} || virtual nic: #{virtual_nic}, filter: #{filter}, interface: #{interface}")
|
||||
case opt
|
||||
when "-v"
|
||||
@ -142,9 +153,9 @@ class Console::CommandDispatcher::NetworkPug
|
||||
return
|
||||
end
|
||||
|
||||
tapdev, tapname, mac = setup_tapdev
|
||||
@tapdev, tapname, mac = setup_tapdev
|
||||
|
||||
if(tapdev == nil)
|
||||
if(@tapdev == nil)
|
||||
print_status("Failed to create tapdev")
|
||||
return
|
||||
end
|
||||
@ -152,35 +163,25 @@ class Console::CommandDispatcher::NetworkPug
|
||||
# PKS, we should implement multiple filter strings and let the
|
||||
# remote host build it properly.
|
||||
# not (our conn) and (virtual nic filter) and (custom filter)
|
||||
|
||||
# print_line("before virtual, filter is #{filter}")
|
||||
|
||||
if(filter == nil and virtual_nic == true)
|
||||
filter = "ether host #{mac}"
|
||||
elsif(filter != nil and virtual_nic == true)
|
||||
filter += " and ether host #{mac}"
|
||||
print_line("Adjusted filter is #{filter}")
|
||||
#print_line("Adjusted filter is #{filter}")
|
||||
end
|
||||
|
||||
# print_line("after virtual, filter is #{filter}")
|
||||
|
||||
print_line("#{tapname} created with a hwaddr of #{mac}, ctrl-c when done")
|
||||
|
||||
begin
|
||||
response, channel = client.networkpug.networkpug_start(interface, filter)
|
||||
response, @channel = client.networkpug.networkpug_start(interface, filter)
|
||||
|
||||
if(not channel)
|
||||
print_line("No channel? bailing")
|
||||
return
|
||||
end
|
||||
if(@channel)
|
||||
@thread_stuff = ::Thread.new {
|
||||
proxy_packets()
|
||||
}
|
||||
|
||||
|
||||
print_line("Forwarding packets between #{tapname} and remote host")
|
||||
proxy_packets(tapdev, channel)
|
||||
ensure
|
||||
tapdev.close()
|
||||
print_line("don't forget to networkpug_stop remote host as well")
|
||||
|
||||
print_line("Packet slinger for #{interface} has a thread structure of #{@thread_stuff}")
|
||||
end
|
||||
|
||||
return true
|
||||
@ -191,8 +192,18 @@ class Console::CommandDispatcher::NetworkPug
|
||||
if (interface == nil)
|
||||
print_error("Usage: networkpug_stop [interface]")
|
||||
return
|
||||
end
|
||||
|
||||
if(@thread_stuff)
|
||||
::Thread.kill(@thread_stuff)
|
||||
::Thread.join(@thread_stuff)
|
||||
|
||||
@thread_stuff = nil
|
||||
|
||||
@channel.close
|
||||
@tapdev.close
|
||||
end
|
||||
|
||||
|
||||
client.networkpug.networkpug_stop(interface)
|
||||
print_status("Packet slinging stopped on #{interface}")
|
||||
return true
|
||||
|
Loading…
Reference in New Issue
Block a user