{"id":19456738,"url":"https://github.com/x0reaxeax/fetch-n-exec","last_synced_at":"2025-04-15T00:33:33.477Z","repository":{"id":134816920,"uuid":"427798070","full_name":"x0reaxeax/Fetch-n-Exec","owner":"x0reaxeax","description":"An x64 binary executing code that's not inside of it.","archived":false,"fork":false,"pushed_at":"2023-02-28T12:03:03.000Z","size":200,"stargazers_count":16,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-05T11:39:53.129Z","etag":null,"topics":["polymorphism","runtime-polymorphism","self-modifying-code","urban-dollop","x64"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/x0reaxeax.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-11-13T23:53:32.000Z","updated_at":"2025-02-16T02:46:44.000Z","dependencies_parsed_at":"2023-09-17T06:16:58.146Z","dependency_job_id":null,"html_url":"https://github.com/x0reaxeax/Fetch-n-Exec","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/x0reaxeax%2FFetch-n-Exec","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/x0reaxeax%2FFetch-n-Exec/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/x0reaxeax%2FFetch-n-Exec/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/x0reaxeax%2FFetch-n-Exec/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/x0reaxeax","download_url":"https://codeload.github.com/x0reaxeax/Fetch-n-Exec/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248985290,"owners_count":21193924,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["polymorphism","runtime-polymorphism","self-modifying-code","urban-dollop","x64"],"created_at":"2024-11-10T17:18:19.869Z","updated_at":"2025-04-15T00:33:33.453Z","avatar_url":"https://github.com/x0reaxeax.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Remote Machine Code Fetch \u0026 Exec\n_in other words, another self rewriting binary.. boy I just love doing these._\n\n## Description\nThe idea behind this one is to fetch opcodes and data from a remote server to rewrite the binary with during runtime.  \nExcept this time, we go x64 and `-nostdlib`, so everything will be done using syscalls and a few helper buddies.\n\n## Remote Server Setup \nAlright, we have our `index` file, which contains this long mess:\n`26F68656c6c6f20776f726c640a00x31c031ffffc0ffc748beffffffff77777777ba0d0000000f05b83c00000031ff0f05c3`\n\nThis can be broken down into 3 parts:\n### 1. Data Length\n`26F`  \nThe first 3 characters represent the length of data to be printed out.  \nThis includes the newline character and null terminator.  \n\nThe length is specified with decimal numbers and a non-decimal character to fill up the space, if needed. I just chose `F`, because \"F is for Family\" was playing on the TV, but literally anything non-decimal should be good to go.\n\nTo be more specific, this number specifies is the **number of characters** in the next part of the payload.\n\nThere is 13 bytes represented by 26 characters.\n\n### 2. Data\n`68656c6c6f20776f726c640a00`  \nThis is the payload to be printed. ASCII letters represented in hexadecimal. There is 11 of them (11x2). Afterwards comes the newline character (`0x0a`) and the null terminator (`0x00`). In this case, the text \"hello world\" is defined here.\n\n(11+2) × 2 = 26 characters in this section.\n\n### 3. Instructions\n`31c031ffffc0ffc748beffffffff77777777ba0d0000000f05b83c00000031ff0f05c3`  \nThis final part is separated from the previous part by the letter `'x'`, because it made debugging and constructing the payload easier.\nThese are our opcodes to be written and executed.\n\n```asm\n0:  31 c0                   xor    eax, eax\n2:  31 ff                   xor    edi, edi\n4:  ff c0                   inc    eax\n6:  ff c7                   inc    edi\n8:  48 be ff ff ff ff 77    movabs rsi, 0x77777777ffffffff\nf:  77 77 77\n12: ba 0d 00 00 00          mov    edx, 0xd\n17: 0f 05                   syscall\n19: b8 3c 00 00 00          mov    eax, 0x3c\n1e: 31 ff                   xor    edi, edi\n20: 0f 05                   syscall\n```\n\nThe first 4 lines load the `sys_write` syscall into `eax` and `STDOUT_FILENO` (`0x1`) into `edi`. We save 2 bytes by not using the `mov` instruction.  \nThe following `mov` instruction at `0x8` loads a placeholder 64bit address `0x77777777FFFFFFFF` into `rsi`. We will be overwriting this, once we can determine our data address during runtime (technically, this could totally be done now without any runtime calculations, but I will benefit from this approach, when I'll be doing **🎇 r e v e r s e _ s h e l l s 🎆** next).  \nNext is loading the hardcoded size `0xd` as the `strlen` argument. This will be overwritten during runtime in the upgraded version of this that was just mentioned above, but for now, it's `(int) 13`.  \nNow, we just execute this with `syscall`.  \nFollowing is only the `sys_exit` syscall, with return code `0` (`EXIT_SUCCESS`), which just obviously ends the program, since (for now, hihihaha) there's nowhere we can jump to continue execution.\n\n\n## Order of operations\nFirst, we try to fetch the remote data using the function `read_remote_bytes()`. I say \"try\", because this makeshift function uses the Linux socket for IPv4 communication, which basic functionality is achieved mostly by glueing some syscalls together.  \nTwo specific syscalls are known to cause trouble here, that being `sys_recvfrom` and `sys_sendto`. These guys don't want to work all the time for some reason (in other words, me doing something wrong), but due to nature of this function being completely makeshift, I don't really care that much. If the execution fails, one of the following error codes is returned:\n\n| Code | Name      | Description                   | \n|------|-----------|-------------------------------|\n| 3    | EINPUT    | Invalid/Corrupted remote data |\n| 4    | EMPROTECT | sys_mprotect RWX failure      |\n| 5    | EREAD     | Error reading socket fd       |\n| 6    | ESOCKSEND | sys_sendto error |\n| 7    | ESOCKRECV | sys_recvfrom error |\n| 8    | ECLOSE    | Error closing socket fd |\n\nCheck yours with `$ echo $?`  \n\nAfter we successfully fetch our remote data, we need to get `WRITE` permission for the text segment, or to be more specific, the closest, page-aligned address to our target function-to-be-rewrtitten - `int _malloc(void)`. I don't really know why I named it `_malloc`, so just deal with it. We use the `sys_mprotect` syscall to achieve this, which we feed with `PROT_READ | PROT_WRITE | PROT_EXEC`, to flip the bits we need (RWX).  \n\nThe only things left to do are converting our remote-fetched characters to hex bytes, writing them at `\u0026_malloc` and calculating a usable address to store our data to be printed, which is actually the very first byte after our last opcode, so that's where we write our data. After that, we are ready to execute!\n\n## Demo\n\n\nhttps://user-images.githubusercontent.com/61374847/141669441-661e17da-a441-4d34-899b-ef8fdcf8ba3b.mp4  \n\n![733655604404420648](https://user-images.githubusercontent.com/61374847/141669516-c19286fe-b13c-4f6e-99ff-080a201d94dc.png)\n\nThis is the disassembly of compiled code for our `_malloc` function:\n\nDisassembly of `_malloc`\n```nasm\n000000000000187e \u003c_malloc\u003e:\n    187e:       55                      push   rbp\n    187f:       48 89 e5                mov    rbp,rsp\n    1882:       ff                      (bad)\n    1883:       ff                      (bad)\n    1884:       ff                      (bad)\n    1885:       ff                      (bad)\n    ; \u003c ... repeat ... \u003e\n    197f:       ff                      (bad)\n    1980:       ff                      (bad)\n    1981:       ff                      .byte 0xff\n    1982:       90                      nop\n    1983:       5d                      pop    rbp\n    1984:       c3                      ret\n```\n\n\n**Runtime** Dump of assembler code for function `_malloc`:\n```asm\n   0x000055555555587f \u003c+0\u003e:     31 c0                           xor    eax, eax\n   0x0000555555555881 \u003c+2\u003e:     31 ff                           xor    edi, edi\n   0x0000555555555883 \u003c+4\u003e:     ff c0                           inc    eax\n   0x0000555555555885 \u003c+6\u003e:     ff c7                           inc    edi\n   0x0000555555555887 \u003c+8\u003e:     48 be a2 58 55 55 55 55 00 00   movabs rsi, 0x5555555558a2\n   0x0000555555555891 \u003c+18\u003e:    ba 0d 00 00 00                  mov    edx, 0xd\n   0x0000555555555896 \u003c+23\u003e:    0f 05                           syscall\n   0x0000555555555898 \u003c+25\u003e:    b8 3c 00 00 00                  mov    eax, 0x3c\n   0x000055555555589d \u003c+30\u003e:    31 ff                           xor    edi,edi\n   0x000055555555589f \u003c+32\u003e:    0f 05                           syscall\n   0x00005555555558a1 \u003c+34\u003e:    c3                              ret\n   \u003c --- DATA BYTES START HERE --- \u003e\n   0x00005555555558a2 \u003c+35\u003e:    68 65 6c 6c 6f\n   0x00005555555558a7 \u003c+40\u003e:    20 77 6f\n   0x00005555555558aa \u003c+43\u003e:    72 6c   jb\n   0x00005555555558ac \u003c+45\u003e:    64 0a 00\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fx0reaxeax%2Ffetch-n-exec","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fx0reaxeax%2Ffetch-n-exec","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fx0reaxeax%2Ffetch-n-exec/lists"}