跳转至

pwntools

此题用于熟悉python中的pwntools包

1.题目

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <time.h>
#include <unistd.h>

void handler(int signum){
  puts("Timeout");
  _exit(1);
}

int main()
{
  setvbuf(stdout, 0, 2, 0);
  setvbuf(stdin, 0, 2, 0);
  signal(SIGALRM, handler);
  alarm(90);

  unsigned seed = (unsigned)time(NULL);
  srand(seed);

  unsigned int magic;
  printf("Give me the magic number :)\n");
  read(0, &magic, 4);
  if (magic != 3735928559) {
    printf("Bye~\n");
    exit(0);
  }

  printf("Complete 1000 math questions in 90 seconds!!!\n");
  for (int i = 0; i < 1000; ++i) {
    int a = random() % 65535;
    int b = random() % 65535;
    int c = random() % 3;
    int ans;
    switch(c) {
      case 0:
        printf("%d + %d = ?", a, b);
        scanf("%d", &ans);
        if (ans != a + b) {
          printf("Bye Bye~\n");
          exit(0);
        }
        break;
      case 1:
        printf("%d - %d = ?", a, b);
        scanf("%d", &ans);
        if (ans != a - b) {
          printf("Bye Bye~\n");
          exit(0);
        }
        break;
      case 2:
        printf("%d * %d = ?", a, b);
        scanf("%d", &ans);
        if (ans != a * b) {
          printf("Bye Bye~\n");
          exit(0);
        }
        break;
    }
  }
  printf("Good job!\n");
  system("sh");

  return 0;
}

Makefile:

pwntools: pwntools.c
  gcc pwntools.c -o pwntools

2.思路

因为题中read函数只接受4个Bytes,所以把3735928559转为16进制,为0xdeadbeef,刚好4个Bytes,即可通过第一个检查,

然后是一个循环,随机输出1000道计算题,并且要求在90s内完成,可以用pwntools的recvuntil函数截获计算题的题目,然后用eval函数执行计算,

最后用interactive函数获取终端交互

3.解题脚本

from pwn import *

# r = remote("*.*.*.*",****)
r = process("./pwntools")

r.recvline()
magic_num = p32(0xdeadbeef)
r.send(magic_num)
r.recvline()
for i in range(1000):
    exp = str(r.recvuntil("?"))[2:-4]
    print(exp)
    r.sendline(str(eval(exp)))

r.interactive()