Skip to content
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

Fix get_processes for some shell sessions #15328

Merged
merged 1 commit into from
Jun 10, 2021

Conversation

zeroSteiner
Copy link
Contributor

@zeroSteiner zeroSteiner commented Jun 10, 2021

This fixes instances where #shell_read_until_token would fail to return any output because the random token is included in the output. Since the token is random, this is very unlikely to happen with one exception and that is listing out processes. When the ps aux command is run, such as by the get_processes method, the command that executed it, including the random token as an argument, will be included in the response. This effectively breaks get_processes for shell commands where the ps aux command behaves this way.

From my testing, it looks like the native Linux shell payloads are not affected by this, presumably because their environment variables are different. This can be verified by running session.shell_command_token('env') and comparing it to other sessions.

The python/shell_reverse_tcp payload does appear to be affected by this issue however.

The proposed solution here is to leverage the fact that when the ending token is echoed, it will be directly preceded by a newline which is omitted when the token itself is returned in the output as part of the ps aux command.

Verification

List the steps needed to make sure this thing works

  • Start msfconsole
  • Obtain a session on a Linux host using the python/shell_reverse_tcp payload
    • The exploit/multi/sshexec module works nicely for this, or just generate a payload and run it, that works too
  • Drop into pry and run sessions[#].shell_command_token('ps aux'), see output

Issue Example

Notice how both sessions are on the same host, but the env lines is different.

msf6 > sessions

Active sessions
===============

  Id  Name  Type                 Information  Connection
  --  ----  ----                 -----------  ----------
  1         shell x64/linux                   192.168.159.128:4444 -> 192.168.159.115:37556 (192.168.159.115)
  4         shell python/python               192.168.159.128:4444 -> 192.168.159.115:37560 (192.168.159.115)

msf6 > pry
[*] Starting Pry shell...
[*] You are in the "framework" object

[1] pry(#<Msf::Framework>)> sessions[1].shell_command_token('env').split("\n").length
=> 1
[2] pry(#<Msf::Framework>)> sessions[1].shell_command_token('ps aux').length
=> 14814
[3] pry(#<Msf::Framework>)> sessions[4].shell_command_token('env').split("\n").length
=> 14
[4] pry(#<Msf::Framework>)> sessions[4].shell_command_token('ps aux').length
NoMethodError: undefined method `length' for nil:NilClass
from (pry):45:in `__pry__'
[5] pry(#<Msf::Framework>)> 

@gwillcox-r7
Copy link
Contributor

Note the testing steps are somewhat wrong. After you get a session you have to type back until you get to just a msf6 > prompt, otherwise session will not be a recognized variable since you aren't operating under the framework object.

@gwillcox-r7
Copy link
Contributor

Tests look good, first part is when the fix is applied, showing the output is returned properly. Other part is the output from master showing that running the ps aux command throws an error and doesn't return results. Whilst its not possible to show it here, its also interesting to note that with the patch things run faster as well.

msf6 > sessions

Active sessions
===============

  Id  Name  Type                 Information  Connection
  --  ----  ----                 -----------  ----------
  1         shell python/python               127.0.0.1:4444 -> 127.0.0.1:50444 (127.0.0.1)

msf6 > pry
[*] Starting Pry shell...
[*] You are in the "framework" object

[1] pry(#<Msf::Framework>)> sessions[1].shell_command_token('env').split("\n").length
=> 92
[2] pry(#<Msf::Framework>)> sessions[1].shell_command_token('ps aux').length
=> 45610
[3] pry(#<Msf::Framework>)> exit
msf6 > exit
[*] You have active sessions open, to exit anyway type "exit -y"
msf6 > sessions -K
[*] Killing all sessions...
[*] 127.0.0.1 - Command shell session 1 closed.
msf6 > exit
 ~/git/metasploit-framework │ land-pr15328:pr/15328 ?5  git checkout master                               ✔ │ 9m 27s │ 2.7.2 Ruby 
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
 ~/git/metasploit-framework │ master ?5  ./msfconsole                                                              ✔ │ 2.7.2 Ruby 
[-] No local database connected, meaning some Metasploit features will not be available. A full list of the affected features & database setup instructions can be found here: https://github.com/rapid7/metasploit-framework/wiki/msfdb:-Database-Features-&-How-to-Set-up-a-Database-for-Metasploit
[!] The following modules could not be loaded!..\
[!] 	/home/gwillcox/git/metasploit-framework/modules/auxiliary/gather/office365userenum.py
[!] Please see /home/gwillcox/.msf4/logs/framework.log for details.
                                                  

*Neutrino_Cannon*PrettyBeefy*PostalTime*binbash*deadastronauts*EvilBunnyWrote*L1T*Mail.ru*() { :;}; echo vulnerable*
*Team sorceror*ADACTF*BisonSquad*socialdistancing*LeukeTeamNaam*OWASP Moncton*Alegori*exit*Vampire Bunnies*APT593*
*QuePasaZombiesAndFriends*NetSecBG*coincoin*ShroomZ*Slow Coders*Scavenger Security*Bruh*NoTeamName*Terminal Cult*
*edspiner*BFG*MagentaHats*0x01DA*Kaczuszki*AlphaPwners*FILAHA*Raffaela*HackSurYvette*outout*HackSouth*Corax*yeeb0iz*
*SKUA*Cyber COBRA*flaghunters*0xCD*AI Generated*CSEC*p3nnm3d*IFS*CTF_Circle*InnotecLabs*baadf00d*BitSwitchers*0xnoobs*
*ItPwns - Intergalactic Team of PWNers*PCCsquared*fr334aks*runCMD*0x194*Kapital Krakens*ReadyPlayer1337*Team 443*
*H4CKSN0W*InfOUsec*CTF Community*DCZia*NiceWay*0xBlueSky*ME3*Tipi'Hack*Porg Pwn Platoon*Hackerty*hackstreetboys*
*ideaengine007*eggcellent*H4x*cw167*localhorst*Original Cyan Lonkero*Sad_Pandas*FalseFlag*OurHeartBleedsOrange*SBWASP*
*Cult of the Dead Turkey*doesthismatter*crayontheft*Cyber Mausoleum*scripterz*VetSec*norbot*Delta Squad Zero*Mukesh*
*x00-x00*BlackCat*ARESx*cxp*vaporsec*purplehax*RedTeam@MTU*UsalamaTeam*vitamink*RISC*forkbomb444*hownowbrowncow*
*etherknot*cheesebaguette*downgrade*FR!3ND5*badfirmware*Cut3Dr4g0n*dc615*nora*Polaris One*team*hail hydra*Takoyaki*
*Sudo Society*incognito-flash*TheScientists*Tea Party*Reapers of Pwnage*OldBoys*M0ul3Fr1t1B13r3*bearswithsaws*DC540*
*iMosuke*Infosec_zitro*CrackTheFlag*TheConquerors*Asur*4fun*Rogue-CTF*Cyber*TMHC*The_Pirhacks*btwIuseArch*MadDawgs*
*HInc*The Pighty Mangolins*CCSF_RamSec*x4n0n*x0rc3r3rs*emehacr*Ph4n70m_R34p3r*humziq*Preeminence*UMGC*ByteBrigade*
*TeamFastMark*Towson-Cyberkatz*meow*xrzhev*PA Hackers*Kuolema*Nakateam*L0g!c B0mb*NOVA-InfoSec*teamstyle*Panic*
*B0NG0R3*                                                                                    *Les Cadets Rouges*buf*
*Les Tontons Fl4gueurs*                                                                      *404 : Flag Not Found*
*' UNION SELECT 'password*      _________                __                                  *OCD247*Sparkle Pony* 
*burner_herz0g*                 \_   ___ \_____  _______/  |_ __ _________   ____            *Kill$hot*ConEmu*
*here_there_be_trolls*          /    \  \/\__  \ \____ \   __\  |  \_  __ \_/ __ \           *;echo"hacked"*
*r4t5_*6rung4nd4*NYUSEC*        \     \____/ __ \|  |_> >  | |  |  /|  | \/\  ___/           *karamel4e*
*IkastenIO*TWC*balkansec*        \______  (____  /   __/|__| |____/ |__|    \___  >          *cybersecurity.li*
*TofuEelRoll*Trash Pandas*              \/     \/|__|                           \/           *OneManArmy*cyb3r_w1z4rd5*
*Astra*Got Schwartz?*tmux*                  ___________.__                                   *AreYouStuck*Mr.Robot.0*
*\nls*Juicy white peach*                    \__    ___/|  |__   ____                         *EPITA Rennes*
*HackerKnights*                               |    |   |  |  \_/ __ \                        *guildOfGengar*Titans*
*Pentest Rangers*                             |    |   |   Y  \  ___/                        *The Libbyrators*
*placeholder name*bitup*                      |____|   |___|  /\___  >                       *JeffTadashi*Mikeal*
*UCASers*onotch*                                            \/     \/                        *ky_dong_day_song*
*NeNiNuMmOk*                              ___________.__                                     *JustForFun!*
*Maux de tête*LalaNG*                     \_   _____/|  | _____     ____                     *g3tsh3Lls0on*
*crr0tz*z3r0p0rn*clueless*                 |    __)  |  | \__  \   / ___\                    *Phở Đặc Biệt*Paradox*
*HackWara*                                 |     \   |  |__/ __ \_/ /_/  >                   *KaRIPux*inf0sec*
*Kugelschreibertester*                     \___  /   |____(____  /\___  /                    *bluehens*Antoine77*
*icemasters*                                   \/              \//_____/                     *genxy*TRADE_NAMES*
*Spartan's Ravens*                       _______________   _______________                   *BadByte*fontwang_tw*
*g0ldd1gg3rs*pappo*                     \_____  \   _  \  \_____  \   _  \                   *ghoti*
*Les CRACKS*c0dingRabbits*               /  ____/  /_\  \  /  ____/  /_\  \                  *LinuxRiders*   
*2Cr4Sh*RecycleBin*                     /       \  \_/   \/       \  \_/   \                 *Jalan Durian*
*ExploitStudio*                         \_______ \_____  /\_______ \_____  /                 *WPICSC*logaritm*
*Car RamRod*0x41414141*                         \/     \/         \/     \/                  *Orv1ll3*team-fm4dd*
*Björkson*FlyingCircus*                                                                      *PwnHub*H4X0R*Yanee*
*Securifera*hot cocoa*                                                                       *Et3rnal*PelarianCP*
*n00bytes*DNC&G*guildzero*dorko*tv*42*{EHF}*CarpeDien*Flamin-Go*BarryWhite*XUcyber*FernetInjection*DCcurity*
*Mars Explorer*ozen_cfw*Fat Boys*Simpatico*nzdjb*Isec-U.O*The Pomorians*T35H*H@wk33*JetJ*OrangeStar*Team Corgi*
*D0g3*0itch*OffRes*LegionOfRinf*UniWA*wgucoo*Pr0ph3t*L0ner*_n00bz*OSINT Punchers*Tinfoil Hats*Hava*Team Neu*
*Cyb3rDoctor*Techlock Inc*kinakomochi*DubbelDopper*bubbasnmp*w*Gh0st$*tyl3rsec*LUCKY_CLOVERS*ev4d3rx10-team*ir4n6*
*PEQUI_ctf*HKLBGD*L3o*5 bits short of a byte*UCM*ByteForc3*Death_Geass*Stryk3r*WooT*Raise The Black*CTErr0r*
*Individual*mikejam*Flag Predator*klandes*_no_Skids*SQ.*CyberOWL*Ironhearts*Kizzle*gauti*
*San Antonio College Cyber Rangers*sam.ninja*Akerbeltz*cheeseroyale*Ephyra*sard city*OrderingChaos*Pickle_Ricks*
*Hex2Text*defiant*hefter*Flaggermeister*Oxford Brookes University*OD1E*noob_noob*Ferris Wheel*Ficus*ONO*jameless*
*Log1c_b0mb*dr4k0t4*0th3rs*dcua*cccchhhh6819*Manzara's Magpies*pwn4lyfe*Droogy*Shrubhound Gang*ssociety*HackJWU*
*asdfghjkl*n00bi3*i-cube warriors*WhateverThrone*Salvat0re*Chadsec*0x1337deadbeef*StarchThingIDK*Tieto_alaviiva_turva*
*InspiV*RPCA Cyber Club*kurage0verfl0w*lammm*pelicans_for_freedom*switchteam*tim*departedcomputerchairs*cool_runnings*
*chads*SecureShell*EetIetsHekken*CyberSquad*P&K*Trident*RedSeer*SOMA*EVM*BUckys_Angels*OrangeJuice*DemDirtyUserz*
*OpenToAll*Born2Hack*Bigglesworth*NIS*10Monkeys1Keyboard*TNGCrew*Cla55N0tF0und*exploits33kr*root_rulzz*InfosecIITG*
*superusers*H@rdT0R3m3b3r*operators*NULL*stuxCTF*mHackresciallo*Eclipse*Gingabeast*Hamad*Immortals*arasan*MouseTrap*
*damn_sadboi*tadaaa*null2root*HowestCSP*fezfezf*LordVader*Fl@g_Hunt3rs*bluenet*P@Ge2mE*



       =[ metasploit v6.0.49-dev-9245293d4d               ]
+ -- --=[ 2139 exploits - 1138 auxiliary - 365 post       ]
+ -- --=[ 596 payloads - 45 encoders - 10 nops            ]
+ -- --=[ 8 evasion                                       ]

Metasploit tip: Use sessions -1 to interact with the 
last opened session

msf6 > use multi/handler
[*] Using configured payload generic/shell_reverse_tcp
msf6 exploit(multi/handler) > set payload python/shell_reverse_tcp
payload => python/shell_reverse_tcp
msf6 exploit(multi/handler) > set LHOST 127.0.0.1
LHOST => 127.0.0.1
msf6 exploit(multi/handler) > exploit

[!] You are binding to a loopback address by setting LHOST to 127.0.0.1. Did you want ReverseListenerBindAddress?
[*] Started reverse TCP handler on 127.0.0.1:4444 
[*] Command shell session 1 opened (127.0.0.1:4444 -> 127.0.0.1:50474) at 2021-06-10 16:35:09 -0500

^Z
Background session 1? [y/N]  y  
msf6 exploit(multi/handler) > back
msf6 > pry
[*] Starting Pry shell...
[*] You are in the "framework" object

[1] pry(#<Msf::Framework>)> sessions[1].shell_command_token('ps aux').length
NoMethodError: undefined method `length' for nil:NilClass
from (pry):1:in `__pry__'
[2] pry(#<Msf::Framework>)> 

@gwillcox-r7 gwillcox-r7 added the rn-fix release notes fix label Jun 10, 2021
@gwillcox-r7 gwillcox-r7 merged commit e07561c into rapid7:master Jun 10, 2021
@gwillcox-r7
Copy link
Contributor

gwillcox-r7 commented Jun 10, 2021

Release Notes

The lib/msf/core/session/provider/single_command_shell.rb library has been updated to address an issue whereby shell_read_until_token may sometimes fail to return output if the randomized token being used to delimit output is contained within the legitimate output as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug library rn-fix release notes fix
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants