人生中的第一个代码审计题目。虽然有点low,也没什么坑,但是它是我的第一次啊啊啊啊,第一次总是让人难以忘记,不是嘛?文章适合初学者,写的比较详细,笔者只是在这记录一下,并没有别的想法。
0x00
首先介绍一下题目,题目是把源码下载到本地分析的,其中的文件结构是以下截图这样的。看到题目,咦,有sql文件,二话不说,那就先放到本机试试吧,于是把user.sql导入到本机数据库。然后一个一个看文件功能。
0x01
1.首先看public里的app.php。在默认用户名密码登录的情况下,可以用来调用执行server目录下的login,logout,img这三个php文件。例如http://127.0.0.1:8000/source_code/public/app.php?action=login...
2.index.html就是一个登录页面,在这里没什么用,是一个假的,没有跳转。
3.server下面login.php是可以用来get型登录的。调用sql.php文件来验证用户名密码是否正确,调用func.php来返回登录的状态。
4.下面重点来了,img.php,功能是读文件,关键点就在最后读文件,可以看出如果用户没有登录成功的状态下,$portrait是固定的为img/user.png。如果用户登录成功$portrait是变量,而且读的是当前数据库user表里面portrait的值。所以现在突破点就在变量$portrait这。如果想要实现任意文件读取,必须满足两个条件,一个是变量没有过滤,二变量可控,显示对变量是没有过滤的,想要实现可控就是要满足用户在登录网站,而且数据库可控制,因为我们要改数据库user表里面portrait的值。
因为我们本地搭建,就在本地可以很容易的修改数据库,把user.sql导入到本地,修改portrait字段值为../server/flag,因为flag文件在server下面,相对于img.php的话,就要改下相对路径。
文件功能分析完了,接下来需要实现了。
5.先登录网站,账号密码在user.sql文件里能找到,为test/test。如下操作:
条件都已经满足,现在要获取flag。因为是我本地,所以出现的是这个样子。
0x03
下面总结一下,顺便说下外网情况怎么做。
1.假如自己有一个外网服务器,ip:1.1.1.1,安装mysql,3306端口。
2.把user.sql导入到外网服务器的数据库中。数据库名test(随便起)。
3.修改user表中的portrait字段值为字符串"../server/flag"。
4.用默认的用户名密码登录,登录界面http://题目ip/public/app.php?action=login&name=test&pwd=test。
5.访问http://题目ip/public/app.php?action=img&dsn=test;host=1.1.1.1,就可以获取flag。
因为我没有外网就只能本地测试了,每次需要FQ都是蹭别人的。。没办法,笔者就是这么阔爱。啊哈哈哈......
要不要把附件放上去呢?有人要么?
昨天文章发表之后,有大神说描述不够清楚,我后来又看了一下好像是那么回事。其实两个关键点一个是任意文件读取那里,还有一个就是,怎么实现连接你外网的数据库的,这个突破点在sql.php文件里面,sql文件里面连接数据库是通过创建 PDO 基类的实例而建立的。构造函数接收用于指定数据库源(dsn)以及可能还包括用户名和密码(如果有的话)的参数。sql文件里面是这样定义的,$dsn = "mysql:dbname={$dsn}";,$dbh = new PDO($dsn, $username, $password, $options);,所以在连接数据库的时候,给$dsn参数传参的格式是:dsn=test;host=1.1.1.1。如果dsn是这样定义的,$dsn = "mysql:host={$dsn}";,那么传参的格式是:dsn=1.1.1.1;dbname=test。这就是0x03里面第5个步骤,为什么传参的格式是那样的。到此就解释完了。。。。。。