作者:[email protected]知道创宇404实验室
日期:2023年2月17日
漏洞介绍
漏洞环境搭建
| IP地址 | 域名 | 用途 | |
定位漏洞程序
漏洞分析
[email protected]# /netscaler/pb_policy -h nothingCurrent pitboss policy is 0x29b4 (10676):PB_ABRT_CULPRIT | PB_RESTART_CULPRIT | PB_RESTART_SYSTEM | PB_KILL_USER_PROCS | PB_WAIT_CORES | PB_REBOOT_ON_SLOW_WARMSTART | PB_REBOOT_ON_INCOMPLETE_REGHung processes will be sent a SIGABRT (PB_ABRT_CULPRIT).Monitored processes which exit will be restarted up to 5 times, except forpacket engines (PB_RESTART_CULPRIT).If pitboss decides not to restart some failing process(es) all non-failingprocesses will be sent a SIGKILL (PB_KILL_USER_PROCS).Pitboss will then wait for all core dumps to complete (PB_WAIT_CORES) and thendo a warm restart (if a packet engine failed) and otherwise reboot the system (PB_RESTART_SYSTEM).If startup failure is detected do nothing.If warmstart takes too long pitboss will reboot the system (PB_REBOOT_ON_SLOW_WARMSTART).On incomplete registration of mandatory processes after warmstart pitboss willreboot the system (PB_REBOOT_ON_INCOMPLETE_REG).Log messages from pitboss will take the default path.New pitboss policy is 0x29b0 (10672):PB_RESTART_CULPRIT | PB_RESTART_SYSTEM | PB_KILL_USER_PROCS | PB_WAIT_CORES | PB_REBOOT_ON_SLOW_WARMSTART | PB_REBOOT_ON_INCOMPLETE_REGHung processes will be ignored.Monitored processes which exit will be restarted up to 5 times, except forpacket engines (PB_RESTART_CULPRIT).If pitboss decides not to restart some failing process(es) all non-failingprocesses will be sent a SIGKILL (PB_KILL_USER_PROCS).Pitboss will then wait for all core dumps to complete (PB_WAIT_CORES) and thendo a warm restart (if a packet engine failed) and otherwise reboot the system (PB_RESTART_SYSTEM).If startup failure is detected do nothing.If warmstart takes too long pitboss will reboot the system (PB_REBOOT_ON_SLOW_WARMSTART).On incomplete registration of mandatory processes after warmstart pitboss willreboot the system (PB_REBOOT_ON_INCOMPLETE_REG).Log messages from pitboss will take the default path.
__int64 __fastcall ns_aaa_saml_entity_encode_decode(__int64 a1, __int64 a2, int a3, __int64 a4){__int64 v5; // rax__int64 v6; // rbx__int64 v7; // rbxint v8; // r9dint v9; // r9dunsigned __int16 v10; // axunsigned int v11; // eaxunsigned int v12; // r12d__int64 v14; // [rsp+18h] [rbp-58h] BYREF__int64 v15[2]; // [rsp+20h] [rbp-50h] BYREFint v16; // [rsp+30h] [rbp-40h]int v17; // [rsp+34h] [rbp-3Ch]int v18; // [rsp+38h] [rbp-38h]int v19; // [rsp+3Ch] [rbp-34h]int v20; // [rsp+40h] [rbp-30h]v15[0] = 0LL;v15[1] = a1;v16 = a3;v17 = a3;v18 = 4;v19 = 22;LOBYTE(v20) = v20 & 0xE0;v20 = (32 * ASTR_NOT_REF_COUNTED) | v20 & 0x1F;v5 = astr_canonicalize(*(_QWORD *)(*((_QWORD *)cur_as_partition + 2) + 8LL), 5LL, v15, a4, 0LL, 0LL);v6 = v5;if ( v5 ){ns_bcopy_(*(_QWORD *)(v5 + 8), a2, *(unsigned int *)(v5 + 16));v12 = *(_DWORD *)(v6 + 16);astr_destroy(*(_QWORD *)(*((_QWORD *)cur_as_partition + 2) + 8LL), 5LL, v6);}else{......// 日志记录return 0;}return v12;}
__int64 __fastcall ns_aaa_entity_encode_decode(__int64 a1, __int64 a2, int a3, unsigned int a4, unsigned int a5){__int64 v7; // rax__int64 v8; // r12__int64 v9; // rbxint v10; // r9dint v11; // r9dunsigned __int16 v12; // axunsigned int v13; // eaxunsigned int v14; // ebxunsigned int v15; // eax__int64 v16; // rbxint v17; // r8dint v18; // r9dint v19; // r8dint v20; // r9dunsigned __int16 v21; // axunsigned int v22; // eaxchar v24; // [rsp+0h] [rbp-80h]char v25; // [rsp+0h] [rbp-80h]char v26; // [rsp+0h] [rbp-80h]char v27; // [rsp+0h] [rbp-80h]__int64 v28; // [rsp+18h] [rbp-68h] BYREF__int64 v29[2]; // [rsp+20h] [rbp-60h] BYREFint v30; // [rsp+30h] [rbp-50h]int v31; // [rsp+34h] [rbp-4Ch]int v32; // [rsp+38h] [rbp-48h]int v33; // [rsp+3Ch] [rbp-44h]int v34; // [rsp+40h] [rbp-40h]v29[0] = 0LL;v29[1] = a1;v30 = a3;v31 = a3;v32 = 4;v33 = 22;LOBYTE(v34) = v34 & 0xE0;v34 = (32 * ASTR_NOT_REF_COUNTED) | v34 & 0x1F;v7 = astr_canonicalize(*(_QWORD *)(*((_QWORD *)cur_as_partition + 2) + 8LL), 5LL, v29, a5, 0LL, 0LL);v8 = v7;if ( v7 ){v15 = *(_DWORD *)(v7 + 16);if ( v15 <= a4 ){ns_bcopy_(*(_QWORD *)(v8 + 8), a2, v15);v14 = *(_DWORD *)(v8 + 16);astr_destroy(*(_QWORD *)(*((_QWORD *)cur_as_partition + 2) + 8LL), 5LL, v8);}else{...... //日志记录astr_destroy(*(_QWORD *)(*((_QWORD *)cur_as_partition + 2) + 8LL), 5LL, v8);return 0;}}else{...... //日志记录return 0;}return v14;}
(gdb) b ns_aaa_saml_entity_encode_decodeBreakpoint 1 at 0xbebfb4(gdb) cContinuing.Breakpoint 1, 0x0000000000bebfb4 in ns_aaa_saml_entity_encode_decode ()(gdb) bt#0 0x0000000000bebfb4 in ns_aaa_saml_entity_encode_decode ()#1 0x0000000000bf8356 in ns_aaa_saml_verify_signature ()#2 0x0000000000c216ca in ns_aaa_saml_process_data ()#3 0x0000000000c25577 in ns_aaa_process_saml_req ()#4 0x0000000000c25842 in ns_aaa_saml_auth ()#5 0x00000000007c6a45 in ns_vpn_process_unauthenticated_request ()#6 0x000000000080a326 in ns_aaa_cookie_valid ()#7 0x000000000081ca31 in ns_aaa_client_handler ()#8 0x0000000001c2e6a1 in nshttp_input ()#9 0x0000000001c2433b in nshttp_handler ()#10 0x00000000016e495e in ns_async_restart_http ()#11 0x0000000000bfaf40 in ns_aaa_saml_canon_resp_handler ()#12 0x000000000079ab48 in nsaaa_handler ()#13 0x0000000001c6d149 in nstcp_input ()#14 0x0000000001c59e0a in handleL4Session ()#15 0x0000000001c5724f in dispatch_tcp ()#16 0x00000000010cf0eb in vmpe_intf_loop_rx_proc ()#17 0x0000000001c55472 in vc_poll ()#18 0x00000000015b5ae3 in ns_netio ()#19 0x00000000015baf4b in packet_engine ()#20 0x00000000019bd9a3 in ns_enter_main ()#21 0x00000000019c1fe9 in main ()
(gdb) b *0xBEC15ABreakpoint 1 at 0xbec15a(gdb) cContinuing.Breakpoint 1, 0x0000000000bec15a in ns_aaa_saml_entity_encode_decode ()(gdb) x/10i $rip0xbec15a <ns_aaa_saml_entity_encode_decode+426>:callq 0x1c5e390 <ns_bcopy_>0xbec15f <ns_aaa_saml_entity_encode_decode+431>: mov 0x10(%rbx),%r12d0xbec163 <ns_aaa_saml_entity_encode_decode+435>:mov 27378486(%rip),%rax # 0x26084a0 <cur_as_partition>0xbec16a <ns_aaa_saml_entity_encode_decode+442>: mov 0x10(%rax),%rax0xbec16e <ns_aaa_saml_entity_encode_decode+446>: mov 0x8(%rax),%rdi0xbec172 <ns_aaa_saml_entity_encode_decode+450>: mov %rbx,%rdx0xbec175 <ns_aaa_saml_entity_encode_decode+453>: mov $0x5,%esi0xbec17a <ns_aaa_saml_entity_encode_decode+458>:callq 0x1b4b2a0 <astr_destroy>0xbec17f <ns_aaa_saml_entity_encode_decode+463>:jmp 0xbec187 <ns_aaa_saml_entity_encode_decode+471>0xbec181 <ns_aaa_saml_entity_encode_decode+465>: mov $0x0,%r12d(gdb) x/10gx $rdi0x1115fe018: 0x5057344157596753 0x356e674e666232690x1115fe028: 0x7155336a5a465335 0x2f5a6c72724836530x1115fe038: 0x544247674f624d77 0x337a446e397758500x1115fe048: 0x654765743451734b 0x30756d4e5a536b4c0x1115fe058: 0x3461474947764668 0x5a38303835356d64(gdb) set print elements 0(gdb) x/s $rdi0x1115fe018: "SgYWA4WPi2bfNgn55SFZj3UqS6HrrlZ/wMbOgGBTPXw9nDz3KsQ4teGeLkSZNmu0hFvGIGa4dm55808Zuikx4s1rIbTiuyw1z5VkZGuXLl31mObPvrbowtqoBgaeTfAwImtJrw4g2kQoe35b/Z0AgSlu9/LxKRKTaG1jYk6chGNJpKTBCmEqRWKFtJsPjnB9xkAiYspO1T2AsgR9KAq9+cV93X/ZtPkfutRj4IaI3LcMnDxQ+9Pb75HYBZ9LYVqOPGowGVf/Opz40VU6xyWzRlg45ouEHTFS45xCPCe/eQe3mPjsp/kMGsM2e6611stx3Isu+GMgwDGd5hlRp4lFdQ=="
漏洞利用
查看下nsppe进程的保护机制,没有canary,栈可执行,程序没有aslr无需泄露基址,可控栈空间很大,似乎是很容易利用。
但很快就发现事情似乎没那么简单,Citrix接收到html中的SAMLResponse响应后,将响应base64解码后转换为xml文本,而根据W3C的标准,以下\x00-\x08?\x0b-\x0c?\x0e-\x1f16进制的字符是不被允许出现在XML文件中的,即使放在<![CDATA[]]> 中,也不能幸免。
也就是说,我们只能控制栈变量到返回地址之间的栈空间,且可控的栈内容不能包含以上字符,因此只能放入经过编码的shellcode。而我们的程序高地址都是\x00,也无法在栈中构造ROP链,只有一次覆盖返回地址低位3字节的机会。
可以寻找到合适的gadget将控制流转移到可控栈空间内实现RCE,也可以控制返回地址到大部分任意函数进行恶意操作。
参考文章
作者名片
END