• [buuctf][SUCTF2019]SignIn


    [SUCTF2019]SignIn

    解析

    先查看一下,发现这是一个无壳64位的一个可执行文件,拖入ida中查看main函数。

    __int64 __fastcall main(__int64 a1, char **a2, char **a3)
    {
      char v4; // [rsp+0h] [rbp-4A0h]
      char v5; // [rsp+10h] [rbp-490h]
      char v6; // [rsp+20h] [rbp-480h]
      char v7; // [rsp+30h] [rbp-470h]
      char v8; // [rsp+40h] [rbp-460h]
      char v9; // [rsp+B0h] [rbp-3F0h]
      unsigned __int64 v10; // [rsp+498h] [rbp-8h]
    
      v10 = __readfsqword(0x28u);
      puts("[sign in]");
      printf("[input your flag]: ", a2);
      __isoc99_scanf("%99s", &v8);
      sub_5623E300096A(&v8, &v9);
      __gmpz_init_set_str(&v7, "ad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35", 16LL);
      __gmpz_init_set_str(&v6, &v9, 16LL);
      __gmpz_init_set_str(&v4, "103461035900816914121390101299049044413950405173712170434161686539878160984549", 10LL);
      __gmpz_init_set_str(&v5, "65537", 10LL);
      __gmpz_powm(&v6, &v6, &v5, &v4);
      if ( (unsigned int)__gmpz_cmp(&v6, &v7) )
        puts("GG!");
      else
        puts("TTTTTTTTTTql!");
      return 0LL;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    看一下,sub_5623E300096A做了什么。

    size_t __fastcall sub_5623E300096A(const char *a1, __int64 a2)
    {
      size_t result; // rax
      int v3; // [rsp+18h] [rbp-18h]
      int i; // [rsp+1Ch] [rbp-14h]
    
      v3 = 0;
      for ( i = 0; ; i += 2 )
      {
        result = strlen(a1);
        if ( v3 >= result )
          break;
        *(_BYTE *)(a2 + i) = byte_5623E3202010[(char)(a1[v3] >> 4)];
        *(_BYTE *)(a2 + i + 1LL) = byte_5623E3202010[a1[v3++] & 0xF];
      }
      return result;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    发现是这些东西,但是看不懂,咱们开始动调,发现是获取你输入的ascii码是多少,之后一直在循环,直到获取完所有的。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    我输入的是5个a,之后返回为6161616161,所以这个是在获取你的ascii码,之后跳了回来,看反编译

      __gmpz_init_set_str(&v7, "ad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35", 16LL);
      __gmpz_init_set_str(&v6, &v9, 16LL);
      __gmpz_init_set_str(&v4, "103461035900816914121390101299049044413950405173712170434161686539878160984549", 10LL);
      __gmpz_init_set_str(&v5, "65537", 10LL);
      __gmpz_powm(&v6, &v6, &v5, &v4);
      if ( (unsigned int)__gmpz_cmp(&v6, &v7) )
        puts("GG!");
      else
        puts("TTTTTTTTTTql!");
      return 0LL;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    __gmpz_init_set_str查了一下,这个是GUN高精度算法库里面的函数,官方文链接: 官方文档

    __gmpz_init_set_str(&v7, "ad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35", 16LL);
    #v7保存ad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35以十六进制方式。
    __gmpz_init_set_str(&v6, &v9, 16LL);
    #v6保存转换为ascii的数值以十六进制
    __gmpz_init_set_str(&v4, "103461035900816914121390101299049044413950405173712170434161686539878160984549", 10LL);
    #v4保存103461035900816914121390101299049044413950405173712170434161686539878160984549以十进制
    __gmpz_init_set_str(&v5, "65537", 10LL);
    #v5保存65537以十进制
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    __gmpz_powm根据官方文档的解释进行对照是v6 ^v5%v4,之后返回值给v6,之后__gmpz_cmp比较v6和v7是否相等,看起来是一个RSA的题,咱们先分解大大整数n,分解出来p和q,

    n = 103461035900816914121390101299049044413950405173712170434161686539878160984549
    
    • 1

    这里要用到一个工具是yafu,调用大佬文章链接: yafu
    最后获得到了。

    n = 103461035900816914121390101299049044413950405173712170434161686539878160984549
    p = 282164587459512124844245113950593348271
    q = 366669102002966856876605669837014229419
    e = 65537
    c = 0xad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35
    
    • 1
    • 2
    • 3
    • 4
    • 5

    现在需要求出来m和d的值,利用python的给,gmpy2库进行求解

    脚本

    import gmpy2
    n = 103461035900816914121390101299049044413950405173712170434161686539878160984549
    p = 282164587459512124844245113950593348271
    q = 366669102002966856876605669837014229419
    e = 65537
    c = 0xad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35
    d = gmpy2.invert(e, (p - 1) * (q - 1))
    m = gmpy2.powmod(c, d, n)
    print (hex(m)[2:])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    求出来了是十六进制,之后转为字符串即可获得suctf{Pwn_@_hundred_years}

  • 相关阅读:
    SpringBoot整合Jpa实现增删改查功能(提供Gitee源码)
    爬虫使用代理IP不会被限的原因解析
    基于POI的可快速定制Excel导出脚本设想
    新增一块新磁盘后,扩充逻辑卷lv大小
    JavaSE 第六章 面向对象基础-中(封装)
    出海 SaaS 企业增长修炼手册:聊聊 PLG 的关键指标、技术栈和挑战
    补题2.0
    生产管理:专项生产业务管理系统
    C#和.NET FrameWork概述
    如何选择合适的自动化测试工具?
  • 原文地址:https://blog.csdn.net/m0_71081503/article/details/125564644