-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Latest changes from defcon russia for dns transport #23
base: rebase-defcon_ru-dns_transport
Are you sure you want to change the base?
Latest changes from defcon russia for dns transport #23
Conversation
max3raza
commented
Sep 19, 2017
•
edited
Loading
edited
- Removing debug messages like puts("something...")
- Removed duplicated "transport_config_reverse_dns" definition
- Changed default string for SERVER_ID
- Timeout setup for transport as for other transports
- Latest changes from defcon russia
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Getting this merged and run-tested this week, please pardon the delay - somewhat swamped.
|
||
while (stime + ctimeout > Time.now.to_i) | ||
begin | ||
client = Rex::Socket::Tcp.create( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might as well use UDP here if we're instantiating a socket for every call. If i can get native DNS to work, this wont be an issue, but session-channels may be an appropriate mechanism for this proxy semantic.
# @return [OptAddress] | ||
def self.DOMAIN(default=nil, required=true, desc="Domain name") | ||
Msf::OptString.new(__method__.to_s, [ required, desc, default ]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clever hackery, not sure if this is the best way to implement since every module load would instantiate these opts for every domain name. Also not sure about using a name such as "default" for anything. Still though, clever :)
|
||
# @return [OptEnum] | ||
def self.REQ_TYPE(default=nil, required=true, desc="Domain name") | ||
Msf::OptEnum.new(__method__.to_s, [ required, desc, 'DNSKEY', ['IPv6', 'DNSKEY']]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
^^
def stage_over_connection? | ||
false | ||
end | ||
#def stage_over_connection? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the change to an HTTP payload?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Round 2 of review. Merge testing ongoing presently.
OptAddress.new('RHOST', [true, 'HANDLER BIND IP', '']), | ||
OptString.new('SERVER_ID', [true, 'SERVER ID', 'toor']), | ||
OptEnum.new('REQ_TYPE', [ true, 'Type of DNS tunnel', 'DNSKEY', ['IPv6', 'DNSKEY']]), | ||
OptAddress.new('RHOST', [true, 'DNX PROXY IP', '']), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"DNS proxy IP" - though i suggest "DNS Server IP" since i'm working toward a native handler as well
client = nil | ||
|
||
print_status("Started bind handler") | ||
print_status("Started bind-DNS handler") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DNS-proxy handler?
|
||
# Only try the same host/port combination once | ||
phash = rhost + ':' + lport.to_s | ||
return if self.listener_pairs[phash] | ||
self.listener_pairs[phash] = true | ||
|
||
# Start a new handling thread | ||
self.listener_threads << framework.threads.spawn("BindTcpHandlerListener-#{lport}", false) { | ||
self.listener_threads << framework.threads.spawn("BindTcpHandlerListener-#{lport}", false) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DnsProxyHandler?
#If last connection has a valid session or died | ||
if (framework.sessions.length > 0) | ||
|
||
framework.sessions.each_sorted do |k| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit confused on the logic here - you end up with "session" being the last session in the sorted list, so why not just sessions.sort.last?
opts = { | ||
:datastore => datastore, | ||
:expiration => datastore['SessionExpirationTimeout'].to_i, | ||
:comm_timeout => 60*60*24, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest pulling this from the datastore - tunable.
# Start a new thread and pass the client connection | ||
# as the input and output pipe. Client's are expected | ||
# to implement the Stream interface. | ||
conn_threads << framework.threads.spawn("BindDnsHandlerSession", false, client) { |client_copy| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
client_copy is a bit of a misnomer here - its the original object being passed into the thread. Example:
2.4.2 :001 > a = []; Thread.new(a) {|b| b << 1}
=> #<Thread:0x00000033659320b8@(irb):1 run>
2.4.2 :002 > a
=> [1]
If you dont want the original object, client.clone/dup/etc does the trick
#SEND SERVER_ID | ||
client_copy.put([server_id.length].pack("C") + server_id) | ||
conn = client_copy | ||
#First connect, stage is needed? (or it not the first session and stage alredy there.. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm thinking there's a more graceful way to do this (and i dont just mean replacing strings with symbols)... will get back to this once i have a rational plan :).