axb_2019_fmt32

axb_2019_fmt32

Involved Knowledge

  • format string

Checksec

    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)

Program

Hello,I am a computer Repeater updated.
After a lot of machine learning,I know that the essence of man is a reread machine!
So I'll answer whatever you say!
Please tell me:123
Repeater:123

Analyze

main
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
  char s[257]; // [esp+Fh] [ebp-239h] BYREF
  char format[300]; // [esp+110h] [ebp-138h] BYREF
  unsigned int v5; // [esp+23Ch] [ebp-Ch]

  v5 = __readgsdword(0x14u);
  setbuf(stdout, 0);
  setbuf(stdin, 0);
  setbuf(stderr, 0);
  puts(
    "Hello,I am a computer Repeater updated.\n"
    "After a lot of machine learning,I know that the essence of man is a reread machine!");
  puts("So I'll answer whatever you say!");
  while ( 1 )
  {
    alarm(3u);
    memset(s, 0, sizeof(s));
    memset(format, 0, sizeof(format));
    printf("Please tell me:");
    read(0, s, 256u);
    sprintf(format, "Repeater:%s\n", s);
    if ( strlen(format) > 0x10E )
      break;
    printf(format);
  }
  printf("what you input is really long!");
  exit(0);
}

这里注意程序定义s变量时的大小和通过read去接收的大小是不足以形成stackoverflow这个漏洞的

 char s[257];
 read(0 , s , 256u);

同时这里有一个format string漏洞,我们可以在这里来从栈上泄露或者写入一些东西

sprintf(format, "Repeater:%s\n", s);

Solution 1

观察main函数结构我们可以构造这么一种我们通过format string来泄露出函数真实地址,拿到libc基址,system,然后通过fmtstr_payload将read函数的got表地址改成system,再搭配one_gadget拿到shell

泄露read函数地址

payload = b'a' + p32(read_got) + %8$s

这里因为用户的输入在栈上的偏移为8,这里也就是'a'的偏移为8,那么read的got表地址偏移则为9了,通过%8$s的方式来泄露read函数的真实地址

拿到read函数真实地址后减去偏移则为libc的基址,本来我是用LibcSearcher来打的,但是无奈libc库不太全,拿到的libc基址有问题,所以手动拿read的地址去找到对应的libc版本

下一步就是找对应的gadgets了

[0x3a80c , 0x3a80e , 0x3a812 , 0x3a819 , 0x5f065 , 0x5f066]

这道题的话0x3a812能打通

其他solution后续进行补充

posted @ 2022-09-26 15:19  dotExp  阅读(140)  评论(0编辑  收藏  举报