从管理员身份获得SYSTEM权限的四种方法电脑资料

从管理员身份获得SYSTEM权限的四种方法电脑资料

2023年6月23日发(作者:)

从管理员身份获得 SYSTEM 权限的四种方法 -电脑资料

本文总结了 4 种方法获得 SYSTEM 权限来运行 文件,

源代码很容易修改成命令行方式运行指定的程序,

从管理员身份获得 SYSTEM 权限的四种方法

1. 以服务方式运行

2. 添加 ACL 的方法

3. HOOK ZwCreateProcessEx 函数

4. 远程线程的方法

这几种方法都不是我想出来的,我只不过是总结了一下,用 Win32ASM

重写了代码而以。

关于这个大家可以看文章末尾的参考资料。下面简单的分析每一种方法。

1. 以服务方式运行

因为以服务方式运行程序时,相当于运行程序的是系统进程,所以,

被指定运行的程序自然而然的继承了系统进程的权限,也就是 SYSTEM

权限。

;@echo off

;goto make

;====================================================================================

; 一块三毛钱

; ;

; 2005.1.15

;

; 以 SYSTEM 权限运行程序 - GetSys1

;

; 采用以服务方式运行的方法

;

;====================================================================================

.386

.model flat, stdcall

option casemap :none

include c:

include c:

include c:

include c:

includelib c:

includelib c:

includelib c:

_ReLaunch proto

CTXT MACRO text

local lbl

.const

lbl db text,0 .code

exitm

ENDM

.code

start proc

LOCAL stStartupInfo : STARTUPINFO

LOCAL procinfo : PROCESS_INFORMATION

invoke CreateMutex, NULL, TRUE, CTXT("GetSys1_Mutex")

invoke GetLastError

.if eax==ERROR_ALREADY_EXISTS

invoke RtlZeroMemory, addr stStartupInfo, sizeof

stStartupInfo

mov , sizeof stStartupInfo

invoke CreateProcess, 0, CTXT(""), 0, 0, 0, 0, 0,

0,

addr stStartupInfo, addr procinfo

invoke CloseHandle, ss

invoke CloseHandle, d

.else

invoke _ReLaunch

.endif

invoke ExitProcess, NULL

start endp

_ReLaunch proc LOCAL hSCManager

LOCAL hService

LOCAL szName[MAX_PATH] : byte

invoke OpenSCManager, NULL, NULL, SC_MANAGER_CREATE_SERVICE

.if eax!=0

mov hSCManager, eax

invoke OpenService, hSCManager, CTXT("GetSys1Temp"), DELETE

.if eax!=0

push eax

invoke DeleteService, eax

call CloseServiceHandle

.endif

invoke GetModuleFileName, NULL, addr szName, MAX_PATH

invoke CreateService, hSCManager, CTXT("GetSys1Temp"),

CTXT("GetSys1 Temp Service"),

SERVICE_START + SERVICE_QUERY_STATUS + DELETE,

SERVICE_WIN32_OWN_PROCESS + SERVICE_INTERACTIVE_PROCESS,

SERVICE_DEMAND_START,

SERVICE_ERROR_IGNORE, addr szName, NULL, NULL, NULL, NULL,

NULL

.if eax!=0

mov hService, eax

invoke StartService, hService, 0, NULL

invoke DeleteService, hService

invoke CloseServiceHandle, hService .endif

invoke CloseServiceHandle, hSCManager

.endif

ret

_ReLaunch endp

end start

:make

set path=%path%;c:masm32bin

set appname=GetSys1

ml /nologo /c /coff %appname%.bat

link /nologo /subsystem:windows %appname%.obj

del %appname%.obj

echo.

pause

GetSys1(第一次运行的这个进程 GetSys1 我们称为 A) 开始运行时先创建一个互斥量,

接着以服务的方式重新启动自己

(又一次运行的进程 GetSys1 我们称为 B),重新运行后的 B 已经具有了 SYSTEM 权限。

B 再通过 CreateProcess 函数运行 程序,

因为 B 具有 SYSTEM 权限,所以 从中继承了 SYSTEM 权限。

运行完了 后 B 结束运行,

然后 A 中的 StartService 函数返回,A 结束运行。就是因为

StartService 函数不会直接返回, 所以不能够直接通过服务的方式运行 。

