Improve visual indentation logic for tables

This commit is contained in:
adfoster-r7 2024-02-16 23:06:39 +00:00
parent 4af5c5438f
commit d76dd4a7fb
4 changed files with 104 additions and 102 deletions

View File

@ -426,7 +426,7 @@ GEM
rex-socket
rex-text
rex-struct2 (0.1.4)
rex-text (0.2.53)
rex-text (0.2.56)
rex-zip (0.1.5)
rex-text
rexml (3.2.6)

View File

@ -401,6 +401,7 @@ class DNS
'Prefix' => "\n",
'Postfix' => "\n",
'Columns' => ['Hostname', 'IP Address', 'Rule #', 'Rule', 'Resolver', 'Comm channel'],
'ColProps' => { 'Hostname' => { 'Strip' => false } },
'SortIndex' => -1,
'WordWrap' => false
)
@ -631,6 +632,7 @@ class DNS
'Prefix' => "\n",
'Postfix' => "\n",
'Columns' => ['Hostname', 'IPv4 Address', 'IPv6 Address'],
'ColProps' => { 'Hostname' => { 'Strip' => false } },
'SortIndex' => -1,
'WordWrap' => false
)
@ -654,11 +656,7 @@ class DNS
Rex::Proto::DNS::UpstreamResolver::Type::SYSTEM.to_s.downcase
].freeze
# XXX: By default rex-text tables strip preceding whitespace:
# https://github.com/rapid7/rex-text/blob/1a7b63993
# ca62fd9102665d6986f918ae42cae244e/lib/rex/text/table.rb#L221-L222
# So use https://en.wikipedia.org/wiki/Non-breaking_space as a workaround for now. A change should exist in Rex-Text to support this requirement
TABLE_INDENT = "\xc2\xa0\xc2\xa0\\_ ".freeze
TABLE_INDENT = " \\_ ".freeze
#
# Get user-friendly text for displaying the session that this entry would go through
@ -685,6 +683,7 @@ class DNS
def print_dns_set(heading, result_set, ids: [])
return if result_set.length == 0
columns = ['#', 'Rule', 'Resolver', 'Comm channel']
col_props = { 'Rule' => { 'Strip' => false } }
tbl = Table.new(
Table::Style::Default,
@ -692,6 +691,7 @@ class DNS
'Prefix' => "\n",
'Postfix' => "\n",
'Columns' => columns,
'ColProps' => col_props,
'SortIndex' => -1,
'WordWrap' => false
)

View File

