资讯详情

[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("?s", &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;
}

看一下,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;
}

发现是这些东西,但是看不懂,咱们开始动调,发现是获取你输入的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;

__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以十进制

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

n = 103461035900816914121390101299049044413950405173712170434161686539878160984549

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

n = 103461035900816914121390101299049044413950405173712170434161686539878160984549
p = 282164587459512124844245113950593348271
q = 366669102002966856876605669837014229419
e = 65537
c = 0xad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35

现在需要求出来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:])

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

标签: 4083d06pd光电传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

 锐单商城 - 一站式电子元器件采购平台  

 深圳锐单电子有限公司