2. 添加 ACL 的方法

主要思想是调用 CreateProcessAsUser 函数来运行程序,CreateProcessAsUser

函数的第一个参数是特定用户的令牌,

把这个参数设为具有 SYSTEM 权限的令牌即可。

;@echo off

;goto make

;====================================================================================

; 一块三毛钱

;

;

; 2005.1.15

;

; 以 SYSTEM 权限运行程序 - GetSys2

;

; 采用添加 ACL 的方法

;

;====================================================================================

.386

.model flat, stdcall

option casemap :none

include c: include c:

include c:

include c:

include c:

includelib c:

includelib c:

includelib c:

_EnablePrivilege proto :DWORD,:DWORD

_GetPidFromProcName proto :DWORD

_ModifySecurity proto :DWORD,:DWORD

CTXT MACRO text

local lbl

.const

lbl db text,0

.code

exitm

ENDM

ACL STRUCT

AclRevision BYTE ?

Sbz1 BYTE ?

AclSize WORD ?

AceCount WORD ?

Sbz2 WORD ? ACL ENDS

PACL typedef PTR ACL

SecurityImpersonation equ 2

.code

start proc

LOCAL

LOCAL

LOCAL

LOCAL

sub

mov

mov

mov

invoke

stStartupInfo

invoke

invoke

invoke

invoke

test

jz

mov

invoke

hToken

hProc

hToken, hNewToken

stStartupInfo : STARTUPINFO

procinfo : PROCESS_INFORMATION

eax, eax

hProc, eax

hToken, eax

hNewToken, eax

RtlZeroMemory, addr stStartupInfo, sizeof

RtlZeroMemory, addr procinfo, sizeof procinfo

_EnablePrivilege, CTXT("SeDebugPrivilege"), TRUE

_GetPidFromProcName, CTXT("")

OpenProcess, PROCESS_QUERY_INFORMATION, 0, eax

eax, eax

_exit

hProc, eax

OpenProcessToken, hProc, READ_CONTROL+WRITE_DAC, addr

test eax, eax

jz _exit

invoke _ModifySecurity, hToken, TOKEN_ALL_ACCESS

test eax, eax

jz _exit

invoke CloseHandle, hToken

mov hToken, 0

invoke OpenProcessToken, hProc, TOKEN_ALL_ACCESS, addr hToken

test eax, eax

jz _exit

invoke DuplicateTokenEx, hToken, TOKEN_ALL_ACCESS, 0,

SecurityImpersonation, TokenPrimary, addr hNewToken

test eax, eax

jz _exit

invoke ImpersonateLoggedOnUser, hNewToken

test eax, eax

jz _exit

mov , sizeof stStartupInfo

invoke CreateProcessAsUser, hNewToken, 0, CTXT(""),

0, 0, 0, 0, 0, 0,

addr stStartupInfo, addr procinfo

test eax, eax

jz _exit

invoke CloseHandle, ss invoke CloseHandle, d

_exit:

.if hProc

invoke CloseHandle, hProc

.endif

.if hToken

invoke CloseHandle, hToken

.endif

.if hNewToken

invoke CloseHandle, hNewToken

.endif

invoke ExitProcess, NULL

start endp

_ModifySecurity proc uses ebx esi edi, hToken:DWORD,

dwAccess:DWORD

LOCAL pSD, pAbsSD

LOCAL dwSDLength

LOCAL bDaclPresent, bDaclDefaulted

LOCAL pAcl : PACL

LOCAL pNewAcl : PACL

LOCAL szName[1024] : BYTE

LOCAL ea : EXPLICIT_ACCESS

LOCAL pSacl, pOwner, pPrimaryGroup

LOCAL dwAclSize, dwSaclSize, dwOwnerSize, dwPrimaryGroup LOCAL bSuccess

sub eax, eax

mov pSD, eax

mov pAbsSD, eax

mov dwSDLength, eax

mov bDaclPresent, eax

mov bDaclDefaulted, eax

mov pAcl, eax

mov pNewAcl, eax

mov pSacl, eax

mov pOwner, eax

mov pPrimaryGroup, eax

mov dwAclSize, eax

mov dwSaclSize, eax

mov dwOwnerSize, eax

mov dwPrimaryGroup, eax

mov bSuccess, eax

invoke GetKernelObjectSecurity, hToken,

