CTF 2023 三道pwn题

本文详细介绍了三道CTF(Capture The Flag)挑战中的pwn题目,包括appointment_book、impossible_v2和ropedancer。题目涉及栈溢出、格式化字符串漏洞和SROP利用技术。在appointment_book中,通过输入负数索引修改got表项获取shell;impossible_v2利用格式化字符串漏洞修改AES加密密钥;ropedancer则利用栈溢出和SROP技术执行任意代码。每道题都解析了程序信息、逆向分析和利用思路,并提供了利用脚本示例。
摘要由CSDN通过智能技术生成

作者丨selph

appointment_book

程序信息

程序保护信息:

➜ HeroCTF checksec appointment_book
[*] '/home/selph/ctf/HeroCTF/appointment_book'
    Arch:     amd64-64-little
    RELRO:    No RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)

这里其实已经给出提示了,没有Relocation Read-Only,没有PIE,说明可以去修改got表项,当时咋就没想到呢hhhh

程序运行信息:

***** Select an option *****
1) List appointments
2) Add an appointment
3) Exit

Your choice: 2
[+] Enter the index of this appointment (0-7): 0
[+] Enter a date and time (YYYY-MM-DD HH:MM:SS): 1111-11-11 22:22:22
[+] Converted to UNIX timestamp using local timezone: -27080300601
[+] Enter an associated message (place, people, notes...): YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY

***** Select an option *****
1) List appointments
2) Add an appointment
3) Exit

Your choice: 1

[+] List of appointments:
- Appointment n°1:
    - Date: 1111-11-11 22:22:22
    - Message: YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY

- Appointment n°2:
    [NO APPOINTMENT]
- Appointment n°3:
    [NO APPOINTMENT]
- Appointment n°4:
    [NO APPOINTMENT]
- Appointment n°5:
    [NO APPOINTMENT]
- Appointment n°6:
    [NO APPOINTMENT]
- Appointment n°7:
    [NO APPOINTMENT]
- Appointment n°8:
    [NO APPOINTMENT]

***** Select an option *****
1) List appointments
2) Add an appointment
3) Exit

逆向分析

主程序:就是提供个菜单项,主要功能在菜单函数内

int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
  char *v3; // rax
  int v4; // [rsp+4h] [rbp-Ch]
  time_t v5; // [rsp+8h] [rbp-8h]

  memset(&appointments, 0, 0x80uLL);
  puts("========== Welcome to your appointment book. ==========");
  v5 = time(0LL);
  v3 = timestamp_to_date(v5);
  printf("\n[LOCAL TIME] %s\n", v3);
  fflush(stdout);
  while ( 1 )
  {
    v4 = menu();
    if ( v4 == 3 )
    {
      puts("\n[+] Good bye!");
      fflush(stdout);
      exit(1);
    }
    if ( v4 > 3 )
    {
LABEL_10:
      puts("\n[-] Unknwon choice\n");
      fflush(stdout);
    }
    else if ( v4 == 1 )
    {
      list_appointments();
    }
    else
    {
      if ( v4 != 2 )
        goto LABEL_10;
      create_appointment();
    }
  }
}

list_appointments函数:这里只是展示结构体保存的内容,没有什么特别的

int list_appointments()
{
  int result; // eax
  char *v1; // rax
  int i; // [rsp+4h] [rbp-Ch]
  const char **v3; // [rsp+8h] [rbp-8h]

  puts("\n[+] List of appointments: ");
  result = fflush(stdout);
  for ( i = 0; i <= 7; ++i )
  {
    v3 = (const char **)((char *)&appointments + 16 * i);
    printf("- Appointment n°%d:\n", (unsigned int)(i + 1));
    if ( v3[1] )
    {
      v1 = timestamp_to_date((time_t)*v3);
      printf("\t- Date: %s\n", v1);
      printf("\t- Message: %s\n", v3[1]);
    }
    else
    {
      puts("\t[NO APPOINTMENT]");
    }
    result = fflush(stdout);
  }
  return result;
}

create_appointment():这里是向结构体里填充内容,但不存在堆栈相关漏洞

这里的结构体是在IDA里手动创建的,打开结构体窗口,然后右键创建即可

unsigned __int64 create_appointment()
{
  __int64 v0; // rax
  int i; // [rsp+Ch] [rbp-24h] BYREF
  void *tmp_data; // [rsp+10h] [rbp-20h]
  char *content; // [rsp+18h] [rbp-18h]
  Appointment *v5; // [rsp+20h] [rbp-10h]
  unsigned __int64 v6; // [rsp+28h] [rbp-8h]

  v6 = __readfsqword(0x28u);
  tmp_data = malloc(0x20uLL);
  content = (char *)malloc(0x40uLL);            // 可以申请一堆,导致内存泄露,但没啥用
  memset(tmp_data, 0, 0x20uLL);
  memset(content, 0, 0x40uLL);
  do
  {
    printf("[+] Enter the index of this appointment (0-7): ");
    fflush(stdout);
    __isoc99_scanf("%d", &i);
    getchar();
  }
  while ( i > 7 );              // 【关键点!!!!!】
  v5 = &appointments[i];
  printf("[+] Enter a date and time (YYYY-MM-DD HH:MM:SS): ");
  fflush(stdout);
  fgets((char *)tmp_data, 0x1E, stdin);
  v0 = date_to_timestamp((__int64)tmp_data);    // 接收到一个数字
  v5->time 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

极安御信安全研究院

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

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

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

打赏作者

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

抵扣说明:

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

余额充值