{"id":477,"date":"2010-04-30T03:57:14","date_gmt":"2010-04-29T19:57:14","guid":{"rendered":"http:\/\/www.computersolutions.cn\/blog\/?p=477"},"modified":"2013-01-04T22:50:38","modified_gmt":"2013-01-04T14:50:38","slug":"ip-cam-hacking-pt4","status":"publish","type":"post","link":"https:\/\/www.computersolutions.cn\/blog\/2010\/04\/ip-cam-hacking-pt4\/","title":{"rendered":"IP Cam Hacking &#8211; pt#4"},"content":{"rendered":"<p>Spent a while checking out the different binaries available for the different OEM versions.<br \/>\nSome interesting things I&#8217;ve found.<\/p>\n<p>If I take a look at a sample kernel &#8211; eg<br \/>\nlr_cmos_11_14_1_46.bin<\/p>\n<p><code> ls -al lr_cmos_11_14_1_46.bin<br \/>\n-rw-r--r--  1 lawrence  staff  1350539 Mar 15 13:47 lr_cmos_11_14_1_46.bin<br \/>\n<\/code><\/p>\n<p>Our file size for the file i have is 1350539 bytes.<\/p>\n<p>A hexdump of the header shows:<\/p>\n<p>00000000  42 4e 45 47 01 00 00 00  01 00 00 00 77 cb 0b 00  |BNEG&#8230;&#8230;..w&#8230;|<br \/>\n00000010  00 d0 08 00 50 4b 03 04  14 00 00 00 08 00 3a 2e  |&#8230;.PK&#8230;&#8230;..:.|<br \/>\n00000020  87 3b 3b e7 b8 16 03 cb  0b 00 bc d9 18 00 09 00  |.;;&#8230;&#8230;&#8230;&#8230;.|<\/p>\n<p>PK is the standard file header for Zip compression (as Zip was invented by Phil Katz)<br \/>\nZip fingerprint in hex is &#8211; 0x04034b50, which matches nicely in our second line &#8211; 50 4b 03 04<\/p>\n<p>On the offchance it contained a zip file, I tried unzipping from the start of the PK.<\/p>\n<p>We can totally misuse dd to write from an offset of 20 bytes to a test.zip file as follows:<\/p>\n<p><code><br \/>\nlawrence$ dd if=lr_cmos_11_14_1_46.bin of=test.zip skip=0x14 bs=1 <\/p>\n<p>(check I actually did that right)<br \/>\nlawrence$ hexdump -C test.zip  |more<br \/>\n00000000  50 4b 03 04 14 00 00 00  08 00 3a 2e 87 3b 3b e7  |PK........:..;;.|<br \/>\n00000010  b8 16 03 cb 0b 00 bc d9  18 00 09 00 00 00 6c 69  |..............li|<\/p>\n<p><\/code><\/p>\n<p>Unfortunately this didn&#8217;t unzip.<\/p>\n<p>However&#8230; <\/p>\n<p><code>zipinfo test.zip<br \/>\nArchive:  test.zip   1350519 bytes   1 file<br \/>\n-rw-------  2.0 fat  1628604 b- defN  7-Dec-09 05:49 linux.bin<br \/>\n1 file, 1628604 bytes uncompressed, 772867 bytes compressed:  52.5%<\/code><\/p>\n<p>Says there is a valid zip file there, so we&#8217;re getting somewhere.  It should be something like 772867 bytes + whatever Zip header \/ footer file bits in size.<\/p>\n<p>If we take a look at the Zip file format, it says that the end of directory (aka end of zip file) marker is 0x06054b50<\/p>\n<p><code>ZIP end of central directory record <\/p>\n<p>Offset \tBytes \tDescription[4]<br \/>\n\u20070 \t4 \tEnd of central directory signature = 0x06054b50<br \/>\n\u20074 \t2 \tNumber of this disk<br \/>\n\u20076 \t2 \tDisk where central directory starts<br \/>\n\u20078 \t2 \tNumber of central directory records on this disk<br \/>\n10 \t2 \tTotal number of central directory records<br \/>\n12 \t4 \tSize of central directory (bytes)<br \/>\n16 \t4 \tOffset of start of central directory, relative to start of archive<br \/>\n20 \t2 \tZIP file comment length (n)<br \/>\n22 \tn \tZIP file comment<\/code><\/p>\n<p>If we search the file for that, we get:<br \/>\n000bcb70  78 2e 62 69 6e 50 4b 05  06 00 00 00 00 01 00 01  |x.binPK&#8230;&#8230;&#8230;|<\/p>\n<p>So, from our Start PK 03 04 through to PK 05 06 we&#8217;re at position 0x14 through 0x0bcb79<\/p>\n<p>If we write that out now &#8211;<br \/>\ndd if=lr_cmos_11_14_1_46.bin of=test.zip skip=0x14 bs=1 count=0x0bcb79<\/p>\n<p>Then try unzip test.zip &#8211; we have a winner!<\/p>\n<p><code>lawrence$ unzip test.zip<br \/>\nArchive:  test.zip<br \/>\n  inflating: linux.bin<br \/>\nlawrence$ ls -al test.zip<br \/>\n-rw-r--r--  1 lawrence  staff  772985 Apr 30 03:28 test.zip<br \/>\nlawrence$ ls -al linux.bin<br \/>\n-rw-------@ 1 lawrence  staff  1628604 Dec  7 05:49 linux.bin<br \/>\n<\/code><\/p>\n<p>So, we know that the file has a header, then a zip file (which uncompresses to linux.bin, and has our linux binary), then more data.<\/p>\n<p>If we take a look at what follows &#8211; ie the rest of the data in the original file after the end of the zip, it doesn&#8217;t look compressed<\/p>\n<p>000bcb79  00 00 00 00 01 00 01 00  37 00 00 00 2a cb 0b 00  |&#8230;&#8230;..7&#8230;*&#8230;|<br \/>\n000bcb89  00 00 2d 72 6f 6d 31 66  73 2d 00 08 cf a0 98 16  |..-rom1fs-&#8230;&#8230;|<br \/>\n000bcb99  76 dd 72 6f 6d 20 34 62  31 63 62 36 38 66 00 00  |v.rom 4b1cb68f..|<br \/>\n000bcba9  00 00 00 00 00 49 00 00  00 20 00 00 00 00 d1 ff  |&#8230;..I&#8230; &#8230;&#8230;|<br \/>\n000bcbb9  ff 97 2e 00 00 00 00 00  00 00 00 00 00 00 00 00  |&#8230;&#8230;&#8230;&#8230;&#8230;.|<br \/>\n000bcbc9  00 00 00 00 00 60 00 00  00 20 00 00 00 00 d1 d1  |&#8230;..`&#8230; &#8230;&#8230;|<br \/>\n000bcbd9  ff 80 2e 2e 00 00 00 00  00 00 00 00 00 00 00 00  |&#8230;&#8230;&#8230;&#8230;&#8230;.|<br \/>\n000bcbe9  00 00 00 00 00 c9 00 00  00 80 00 00 00 00 8c 88  |&#8230;&#8230;&#8230;&#8230;&#8230;.|<br \/>\n000bcbf9  9d 47 73 77 61 70 00 00  00 00 00 00 00 00 00 00  |.Gswap&#8230;&#8230;&#8230;.|<\/p>\n<p>&#8230;<\/p>\n<p>000bd969  50 7d 64 68 63 70 63 00  00 00 00 00 00 00 00 00  |P}dhcpc&#8230;&#8230;&#8230;|<br \/>\n000bd979  00 00 62 46 4c 54 00 00  00 04 00 00 00 40 00 01  |..bFLT&#8230;&#8230;.@..|<br \/>\n000bd989  11 70 00 01 37 60 00 01  50 e8 00 00 28 00 00 01  |.p..7`..P&#8230;(&#8230;|<br \/>\n000bd999  37 60 00 00 02 b5 00 00  00 05 00 00 00 00 00 00  |7`&#8230;&#8230;&#8230;&#8230;..|<br \/>\n000bd9a9  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |&#8230;&#8230;&#8230;&#8230;&#8230;.|<br \/>\n000bd9b9  00 00 1f 8b 08 00 f4 6b  45 3f 02 03 dc 5b 0f 70  |&#8230;&#8230;.kE?&#8230;[.p|<br \/>\n000bd9c9  14 d7 79 7f bb 77 a7 bf  07 9c fe f0 c7 48 a0 95  |..y..w&#8230;&#8230;.H..|<br \/>\n000bd9d9  50 88 5c 23 b3 02 19 64  23 e0 84 30 76 72 b8 9c  |P.\\#&#8230;d#..0vr..|<br \/>\n000bd9e9  31 50 6c 2b 58 06 d7 25  84 d6 ea 80 6d 02 8c 7d  |1Pl+X..%&#8230;.m..}|<br \/>\n000bd9f9  48 02 64 17 b0 00 91 12  17 fb b6 29 ed 60 86 c6  |H.d&#8230;&#8230;..).`..|<br \/>\n000bda09  4c aa 74 34 0e 71 0e 90  03 d3 d2 54 fc 51 87 30  |L.t4.q&#8230;..T.Q.0|<\/p>\n<p>In fact it looks like more files&#8230;<\/p>\n<p>bFLT is our flat ELF header&#8230;, and the other bits in-between look suspiciously like more files, and folders.<br \/>\nSo, we probably have a filesystem in there.<\/p>\n<p>Its late, and thats all for today, but it looks like we might even get to play around with both the linux image and the web UI image.<\/p>\n<p>Just had another thought though &#8211; if you recall, our romfs size was  0x0008D000<\/p>\n<p>Image: 6 name:romfs.img base:0x7F0E0000 size:0x0008D000 exec:0x7F0E0000 -a<\/p>\n<p>What do we see here &#8211; in our header?   00000010 00 d0 08 00 <\/p>\n<p><code><br \/>\n00000000 42 4e 45 47 01 00 00 00 01 00 00 00 77 cb 0b 00 |BNEG\u2026\u2026..w\u2026|<br \/>\n00000010 00 d0 08 00 50 4b 03 04 14 00 00 00 08 00 3a 2e |\u2026.PK\u2026\u2026..:.|<br \/>\n<\/code><\/p>\n<p>Seem to have a match, no?  0x 08 d0 00<br \/>\nI&#8217;m going to bet that our 0x 00 0b cb 77 also has some meaning too in our header 20 bytes,  especially as the linux.bin zip file size is close to that at 0x00 0b cb 79.<\/p>\n<p>Its highly probable I&#8217;ve miscounted something with the offset, and thats going to turn out to be the zip file size.<\/p>\n<p>Now I&#8217;ve gotten this far, I&#8217;m too excited to go to sleep (its 4am here now!)<\/p>\n<p>Lets try the filesystem from where we left off (aka from 0x0bcb79)<br \/>\ndd if=lr_cmos_11_14_1_46.bin of=unsure_what_filesystem.img skip=0x0bcb79 bs=1 <\/p>\n<p> mount -r unsure_what_filesystem.img<br \/>\nmount: unsure_what_filesystem.img: unknown special file or file system.<\/p>\n<p>Nope.<\/p>\n<p>Kyle&#8217;s blog comment has this gem in <\/p>\n<blockquote><p>however the \u2018-romfs-\u2019 tag is offset by 0\u00d714<\/p>\n<p>so I used the line<\/p>\n<p>fx 6 romfs.img 0x7f0a0000 0x7f0a0014 -a<\/p>\n<p>the system then rebooted correctly\u2026\u201d<\/p><\/blockquote>\n<p>Lets use that as the start.<\/p>\n<p>hexdump -C unsure_what_filesystem.img |more<br \/>\n00000000  00 00 00 00 01 00 01 00  37 00 00 00 2a cb 0b 00  |&#8230;&#8230;..7&#8230;*&#8230;|<br \/>\n00000010  00 00 2d 72 6f 6d 31 66  73 2d 00 08 cf a0 98 16  |..-rom1fs-&#8230;&#8230;|<br \/>\n00000020  76 dd 72 6f 6d 20 34 62  31 63 62 36 38 66 00 00  |v.rom 4b1cb68f..|<\/p>\n<p>-rom1fs- starts at position 0x12 [which is another indicator that I&#8217;m off by 2 bytes somewhere &#8211; as they mention 0x14 bytes, and the 12bytes prefix I have prior to the -rom1fs- are going to be from our second file header, I&#8217;ll bet&#8230;<br \/>\n 0x0bcb79 &#8211; 2 = 0x0bcb77, which is what the previous header said, so that really makes me think thats the filesize now! <\/p>\n<p>Our ROMFS works out to  be 577 536 bytes, which is 0x8D000, which is also what the boot loader said, so getting a lot of good confirmation on these figures!]<\/p>\n<p>Write that out to another file:<br \/>\ndd if=unsure_what_filesystem.img of=still_unsure.img skip=0x12 bs=1 <\/p>\n<p>Still doesn&#8217;t mount on my Mac, however, some more googling for rom1fs uclinux got me here<\/p>\n<p>http:\/\/romfs.sourceforge.net\/<\/p>\n<p>Which specifically mentions &#8211; <\/p>\n<blockquote><p>Embedded projects using romfs<\/p>\n<p>uClinux, the microcontroller Linux, is a port of the kernel, and selected user-space programs to capable, embedded processors, like some &#8220;smaller&#8221; Motorola m68k, and ARM systems. <\/p><\/blockquote>\n<p>ROMFS looks like:<\/p>\n<p>offset      content<br \/>\n        +&#8212;+&#8212;+&#8212;+&#8212;+<br \/>\n  0     |  &#8211;  |  r  |  o  | m  |  \\<br \/>\n        +&#8212;+&#8212;+&#8212;+&#8212;+    The ASCII representation of those bytes<br \/>\n  4     |  1  |  f  |  s  |  &#8211;  |  \/    (i.e. &#8220;-rom1fs-&#8220;)<br \/>\n        +&#8212;+&#8212;+&#8212;+&#8212;+<br \/>\n  8     |     full size       |    The number of accessible bytes in this fs.<br \/>\n        +&#8212;+&#8212;+&#8212;+&#8212;+<br \/>\n 12     |    checksum   |       The checksum of the FIRST 512 BYTES.<br \/>\n        +&#8212;+&#8212;+&#8212;+&#8212;+<br \/>\n 16     |  volume name     |    The zero terminated name of the volume,<br \/>\n        :               :       padded to 16 byte boundary.<br \/>\n        +&#8212;+&#8212;+&#8212;+&#8212;+<br \/>\n xx     |     file      |<br \/>\n        :    headers    :<\/p>\n<p>struct romfs_super_block<br \/>\n{<\/p>\n<p>__u32 word0;<\/p>\n<p>__u32 word1;<\/p>\n<p>__u32 size;<\/p>\n<p>__u32 checksum;<\/p>\n<p>char name[0];        \/* volume name *\/<\/p>\n<p>};<\/p>\n<p>Which looks to be a *very* good match for what that header has!<br \/>\nSo, its in ROMFS format from the -rom1fs- start header.<\/p>\n<p>(Mostly from here &#8211; <a href=\"http:\/\/zhwen.org\/?p=articles\/romfs\">http:\/\/zhwen.org\/?p=articles\/romfs<\/a>) <\/p>\n<p>Unfortunately my OSX box appears to be missing romfs support, so I can&#8217;t check it without going back to the office.<\/p>\n<p>mount -o loop -t romfs  still_unsure.img \/mnt<br \/>\nmount: exec \/System\/Library\/Filesystems\/romfs.fs\/Contents\/Resources\/mount_romfs for \/mnt: No such file or directory<\/p>\n<p>Booted up my Debian VM, and tried again.<br \/>\n<code><br \/>\ndebian:\/mnt\/hgfs\/FI8908\uff0cFI8908W# mount -o loop -t romfs still_unsure.img \/mnt\/test -r<br \/>\ndebian:\/mnt\/hgfs\/FI8908\uff0cFI8908W# cd \/mnt\/test\/<br \/>\ndebian:\/mnt\/test# ls -al<br \/>\ntotal 4<br \/>\ndrwxr-xr-x 1 root root   32 1969-12-31 18:00 .<br \/>\ndrwxr-xr-x 4 root root 4096 2010-04-29 16:19 ..<br \/>\ndrwxr-xr-x 1 root root   32 1969-12-31 18:00 bin<br \/>\ndrwxr-xr-x 1 root root   32 1969-12-31 18:00 dev<br \/>\ndrwxr-xr-x 1 root root   32 1969-12-31 18:00 etc<br \/>\ndrwxr-xr-x 1 root root   32 1969-12-31 18:00 flash<br \/>\ndrwxr-xr-x 1 root root   32 1969-12-31 18:00 home<br \/>\ndrwxr-xr-x 1 root root   32 1969-12-31 18:00 proc<br \/>\ndrwxr-xr-x 1 root root   32 1969-12-31 18:00 swap<br \/>\ndrwxr-xr-x 1 root root   32 1969-12-31 18:00 usr<br \/>\n<\/code><\/p>\n<p>We have a winner!<\/p>\n<p>Full file listing below:<\/p>\n<p><code>.<br \/>\n|-- bin<br \/>\n|   |-- camera<br \/>\n|   |-- dhcpc<br \/>\n|   |-- ifconfig<br \/>\n|   |-- init<br \/>\n|   |-- iwconfig<br \/>\n|   |-- iwpriv<br \/>\n|   |-- mypppd<br \/>\n|   |   |-- chap-secrets<br \/>\n|   |   |-- options<br \/>\n|   |   |-- pap-secrets<br \/>\n|   |   `-- pppd<br \/>\n|   |-- route<br \/>\n|   |-- rt73.bin<br \/>\n|   |-- sh<br \/>\n|   |-- wetctl<br \/>\n|   `-- wpa_supplicant<br \/>\n|-- dev<br \/>\n|   |-- console<br \/>\n|   |-- display<br \/>\n|   |-- dsp -> dsp1<br \/>\n|   |-- dsp0<br \/>\n|   |-- dsp1<br \/>\n|   |-- fb0<br \/>\n|   |-- hda<br \/>\n|   |-- hda1<br \/>\n|   |-- hda2<br \/>\n|   |-- hdb<br \/>\n|   |-- i2c0<br \/>\n|   |-- i2c1<br \/>\n|   |-- key<br \/>\n|   |-- keypad<br \/>\n|   |-- lp0<br \/>\n|   |-- mixer -> mixer1<br \/>\n|   |-- mixer0<br \/>\n|   |-- mixer1<br \/>\n|   |-- mouse<br \/>\n|   |-- mtd0<br \/>\n|   |-- mtd1<br \/>\n|   |-- mtdblock0<br \/>\n|   |-- mtdblock1<br \/>\n|   |-- nftlA1<br \/>\n|   |-- nftla<br \/>\n|   |-- null<br \/>\n|   |-- ppp<br \/>\n|   |-- ppp1<br \/>\n|   |-- ptmx<br \/>\n|   |-- pts<br \/>\n|   |-- ptyp0<br \/>\n|   |-- ptyp1<br \/>\n|   |-- ptyp2<br \/>\n|   |-- ptyp3<br \/>\n|   |-- ptyp4<br \/>\n|   |-- ptyp5<br \/>\n|   |-- ptyp6<br \/>\n|   |-- ptyp7<br \/>\n|   |-- ptyp8<br \/>\n|   |-- ptyp9<br \/>\n|   |-- ptz0<br \/>\n|   |-- rom0<br \/>\n|   |-- rom1<br \/>\n|   |-- rom2<br \/>\n|   |-- sda<br \/>\n|   |-- sda1<br \/>\n|   |-- sda2<br \/>\n|   |-- sdb<br \/>\n|   |-- sdb1<br \/>\n|   |-- sdb2<br \/>\n|   |-- smartcard0<br \/>\n|   |-- smartcard1<br \/>\n|   |-- tty<br \/>\n|   |-- tty1<br \/>\n|   |-- ttyS0<br \/>\n|   |-- ttyS1<br \/>\n|   |-- ttyS2<br \/>\n|   |-- ttyS3<br \/>\n|   |-- ttyp0<br \/>\n|   |-- ttyp1<br \/>\n|   |-- ttyp2<br \/>\n|   |-- ttyp3<br \/>\n|   |-- ttyp4<br \/>\n|   |-- ttyp5<br \/>\n|   |-- ttyp6<br \/>\n|   |-- ttyp7<br \/>\n|   |-- ttyp8<br \/>\n|   |-- ttyp9<br \/>\n|   |-- urandom<br \/>\n|   |-- usb<br \/>\n|   |   |-- lp.sh<br \/>\n|   |   |-- lp0<br \/>\n|   |   |-- lp1<br \/>\n|   |   |-- lp2<br \/>\n|   |   |-- lp3<br \/>\n|   |   |-- lp4<br \/>\n|   |   |-- lp5<br \/>\n|   |   |-- lp6<br \/>\n|   |   |-- lp7<br \/>\n|   |   |-- lp8<br \/>\n|   |   `-- lp9<br \/>\n|   |-- usi<br \/>\n|   |-- video0<br \/>\n|   `-- video1<br \/>\n|-- etc<br \/>\n|-- flash<br \/>\n|-- home<br \/>\n|-- proc<br \/>\n|-- swap<br \/>\n|-- usr<br \/>\n`-- var<br \/>\n    `-- run<\/p>\n<p>13 directories, 97 files<\/code><\/p>\n<p>While I obviously can&#8217;t run any binaries locally, I can look at the text files to confirm that the ROMFS hasn&#8217;t just gotten the filesystem correct.<\/p>\n<p><code>debian:\/mnt\/test\/bin# cat init<br \/>\nmount -t proc none \/proc<br \/>\nmount -t ramfs none \/usr<br \/>\nmount -t ramfs none \/swap<br \/>\nmount -t ramfs none \/var\/run<br \/>\nmount -t ramfs none \/etc<br \/>\nmount -t ramfs none \/flash<br \/>\nmount -t ramfs none \/home<br \/>\ncamera&<br \/>\nsh<br \/>\n<\/code><\/p>\n<p><code>debian:\/mnt\/test\/bin# file camera<br \/>\ncamera: BFLT executable - version 4 ram gzip<br \/>\n<\/code><\/p>\n<p>Looking *very* good.<\/p>\n<p>Thats all for tonight, but it looks like we can easily add bits to the firmware using genromfs, dd, and a hex editor, or just genromfs, and someone willing to test a rebuilt user rom with an extra binary.  Probably going to be telnetd as ssh requires a kernel recompile \ud83d\ude41<\/p>\n<p>Next step, actually doing that, and testing.<\/p>\n<p>I&#8217;m definitely going to bed now &#8211; its 5:30am.<\/p>\n<p>Tomorrow is a holiday though (in China), so happy May holidays!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Spent a while checking out the different binaries available for the different OEM versions. Some interesting things I&#8217;ve found. If I take a look at a sample kernel &#8211; eg lr_cmos_11_14_1_46.bin ls -al lr_cmos_11_14_1_46.bin -rw-r&#8211;r&#8211; 1 lawrence staff 1350539 Mar 15 13:47 lr_cmos_11_14_1_46.bin Our file size for the file i have is 1350539 bytes. A [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[252,25],"tags":[256,253,197,245,240,255,254,247],"class_list":["post-477","post","type-post","status-publish","format-standard","hentry","category-ip-cam","category-technical-mumbo-jumbo","tag-bflt","tag-bneg","tag-firmware","tag-foscam","tag-ipcam","tag-linux-bin","tag-pkzip","tag-uclinux"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.computersolutions.cn\/blog\/wp-json\/wp\/v2\/posts\/477","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.computersolutions.cn\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.computersolutions.cn\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.computersolutions.cn\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.computersolutions.cn\/blog\/wp-json\/wp\/v2\/comments?post=477"}],"version-history":[{"count":12,"href":"https:\/\/www.computersolutions.cn\/blog\/wp-json\/wp\/v2\/posts\/477\/revisions"}],"predecessor-version":[{"id":919,"href":"https:\/\/www.computersolutions.cn\/blog\/wp-json\/wp\/v2\/posts\/477\/revisions\/919"}],"wp:attachment":[{"href":"https:\/\/www.computersolutions.cn\/blog\/wp-json\/wp\/v2\/media?parent=477"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.computersolutions.cn\/blog\/wp-json\/wp\/v2\/categories?post=477"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.computersolutions.cn\/blog\/wp-json\/wp\/v2\/tags?post=477"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}