DACL_SECURITY_INFORMATION, pSD, 0, addr dwSDLength

invoke LocalAlloc, LPTR, dwSDLength

test eax, eax

jz _exit

mov pSD, eax invoke GetKernelObjectSecurity, hToken,

DACL_SECURITY_INFORMATION, pSD,

dwSDLength, addr dwSDLength

invoke GetSecurityDescriptorDacl, pSD, addr bDaclPresent,

addr pAcl, addr bDaclDefaulted

mov eax, sizeof szName

push eax

invoke GetUserName, addr szName, esp

pop eax

invoke BuildExplicitAccessWithName, addr ea, addr szName,

dwAccess, GRANT_ACCESS, FALSE

invoke SetEntriesInAcl, 1, addr ea, pAcl, addr pNewAcl

cmp eax, ERROR_SUCCESS

jne _exit

invoke LocalFree, pAcl

mov pAcl, 0

invoke MakeAbsoluteSD, pSD, pAbsSD, addr dwSDLength, pAcl,

addr dwAclSize, pSacl, addr dwSaclSize,

pOwner, addr dwOwnerSize, pPrimaryGroup, addr dwPrimaryGroup

invoke LocalAlloc, LPTR, dwSDLength

test eax, eax

jz _exit

mov pAbsSD, eax

invoke LocalAlloc, LPTR, dwAclSize

test eax, eax jz _exit

mov pAcl, eax

invoke LocalAlloc, LPTR, dwSaclSize

test eax, eax

jz _exit

mov pSacl, eax

invoke LocalAlloc, LPTR, dwOwnerSize

test eax, eax

jz _exit

mov pOwner, eax

invoke LocalAlloc, LPTR, dwPrimaryGroup

test eax, eax

jz _exit

mov pPrimaryGroup, eax

invoke MakeAbsoluteSD, pSD, pAbsSD, addr dwSDLength, pAcl,

addr dwAclSize, pSacl, addr dwSaclSize,

pOwner, addr dwOwnerSize, pPrimaryGroup, addr dwPrimaryGroup

invoke SetSecurityDescriptorDacl, pAbsSD, bDaclPresent,

pNewAcl, bDaclDefaulted

invoke SetKernelObjectSecurity, hToken,

DACL_SECURITY_INFORMATION, pAbsSD

mov bSuccess, 1

_exit:

.if pSD

invoke LocalFree, pSD .endif

.if pAcl

invoke LocalFree, pAcl

.endif

.if pNewAcl

invoke LocalFree, pNewAcl

.endif

.if pAbsSD

invoke LocalFree, pAbsSD

.endif

.if pSacl

invoke LocalFree, pSacl

.endif

.if pOwner

invoke LocalFree, pOwner

.endif

.if pPrimaryGroup

invoke LocalFree, pPrimaryGroup

.endif

mov eax, bSuccess

ret

_ModifySecurity endp

_EnablePrivilege proc szPriv:DWORD, bFlags:DWORD LOCAL hToken

LOCAL tkp : TOKEN_PRIVILEGES

invoke GetCurrentProcess

mov edx, eax

invoke OpenProcessToken, edx, TOKEN_ADJUST_PRIVILEGES or

TOKEN_QUERY, addr hToken

invoke LookupPrivilegeValue, NULL, szPriv, addr

mov egeCount, 1

xor eax, eax

.if bFlags

mov eax, SE_PRIVILEGE_ENABLED

.endif

mov utes, eax

invoke AdjustTokenPrivileges, hToken, FALSE, addr tkp, 0, 0,

0

push eax

invoke CloseHandle, hToken

pop eax

ret

_EnablePrivilege endp

_GetPidFromProcName proc lpProcName:DWORD

LOCAL stProcess : PROCESSENTRY32

LOCAL hSnapshot

LOCAL dwProcessID mov dwProcessID, 0

invoke RtlZeroMemory, addr stProcess, sizeof stProcess

mov , sizeof stProcess

invoke CreateToolhelp32Snapshot, TH32CS_SNAPPROCESS, 0

mov hSnapshot, eax

invoke Process32First, hSnapshot, addr stProcess

.while eax

invoke lstrcmpi, lpProcName, addr ile

.if eax==0

mov eax, 32ProcessID

mov dwProcessID, eax

.break

.endif

