Hello I am Arsalan. Offensive Security Engineer, I blog about Cyber security, CTF writeup, Programming, Blockchain and more about tech. born and raised in indonesia, currently living in indonesia
On Friday, 19 May, 2023. I participate on greyCTF 2023 and solved several challenge. In this post I will only cover a challenge called ropv, since this is my first time exploiting RISC-V 64 architecture. It might be useful note for me or someone in order create the ropchain exploit.
What is Riscv64?
RISC-V (pronounced “risk-five”) is an open source instruction set architecture (ISA) based on established reduced instruction set computing (RISC) principles.
In contrast to most ISAs, RISC-V is freely available for all types of use, permitting anyone to design, manufacture and sell RISC-V chips and software. While not the first open ISA, it is significant because it is designed to be useful in modern computerized devices such as warehouse-scale cloud computers, high-end mobile phones and the smallest embedded systems. Such uses demand that the designers consider both performance and power efficiency. The instruction set also has a substantial body of supporting software, which fixes the usual weakness of new instruction sets.
The project was originated in 2010 by researchers in the Computer Science Division at UC Berkeley, but many contributors are volunteers and industry workers that are unaffiliated with the university.
https://wiki.debian.org/RISC-V#What_is_RISC-V.3F
Dynamic Analysis
Since my Binary Ninja and IDA can’t decompile the riscv64 elf binary. So I started by doing some dynamic gdb stuff and blackbox. We can use qemu to emulate the riscv64 and gdb-multiarch to debug the binary remotely
I found that we have a format string vulnerability on the first input and a buffer overflow on the second input, So the plan is simple we can leak the variable address from the first index and leak the canary value from the third index
then we can overflow the second input and bypass the canary check so that we can control the %pc register and craft a ropchain to call execve with /bin/sh as the first parameter.
Exploitation
first we need some gadget to set the register value in order to call execve(). We can use riscv64 toolchain riscv64-unknown-elf-objdump to gather all gadget that we need. execve() in riscv64 is 221 and we need to set the register value to look like this
execve(0x[address to /bin/sh], 0, 0)
I use this gadget since it cover all registers we need
We also need another gadget so we can return safely to %a0 and trigger the syscall there
Last thing we need an ecall instruction to trigger the syscall
So our plan is:
We leak the address variable and canary value from the first input
craft a ropchain that can be used to bypass the canary protection
overwrite the %pc to the first gadget so we can set all register properly to call execve() syscall
since we already know the address of our input, we can stored our /bin/sh string there