[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;
}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逆向萌新

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值