invoke Process32Next, hSnapshot, addr stProcess

.endw

invoke CloseHandle, hSnapshot

mov eax, dwProcessID

ret

_GetPidFromProcName endp

end start

:make

set path=%path%;c:masm32bin

set appname=GetSys2 ml /nologo /c /coff %appname%.bat

link /nologo /subsystem:windows %appname%.obj

del %appname%.obj

echo.

pause

GetSys2 取得 进程的令牌,缺省情况下操作这个令牌的权限很小,

所以需要先取得操作这个令牌的所有权限,

电脑资料

《从管理员身份获得 SYSTEM 权限的四种方法》。这个任务由函数

_ModifySecurity 来完成。

有了权限后,复制一个主令牌,然后在当前线程中扮演 SYSTEM 用户,接着就可以调用 CreateProcessAsUser

函数运行 程序了。有关安全性编程不清楚的地方可以参考[3]。

3. HOOK ZwCreateProcessEx 函数

有关这个[1]里面讲得很清楚了,下面直接给出源代码。

;@echo off

;goto make

;====================================================================================

; 一块三毛钱

;

;

; 2005.1.15 ;

; 以 SYSTEM 权限运行程序 - GetSys3

;

; 采用 HOOK ZwCreateProcessEx 函数的方法

;

;====================================================================================

.386

.model flat, stdcall

option casemap :none

include c:

include c:

include c:

include c:

includelib c:

includelib c:

includelib c:

_EnablePrivilege proto :DWORD,:DWORD

_GetPidFromProcName proto :DWORD

_HackedZwCreateProcessEx proto

CTXT MACRO text

local lbl

.const

lbl db text,0 .code

exitm

ENDM

ASMJMP struct

mov_eax BYTE ?

address DWORD ?

jmp_eax WORD ?

ASMJMP ends

.data?

g_hProc dd ?

g_dwFunc dd ?

.code

start proc

LOCAL osvi : OSVERSIONINFO

LOCAL lpAsmJmp

LOCAL mbi : MEMORY_BASIC_INFORMATION

LOCAL stStartupInfo : STARTUPINFO

LOCAL procinfo : PROCESS_INFORMATION

sub eax, eax

mov lpAsmJmp, eax

invoke RtlZeroMemory, addr osvi, sizeof osvi

invoke RtlZeroMemory, addr mbi, sizeof mbi

invoke RtlZeroMemory, addr stStartupInfo, sizeof

stStartupInfo invoke RtlZeroMemory, addr procinfo, sizeof procinfo

mov rsionInfoSize, sizeof osvi

invoke GetVersionEx, addr osvi

cmp rVersion, 5

jnz _exit

.if rVersion==1

mov g_dwFunc, 30h

.elseif rVersion==2

mov g_dwFunc, 32h

.endif

invoke _EnablePrivilege, CTXT("SeDebugPrivilege"), TRUE

invoke _GetPidFromProcName, CTXT("")

test eax, eax

jz _exit

invoke OpenProcess, PROCESS_CREATE_PROCESS, TRUE, eax

test eax, eax

jz _exit

mov g_hProc, eax

invoke GetModuleHandle, CTXT("")

mov edx, eax

invoke GetProcAddress, edx, CTXT("ZwCreateProcessEx")

mov lpAsmJmp, eax

invoke VirtualQuery, lpAsmJmp, addr mbi, sizeof mbi push eax

invoke VirtualProtect, tionBase, Size,

PAGE_EXECUTE_READWRITE, esp

pop eax

mov edi, lpAsmJmp

assume edi : ptr ASMJMP

mov [edi].mov_eax, 0B8h

mov [edi].address, offset _HackedZwCreateProcessEx

mov [edi].jmp_eax, 0E0FFh

mov , sizeof stStartupInfo

invoke CreateProcess, 0, CTXT(""),

0, 0, 0, 0, 0, 0, addr stStartupInfo, addr procinfo

test eax, eax

jz _exit

invoke CloseHandle, ss

invoke CloseHandle, d

_exit:

invoke ExitProcess, NULL

start endp

_HackedZwCreateProcessEx proc

mov eax, g_hProc

mov dword ptr [esp+16], eax

mov eax, g_dwFunc

lea edx, dword ptr [esp+4] int 2Eh

retn 24h