@ -543,10 +543,7 @@ module Msf
show_child_items = total_children_rows > 1
next unless show_child_items
# XXX: By default rex-text tables strip preceding whitespace:
# https://github.com/rapid7/rex-text/blob/1a7b639ca62fd9102665d6986f918ae42cae244e/lib/rex/text/table.rb#L221-L222
# So use https://en.wikipedia.org/wiki/Non-breaking_space as a workaround for now. A change should exist in Rex-Text to support this requirement
indent = "\xc2\xa0\xc2\xa0\\_ "
indent = " \\_ "
# Note: We still use visual indicators for blank values as it's easier to read
# We can't always use a generic formatter/styler, as it would be applied to the 'parent' rows too
blank_value = '.'
@ -1804,6 +1801,7 @@ module Msf
]
},
'Name' => {
'Strip' => false,
'Stylers' => [Msf::Ui::Console::TablePrint::HighlightSubstringStyler.new(search_terms)]
},
'Check' => {

View File

@ -1,7 +1,6 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Msf::Ui::Console::CommandDispatcher::Creds do
if ENV['REMOTE_DB']
@ -67,52 +66,55 @@ RSpec.describe Msf::Ui::Console::CommandDispatcher::Creds do
context 'when the credential is present' do
it 'should show a user that matches the given expression' do
creds.cmd_creds('-u', username)
expect(@output).to eq([
'Credentials',
'===========',
'',
'host origin service public private realm private_type JtR Format cracked_password',
'---- ------ ------- ------ ------- ----- ------------ ---------- ----------------',
' thisuser thispass Password '
])
expect(@output.join("\n")).to match_table <<~TABLE
Credentials
===========
host origin service public private realm private_type JtR Format cracked_password
---- ------ ------- ------ ------- ----- ------------ ---------- ----------------
thisuser thispass Password
TABLE
end
it 'should not match a regular expression' do
creds.cmd_creds('-u', "^#{username}$")
expect(@output).to_not eq([
'Credentials',
'===========',
'',
'host origin service public private realm private_type JtR Format cracked_password',
'---- ------ ------- ------ ------- ----- ------------ ---------- ----------------',
' thisuser thispass Password '
])
expect(@output.join("\n")).to match_table <<~TABLE
Credentials
===========
host origin service public private realm private_type JtR Format cracked_password
---- ------ ------- ------ ------- ----- ------------ ---------- ----------------
TABLE
end
context 'and when the username is blank' do
it 'should show a user that matches the given expression' do
creds.cmd_creds('-u', blank_username)
expect(@output).to eq([
'Credentials',
'===========',
'',
'host origin service public private realm private_type JtR Format cracked_password',
'---- ------ ------- ------ ------- ----- ------------ ---------- ----------------',
' nonblank_pass Password '
])
expect(@output.join("\n")).to match_table <<~TABLE
Credentials
===========
host origin service public private realm private_type JtR Format cracked_password
---- ------ ------- ------ ------- ----- ------------ ---------- ----------------
nonblank_pass Password
TABLE
end
end
context 'and when the password is blank' do
it 'should show a user that matches the given expression' do
creds.cmd_creds('-P', blank_password)
expect(@output).to eq([
'Credentials',
'===========',
'',
'host origin service public private realm private_type JtR Format cracked_password',
'---- ------ ------- ------ ------- ----- ------------ ---------- ----------------',
' nonblank_user Password '
])
expect(@output.join("\n")).to match_table <<~TABLE
Credentials
===========
host origin service public private realm private_type JtR Format cracked_password
---- ------ ------- ------ ------- ----- ------------ ---------- ----------------
nonblank_user Password
TABLE
end
end
end
@ -121,25 +123,27 @@ RSpec.describe Msf::Ui::Console::CommandDispatcher::Creds do
context 'due to a nonmatching username' do
it 'should return a blank set' do
creds.cmd_creds('-u', nomatch_username)
expect(@output).to eq([
'Credentials',
'===========',
'',
'host origin service public private realm private_type JtR Format cracked_password',
'---- ------ ------- ------ ------- ----- ------------ ---------- ----------------'
])
expect(@output.join("\n")).to match_table <<~TABLE
Credentials
===========
host origin service public private realm private_type JtR Format cracked_password
---- ------ ------- ------ ------- ----- ------------ ---------- ----------------
TABLE
end
end
context 'due to a nonmatching password' do
it 'should return a blank set' do
creds.cmd_creds('-P', nomatch_password)
expect(@output).to eq([
'Credentials',
'===========',
'',
'host origin service public private realm private_type JtR Format cracked_password',
'---- ------ ------- ------ ------- ----- ------------ ---------- ----------------'
])
expect(@output.join("\n")).to match_table <<~TABLE
Credentials
===========
host origin service public private realm private_type JtR Format cracked_password
---- ------ ------- ------ ------- ----- ------------ ---------- ----------------
TABLE
end
end
context 'showing new column of cracked_password for all the cracked passwords' do
@ -158,25 +162,26 @@ RSpec.describe Msf::Ui::Console::CommandDispatcher::Creds do
realm: nil,
workspace: framework.db.workspace)
creds.cmd_creds('-u', 'this_username')
expect(@output).to eq([
"Credentials",
"===========",
"",
"host origin service public private realm private_type JtR Format cracked_password",
"---- ------ ------- ------ ------- ----- ------------ ---------- ----------------",
" this_username some_hash Nonreplayable hash this_cracked_password"
])
expect(@output.join("\n")).to match_table <<~TABLE
Credentials
===========
host origin service public private realm private_type JtR Format cracked_password
---- ------ ------- ------ ------- ----- ------------ ---------- ----------------
this_username some_hash Nonreplayable hash this_cracked_password
TABLE
end
it "should show the user given passwords on private column instead of cracked_password column" do
creds.cmd_creds('-u', 'thisuser')
expect(@output).to eq([
"Credentials",
"===========",
"",
"host origin service public private realm private_type JtR Format cracked_password",
"---- ------ ------- ------ ------- ----- ------------ ---------- ----------------",
" thisuser thispass Password "
])
expect(@output.join("\n")).to match_table <<~TABLE
Credentials
===========
host origin service public private realm private_type JtR Format cracked_password
---- ------ ------- ------ ------- ----- ------------ ---------- ----------------
thisuser thispass Password
TABLE
end
end
end
@ -238,15 +243,15 @@ RSpec.describe Msf::Ui::Console::CommandDispatcher::Creds do
context 'password' do
it 'should show just the password' do
creds.cmd_creds('-t', 'password')
# Table matching really sucks
expect(@output).to eq([
'Credentials',
'===========',
'',
'host origin service public private realm private_type JtR Format cracked_password',
'---- ------ ------- ------ ------- ----- ------------ ---------- ----------------',
' thisuser thispass Password '
])
expect(@output.join("\n")).to match_table <<~TABLE
Credentials
===========
host origin service public private realm private_type JtR Format cracked_password
---- ------ ------- ------ ------- ----- ------------ ---------- ----------------
thisuser thispass Password
TABLE
end
it 'should show all the cores whose private is either password or the private is cracked password' do
common_public = FactoryBot.create(:metasploit_credential_username, username: "this_username")
@ -263,15 +268,16 @@ RSpec.describe Msf::Ui::Console::CommandDispatcher::Creds do
realm: nil,
workspace: framework.db.workspace)
creds.cmd_creds('-t', 'password')
expect(@output).to eq([
"Credentials",
"===========",
"",
"host origin service public private realm private_type JtR Format cracked_password",
"---- ------ ------- ------ ------- ----- ------------ ---------- ----------------",
" thisuser thispass Password ",
" this_username this_cracked_password Password "
])
expect(@output.join("\n")).to match_table <<~TABLE
Credentials
===========
host origin service public private realm private_type JtR Format cracked_password
---- ------ ------- ------ ------- ----- ------------ ---------- ----------------
thisuser thispass Password
this_username this_cracked_password Password
TABLE
end
end
@ -280,15 +286,15 @@ RSpec.describe Msf::Ui::Console::CommandDispatcher::Creds do
skip 'Weird uniqueness constraint on Core (workspace_id, public_id)'
creds.cmd_creds('-t', 'ntlm')
# Table matching really sucks
expect(@output).to =~ [
'Credentials',
'===========',
'',
'host service public private realm private_type JtR Format cracked_password',
'---- ------- ------ ------- ----- ------------ ---------- ----------------',
" thisuser #{ntlm_hash} NTLM hash"
]
expect(@output.join("\n")).to match_table <<~TABLE
Credentials
===========
host origin service public private realm private_type JtR Format cracked_password
---- ------ ------- ------ ------- ----- ------------ ---------- ----------------
thisuser 1443d06412d8c0e6e72c57ef50f76a05:27c433245e4763d074d30a05aae0af2c NTLM hash
TABLE
end
end
end
@ -522,8 +528,6 @@ RSpec.describe Msf::Ui::Console::CommandDispatcher::Creds do
expect { create_core_with_login }.to change { Mdm::Host.count }.by 1
end
end
end
end
end