_HackedZwCreateProcessEx endp

_EnablePrivilege proc szPriv:DWORD, bFlags:DWORD

LOCAL hToken

LOCAL tkp : TOKEN_PRIVILEGES

invoke GetCurrentProcess

mov edx, eax

invoke OpenProcessToken, edx, TOKEN_ADJUST_PRIVILEGES or

TOKEN_QUERY, addr hToken

invoke LookupPrivilegeValue, NULL, szPriv, addr

mov egeCount, 1

xor eax, eax

.if bFlags

mov eax, SE_PRIVILEGE_ENABLED

.endif

mov utes, eax

invoke AdjustTokenPrivileges, hToken, FALSE, addr tkp, 0, 0,

0

push eax

invoke CloseHandle, hToken

pop eax

ret

_EnablePrivilege endp _GetPidFromProcName proc lpProcName:DWORD

LOCAL stProcess : PROCESSENTRY32

LOCAL hSnapshot

LOCAL dwProcessID

mov dwProcessID, 0

invoke RtlZeroMemory, addr stProcess, sizeof stProcess

mov , sizeof stProcess

invoke CreateToolhelp32Snapshot, TH32CS_SNAPPROCESS, 0

mov hSnapshot, eax

invoke Process32First, hSnapshot, addr stProcess

.while eax

invoke lstrcmpi, lpProcName, addr ile

.if eax==0

mov eax, 32ProcessID

mov dwProcessID, eax

.break

.endif

invoke Process32Next, hSnapshot, addr stProcess

.endw

invoke CloseHandle, hSnapshot

mov eax, dwProcessID

ret

_GetPidFromProcName endp end start

:make

set path=%path%;c:masm32bin

set appname=GetSys3

ml /nologo /c /coff %appname%.bat

link /nologo /subsystem:windows %appname%.obj

del %appname%.obj

echo.

pause

4. 远程线程的方法

通过注入远程线程的方法来运行指定的 程序,

也是相当于运行 程序的是系统进程,

那么 也就自然而然的继承了系统进程的 SYSTEM 权限。

;@echo off

;goto make

;====================================================================================

; 一块三毛钱

;

;

; 2005.1.15

;

; 以 SYSTEM 权限运行程序 - GetSys4

; ; 采用远程线程的方法

;

;====================================================================================

.386

.model flat, stdcall

option casemap :none

include c:

include c:

include c:

include c:

includelib c:

includelib c:

includelib c:

_EnablePrivilege proto :DWORD,:DWORD

_GetPidFromProcName proto :DWORD

;下面两个宏来源于罗云彬的《Windows 环境下32位汇编程序设计》一书

reverseArgs macro arglist:VARARG

local txt,count

txt TEXTEQU <>

count = 0

for i,

count = count + 1 txt TEXTEQU @CatStr(i,,<%txt>)

endm

if count GT 0

txt SUBSTR txt,1,@SizeStr(%txt)-1

endif

exitm txt

endm

_invoke macro _Proc,args:VARARG

local count

count = 0

% for i,< reverseArgs( args ) >

count = count + 1

push i

endm

call dword ptr _Proc

endm

CTXT MACRO text

local lbl

.const

lbl db text,0

.code

exitm

ENDM .data?

g_hProcess dd ?

g_lpRemoteCode dd ?

.code

Remote_code_start equ this byte

g_lpGetModuleHandleA dd ?

g_lpGetProcAddress dd ?

g_szKernel32 db "",0

g_szCreateProcessA db "CreateProcessA",0

g_lpCreateProcessA dd ?

g_szRegedit db "",0

g_szDesktop db "WinSta0Default",0

g_stStartupInfo STARTUPINFO

g_procinfo PROCESS_INFORMATION

_RemoteThread proc

; int 3

pushad

call @F

@@:

pop ebx

sub ebx, offset @B

lea eax, [ebx+g_szKernel32]

_invoke [ebx+g_lpGetModuleHandleA], eax mov esi, eax

lea eax, [ebx+g_szCreateProcessA]

_invoke [ebx+g_lpGetProcAddress], esi, eax

mov [ebx+g_lpCreateProcessA], eax

lea eax, [ebx+g_szDesktop]

lea ecx, [ebx+g_stStartupInfo]

mov dword ptr [ecx], sizeof g_stStartupInfo

mov dword ptr [ecx+8], eax

lea eax, [ebx+g_szRegedit]

lea edx, [ebx+g_procinfo]

_invoke [ebx+g_lpCreateProcessA], 0, eax, 0, 0, 0, 0, 0, 0,

ecx, edx

popad

ret

_RemoteThread endp

Remote_code_end equ this byte

Remote_code_length equ offset Remote_code_end -

offset Remote_code_start

start proc

invoke GetModuleHandle, CTXT("")

mov ebx, eax

invoke GetProcAddress, ebx, CTXT("GetModuleHandleA")

mov g_lpGetModuleHandleA, eax

invoke GetProcAddress, ebx, CTXT("GetProcAddress") mov g_lpGetProcAddress, eax

invoke _EnablePrivilege, CTXT("SeDebugPrivilege"), TRUE

invoke _GetPidFromProcName, CTXT("")

invoke OpenProcess,

PROCESS_CREATE_THREAD+PROCESS_VM_OPERATION+PROCESS_VM_WRITE, FALSE, eax

.if eax

mov g_hProcess, eax

invoke VirtualAllocEx, g_hProcess, NULL, Remote_code_length,

MEM_COMMIT, PAGE_EXECUTE_READWRITE

.if eax

mov g_lpRemoteCode, eax

invoke WriteProcessMemory, g_hProcess, g_lpRemoteCode,

offset Remote_code_start, Remote_code_length, NULL

mov eax, g_lpRemoteCode

add eax, offset _RemoteThread - offset

Remote_code_start

invoke CreateRemoteThread, g_hProcess, NULL, 0, eax, 0, 0,

NULL

invoke CloseHandle, eax

.endif

invoke CloseHandle, g_hProcess

.endif

invoke ExitProcess, NULL

start endp

_EnablePrivilege proc szPriv:DWORD, bFlags:DWORD LOCAL hToken

LOCAL tkp : TOKEN_PRIVILEGES

invoke GetCurrentProcess

mov edx, eax

invoke OpenProcessToken, edx, TOKEN_ADJUST_PRIVILEGES or

TOKEN_QUERY, addr hToken

invoke LookupPrivilegeValue, NULL, szPriv, addr

mov egeCount, 1

xor eax, eax

.if bFlags

mov eax, SE_PRIVILEGE_ENABLED

.endif

mov utes, eax

invoke AdjustTokenPrivileges, hToken, FALSE, addr tkp, 0, 0,

0

push eax

invoke CloseHandle, hToken

pop eax

ret

_EnablePrivilege endp

_GetPidFromProcName proc lpProcName:DWORD

LOCAL stProcess : PROCESSENTRY32

LOCAL hSnapshot

LOCAL dwProcessID mov dwProcessID, 0

invoke RtlZeroMemory, addr stProcess, sizeof stProcess

mov , sizeof stProcess

invoke CreateToolhelp32Snapshot, TH32CS_SNAPPROCESS, 0

mov hSnapshot, eax

invoke Process32First, hSnapshot, addr stProcess

.while eax

invoke lstrcmpi, lpProcName, addr ile

.if eax==0

mov eax, 32ProcessID

mov dwProcessID, eax

.break

.endif

invoke Process32Next, hSnapshot, addr stProcess

.endw

invoke CloseHandle, hSnapshot

mov eax, dwProcessID

ret

_GetPidFromProcName endp

end start

:make

set path=%path%;c:masm32bin

set appname=GetSys4 ml /nologo /c /coff %appname%.bat

link /nologo /subsystem:windows

/section:.text,rwe %appname%.obj

del %appname%.obj

echo.

pause

这段代码也没什么好解释的,唯一一个要注意的地方就是调用

CreateProcess 函数时,lpStartupInfo

参数指向的 STARTUPINFO 结构成员 lpDesktop 需要明确的指定

WinSta0Default 为运行桌面。

否则,程序 运行后不知道跑到哪里去了。

参考资料

[1] scz MSDN系列(3)--Administrator用户直接获取SYSTEM权限

/?ac...ew&mid=1900

[2] wsu 1.0

[3] Keith Brown 《Windows 安全性编程》

[4]

Jeffrey Richter/Jason 《s.2000

发布者:admin,转转请注明出处:http://www.yc00.com/xiaochengxu/1687516319a16240.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信