再论跨站脚本攻防之道

本文已发表于《黑客防线》

作者:Xylitol
译者:riusksk

目录

0x100 The Cross Frame Scripting
| 0x110 理论阐述
| 0x111  漏洞代码样本
| 0x112  编写安全代码
0x200 Header for fun and profit
|0x210 Cross Agent Scripting
|0x211 首份XAS漏洞代码
|0x212 安全的XAS.php代码
|0x220 Cross Referer Scripting
|0x221 XRS漏洞代码
|0x222 安全的XRS.php代码
|0x230 HTTP Response splitting
0x300 Cross-site request forgery

| 0x310 基础知识
| 0x311 漏洞代码
| 0x312 编写安全代码

0x400 其它学习资料

0x100 The Cross Frame Scripting

0x110 理论阐述

The Cross Frame Scripting 缩写为“XFS”,主要是由于被访问的页面中的frame地址里的变量缺乏检测所导致的漏洞。
例如:
http://www.site.com/navigate.php?url=guestbook/index.php
在frame中是显示留言本,但我们可将其更改为:
http://www.site.com/navigate.php?url=http://google.com
使其指向google主页(请不要与包含漏洞相混淆)。
Cross Frame Scripting主要用于钓鱼攻击,因为该漏洞具备一定的危害性,一名跨站者(xsser)可以构造以下URL地址:
?url=http://xsser.com/phishing.php
同时将其编码为十六进制值:

%3F%75%72%6C%3D%68%74%74%70%3A%2F%2F%6C%61%6D%7A%6F%72%2E
%63%6F%6D%2F%70%68%69%73%68%69%6E%67%2E%70%68%70

漏洞触发:

image1

0x111 漏洞代码样本

下面建议一个存在漏洞的微型站点。首先需要创建四个文件:

1. en_tete.htm
2. accueil.htm
3. navigation.htm
4. index.php

navigation.htm:

<!DOCTYPE html PUBLIC "//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta httpequiv="ContentType" content="text/html; charset=utf8" />
<title>Menu</title>
</head>
<body bgcolor="#CCCCCC">
<pre>&nbsp;

</pre>
<p>&nbsp;</p>
<p>&nbsp;</p>
<ul>
<li><a href="index.php?iframe=http://google.com" target="_parent">google</a></li>
<li><a href="index.php?iframe=http://fr.wikipedia.org/wiki/Accueil"
target="_parent">wiki</a></li>
<li><a href="index.php?iframe=http://xylitol.free.fr/" target="_parent">Xylitol</a></li>
</ul>
<p>&nbsp;</p>
</body>
</html>

En_tete.htm:

<!DOCTYPE html PUBLIC "//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta httpequiv="ContentType" content="text/html; charset=utf8" />
<title>en tete</title>
<style type="text/css">
<!
.Style1 {
color: #FFFFFF;
fontsize: 36px;
}
>
</style>
</head>
<body bgcolor="#00007F">
<span>Welcome in: mysiteisnotsecure.fr !</span>
<br />
Valid W3C !1!1!1!!1  Greetz: Shéìяy
</body>
</html>

accueil.htm:

<!DOCTYPE html PUBLIC "//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta httpequiv="ContentType" content="text/html; charset=utf8" />
<title>Accueil</title>
</head>
<body bgcolor="#FFCC66">
<h1>What the Hell ?</h1>
</body>
</html>

index.php:

<!DOCTYPE html PUBLIC "//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<head>
<meta httpequiv="ContentType" content="text/html; charset=utf8" />
<title> Welcome in mysiteisnotsecure.fr</title>
</head>
<frameset rows="*" cols="110,*" frameborder="NO" border="0" framespacing="0">
<frame src="navigation.htm" name="navigation" frameborder="yes" scrolling=""NO"
bordercolor="#0000CC" id="navigation">
<frameset rows="98,*" cols="*" framespacing="0" frameborder="NO" border="0" >
<frame src="en_tete.htm" name="entete" frameborder="yes" scrolling="NO"
bordercolor="#000000" id="entete">
<frame  src="<?php
if(isset($_GET['iframe']))
echo $_GET['iframe']; // OMG  Epic fail !
else
echo "accueil.htm";
?>" name="corps" scrolling="auto" id="corps">
</frameset>
</frameset><noframes>No frames :(</noframes>
</html>

Syntax: index.php?iframe=http://google.com

0x112 编写安全代码

针对此项漏洞,我们可采取以下方式进行修补:

Index.php:

<!DOCTYPE html PUBLIC “//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<head>
<meta httpequiv="ContentType" content="text/html; charset=utf8" />
<title> Welcome in mysiteissecurenow.fr</title>
</head>
<frameset rows="*" cols="110,*" frameborder="NO" border="0" framespacing="0">
<frame src="navigation.htm" name="navigation" frameborder="yes" scrolling=""NO"
bordercolor="#0000CC" id="navigation">
<frameset rows="98,*" cols="*" framespacing="0" frameborder="NO" border="0" >
<frame src="en_tete.htm" name="entete" frameborder="yes" scrolling="NO"
bordercolor="#000000" id="entete">
<frame  src="<?php
//secure code
if(isset($_GET['iframe']))
{
$allowUrls = array("http://google.com", "http://fr.wikipedia.org/wiki/Accueil",
"http://xylitol.free.fr/"); // add your allowed links here

if(in_array($_GET['iframe'], $allowUrls))
echo $_GET['iframe']; //if iframe have an url allowed
else // for show the main page (or an error page)
echo "accueil.htm";
}
else // !!!
echo "accueil.htm";
?>" name="corps" scrolling="auto" id="corps">
</frameset>
</frameset><noframes>No frames :(</noframes>
</html>

其它解决方法:

// Checking urls with regex
<?php
if(isset($_GET['iframe']))
{
if(preg_match("#http://xylitol\Sfree\Sfr/SiteSecure/[0-9A-Za-z.-
]{1,13}.htm#", $_GET['iframe'])) // The document must make between 1 and 13 letters in front of
".htm", it leaves a short  number preferably
echo htmlentities($_GET['iframe']); //we secure xss
else // Show main page (or an error page)
echo "accueil.htm";
}
?>

0x200 Header for fun and profit
0x210 Cross Agent Scripting

Cross Agent Scripting (XAS)是指在浏览器的User-Agent字符串中执行html 或者 JavaScript 代码。假设你访问了某站点,并且该站点已经向你提供了User-Agent信息。User-Agent经过修改后,如果在该网站上查看它,即可引发跨站。

Basic header request:

GET /search?q=lol&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:fr:official&client=firefox-a HTTP/1.1
Host: www.google.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.9.0.1) Gecko/2008070208
Firefox/3.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Cookie: PREF=ID=28b7ef6af5bc7c75:TM=1216021699:LM=1216150284:GM=1:S=aGO7RnRgf-g-
4roM; NID=14=W9uUr5xq78IfW_kvmrt5okJYaXkZpWV14dQQMOtug2Rx3-
mmQAhYRYR5vGUbGVdpKpaxKC88s7G5ZYBx7gdB_Ga9Z500BCerjyJPQ2gfVyflM-
cjXTf8TzJO4dSMjQHR

攻击 header request:

GET /search?q=lol&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:fr:official&client=firefox-a HTTP/1.1
Host: www.google.com
User-Agent: <script>alert('X \nS\nS')</script>
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Cookie: PREF=ID=28b7ef6af5bc7c75:TM=1216021699:LM=1216150284:GM=1:S=aGO7RnRgf-g-
4roM; NID=14=W9uUr5xq78IfW_kvmrt5okJYaXkZpWV14dQQMOtug2Rx3-
mmQAhYRYR5vGUbGVdpKpaxKC88s7G5ZYBx7gdB_Ga9Z500BCerjyJPQ2gfVyflM-
cjXTf8TzJO4dSMjQHR

构造User-Agent 固然很酷,但我们如何来修改它呢?你可以通过以下方式篡改User-Agent :
首先需要借助Mozilla Firefox,并在地址栏中输入‘about:config’,接着右击-> New -> String,Firefox会提示‘Enter the preference name’或者类似的信息,然后输入:general.useragent.override ,并点击[OK]。然后就会出现一些像html或者javascript代码的字符串,点击OK。
下面是2008.9.11在Firefox 2.x与3.x版本上测试的。
Firefox v3.0.1法语版:

image2

其它在Firefox上篡改User-Agent的方法:在google上搜索插件‘User Agent Switcher’,通过该插件即可修改User-Agent值。如下图所示:

image3

0x211首份XAS漏洞代码

打开记事本,复制代码,并将文件保存为XAS.php
存在漏洞的XAS.php代码:

<?php
echo (getenv(“HTTP_USER_AGENT”));
echo ‘<br />’; //or
echo ($_SERVER[‘HTTP_USER_AGENT’]);
?>

修改User-Agent后:

image4

0x212 安全的XAS.php代码:

<?php
echo htmlspecialchars (getenv(“HTTP_USER_AGENT”));
echo ‘<br />’; //or
echo htmlspecialchars ($_SERVER[‘HTTP_USER_AGENT’]);
?>

利用javascript显示User-Agent:
比如在搜索框或公式集中进行测试:

<script language=javascript>
document.write(navigator.userAgent);
</script>

注意:Cross User-Agent Scripting并非仅局限于‘cross’,你可以尝试其它攻击方式,比如SQL注入等。

0x220 Cross Referer Scripting

其它执行恶意代码的方式:与XAS相似,Cross Referer Scripting (XRS) 也可利用HTTP头来执行代码。referer常被WEB站点管理员来追踪访问者,因为它可以帮助管理员查看访问来自哪个站点。
例如:anonym.to
我们只需用恶意代码如html(不过需要借助Firefox来实现)来替换 referer串值,即可实现XRS,但很多管理员尚未知晓或忽视该漏洞。
下载Firefox插件: RefControl(http://www.stardrifter.org/refcontrol/ ),如果以上链接失效,可自行在google中搜索。
打开插件选项,并执行以下配置:

image5

测试结果:

image6

header request:

GET /search?hl=fr&client=firefox-
a&rls=org.mozilla%3Afr%3Aofficial&hs=Kcu&q=lawl&btnG=Rechercher&meta= HTTP/1.1
Host: www.google.fr
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.9.0.1) Gecko/2008070208
Firefox/3.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://www.google.fr/search?q=lol&ie=utf-8&oe=utf-
8&aq=t&rls=org.mozilla:fr:official&client=firefox-a
Cookie: SS=Q0=bG9s;
PREF=ID=d53b13b79d03a27c:TM=1216021699:LM=1216021699:S=E3oh8T7Jxha5G7PY;
NID=14=prJQ6exoKYllCGBc0TnP9enIcd2UA-DXWmdaRqWTJfMXTzUklR6-
LpdQRvBHb0ezOcNpEV86Fj67G5sbTRx-5fimqOWXDSAeXwMf3tcfs1Wil3HxfofzDIU2VRX6jNo_

攻击header request :

GET /search?hl=fr&client=firefox-
a&rls=org.mozilla%3Afr%3Aofficial&hs=Kcu&q=lawl&btnG=Rechercher&meta= HTTP/1.1
Host: www.google.fr
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.9.0.1) Gecko/2008070208
Firefox/3.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: <script>alert('XSS')</script>
Cookie: SS=Q0=bG9s;
PREF=ID=d53b13b79d03a27c:TM=1216021699:LM=1216021699:S=E3oh8T7Jxha5G7PY;
NID=14=prJQ6exoKYllCGBc0TnP9enIcd2UA-DXWmdaRqWTJfMXTzUklR6-
LpdQRvBHb0ezOcNpEV86Fj67G5sbTRx-5fimqOWXDSAeXwMf3tcfs1Wil3HxfofzDIU2VRX6jNo_

0x221 XRS漏洞代码
存在漏洞的XRS.php代码:

<!DOCTYPE html PUBLIC “//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<head>
<meta httpequiv="ContentType" content="text/html; charset=utf8" />
<title>XRS</title>
</head>
<body>
<a href="XRS.php">Click</a>
<br />
<?php
$referer = (!empty($_SERVER['HTTP_REFERER'])) ? $_SERVER['HTTP_REFERER'] : 'Unspecified';
echo "$referer";
?>
</body>
</html>

0x222 安全的XRS.php代码:

<!DOCTYPE html PUBLIC “//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<head>
<meta httpequiv="ContentType" content="text/html; charset=utf8" />
<title>XRS</title>
</head>
<body>
<a href="XRS.php">Click</a>
<br />
<?php
$referer = (!empty($_SERVER['HTTP_REFERER'])) ? $_SERVER['HTTP_REFERER'] : 'Unspecified';
echo htmlspecialchars("$referer");
?>
</body>
</html>

0x230 HTTP Response Splitting

HTTP响应分裂(HTTP Response Splitting)可以HTTP1.1协议中利用,XSSER可利用HTTP Response Splitting在漏洞页面中执行跨站攻击,攻击者可利用它来实现多种攻击,比如:CRSF, Phishing, Iframe Phishing等。对于此项漏洞可通过带URL变量的HTTP请求来进行利用,因此在回复浏览者时可欺骗他,并插入可执行的HTML与JavaScript代码。
HTTP Response Splitting漏洞在以下情况可触发:
1.在不可信任来源点或频繁的HTTP请求中输入数据到WEB程序中;
2.在发往用户的HTTP 响应头数据中未过滤恶意字符。
为了成功利用漏洞,需要WEB程序允许输入CR(回车,也可%0d 或者\r)和LF(换行符,也可%0a或者\n)字符到HTTP头中。这此字符不仅攻击者控制发送的响应信息中剩余的header和body,而且可以另外创建可控制的响应信息。

HTTP Response Splitting例子:

%0d %0AContent-Type:%16text/html%0AContent-
Length:13%0A%0Ayou%20are%20xssed%20
%0d%0aContent-Type: text/html%0d%0a%0d%0aHTTP/1.1 200 OK%0d%0aLast-
Modified: Wed, 13 Jan 2006 12:44:23 GMT%0d%0aContent-Type:
text/html%0d%0a%0d%0a<html><font color=red>hey</font></html> HTTP/1.1
%0d%0aContent-Type: text/html%0d%0a%0d%0aHTTP/1.1 200 OK%0d%0aCache-
Control: no-cache%0d%0aContent-Type: text/html%0d%0a%0d%0a<html><font
color=red>hey</font></html> HTTP/1.1
%0d%0aContent-Type: text/html%0d%0a%0d%0aHTTP/1.1 200 OK%0d%0aPragma:
no-cache%0d%0aContent-Type: text/html%0d%0a%0d%0a<html><font
color=red>hey</font></html> HTTP/1.1
%0d%0AContent-Type: text/html;charset=UTF-7%0A%0A%2BADw-script%2BAD4-
alert('%58%79%4C%69%54%6F%4C%21');%2BADw-/script%2BAD4-

在下列截图中可见XSS测试失败,而HTTP Response splitting测试成功:

image7

0x300 Cross-site request forgery

0x 310 基础知识

跨站请求伪造(Cross-site request forgery),也被称成为“one click attack”或者session riding,通常缩写为CSRF或者XSRF,是一种由网站所信任的用户执行未授权命令的恶意攻击行为。尽管听起来像跨站脚本(XSS),但它与XSS 非常不同,并且攻击方式几乎相左。XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相 比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性。下面通过一存在漏洞的投票系统来分析,攻击者可发送一个恶意URL给受害者,受害者点击链接。比如:

http://victime.com/feedback.php?feed=<iframe
src="http://127.0.0.1/crsf/poll.php?id=3"></iframe>

Victime.com执行代码:

<iframe src="http://127.0.0.1/crsf/poll.php?id=3"></iframe>

其它例子 (by luca):

<form action="http://sc.gosugamers.net/admin/friends.php" method="post">
<input value="a_f" type="hidden" />
<input style="width: 150px" value="websecurity.ro" />
<input value="Add user to my friends list" type="submit" />
</form>
<script>
setTimeout("document.dude.submit()", 2000);
</script>

当已登陆 sc.gosugamers.net 的用户访问漏洞页面时,将自动添加 “websecurity.ro” 为其好友。CSRF非常危险,你甚至可以用它来转帐……因此,现在需要一份真实的漏洞代码,并提供修补的安全代码。

0x311漏洞源代码

image8

首先创建5个文件:
1.compteur
2.compteur
3.compteur
survey.php
poll.php
对于 1.compteur, 2.compteur and 3.compteur 仅需输入一个数字,这些文件即可包含投票数。

survey.php:

<!DOCTYPE html PUBLIC “//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<head>
<meta httpequiv="ContentType" content="text/html; charset=utf8" />
<title>Poll</title>
</head>
<body>
<table border="1" bgcolor="#999999">
<tr><td colspan="3">Who do you want to see as Master of the world?</td></tr>
<tr><td>Mr. Saiks</td><td>(Currently <?php readfile('1.compteur'); ?> have voted for
him)</td><td><a href="poll.php?id=1">[I support Mr saiks!]</a></td></tr>
<tr><td>Dr. Gordon Freeman</td><td>(Currently <?php readfile('2.compteur'); ?> have voted for
him)</td><td><a href="poll.php?id=2">[I support Gordon!]</a></td></tr>
<tr><td>Mr. Xylitol</td><td>(Currently <?php readfile('3.compteur'); ?> have voted for
him)</td><td><a href="poll.php?id=3">[I support Xylitol!]</a></td></tr>
</table>
</body>
</html>

poll.php :

<?php
if(isset($_GET['id']))
{
$monfichier = @fopen($_GET['id'] . '.compteur', 'r');
$nombreVote = @fgets($monfichier);
@fclose($monfichier);

$monfichier = fopen($_GET['id'] . '.compteur', 'w');
if($nombreVote == NULL or $nombreVote == 0) $nombreVote = 0;
$nombreVote++;
fputs($monfichier, $nombreVote);

fclose($monfichier);
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Vote Successfully taken</title>
</head>
<body>
Your vote was taken, click here to re-examine the classification: <a
href="survey.php">[RETURN]</a>
</body>
</html>

接下来,我们构造一存在漏洞的PHP文件,并利用以下代码来执行CSRF攻击:

<iframe src="http://127.0.0.1/crsf/poll.php?id=3"></iframe>

结果如下图:

image9

0x312 编写安全代码

如何使代码更为安全呢?
利用验证码来提交确认,防止IP过滤器滥用。首先需要创建8个文件:

1.compteur [No need to modify]
2.compteur [No need to modify]
3.compteur [No need to modify]
survey.php [No need to modify]
poll.php [Need to modify it]
captcha.fct.php
captcha.php
ipquionvote.txt

survey.php :

<?php session_start(); ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Voted sucessfully</title>
</head>
<body>
<?php
if(isset($_GET['id']) or isset($_POST['id'])) //we want to vote !
{
$lesip = file('ipquionvote.txt', FILE_IGNORE_NEW_LINES |
FILE_SKIP_EMPTY_LINES); //That load in a table the IPs which one already used
if(in_array($_SERVER['REMOTE_ADDR'], $lesip)) //IP already used ??!
{//if yes we quit
exit("You have already voted</body></html>");
}

if(isset($_POST['captcha'])) //if one already were on this page and, if we
have answered the captcha
{
if($_SESSION['captcha'] == $_POST['captcha'])
{
if($_POST['id'] != 1 and $_POST['id'] != 2 and $_POST['id']
!= 3) exit(); //Hey, wtfbbq this guy doesn't exist !
$monfichier = @fopen($_POST['id'] . '.compteur', 'r');
$nombreVote = @fgets($monfichier);
@fclose($monfichier);

$monfichier = fopen($_POST['id'] . '.compteur', 'w');
if($nombreVote == NULL or $nombreVote == 0)
$nombreVote = 0;
$nombreVote++;
fputs($monfichier, $nombreVote);

fclose($monfichier);

echo 'Your vote was taken, click here to re-examine the
classification: <a href="survey.php">[RETURN]</a>';

//we save IP
$monfichier = fopen('ipquionvote.txt', 'a');
fputs($monfichier, "\n" . $_SERVER['REMOTE_ADDR']);
fclose($monfichier);
}
else
echo "Incorrect Captcha n00b!";
}
else
{
echo 'You want vote for : ';
switch ($_GET['id'])
{

case 1: echo 'Mr. Saiks';

break;

}

case 2: echo 'Dr. Gordon Freeman'; break;
case 3: echo 'Mr. Xylitol'; break;
default: exit(); //WTFBBQ THIS GUY DOESN'T EXIST !

this captcha : <br />';

echo '<br />For verify if \you are not a bot, you are subjected to

echo "<img src='captcha.php' alt='' /><br />";
echo "<form action='poll.php' method='post'>word of

captcha:<br><input type='text' name='captcha'><br>";
echo "<input type='hidden' name='id' value='" .
htmlentities($_GET['id']) . "' />";
echo "<input type='submit' value='I am a 1337'></form>";
}
}
else // what the hell :o
{
echo 'Err0r, click here <a href="sondage.php">[RETURN]</a>';
}
?>
</body>
</html>

captcha.fct.php :

<?php
/**
* @name captcha
* Show an image with 5 characters generated by chance.
* I HAVE FOUND THIS CODE HERE:
* http://www.phpcs.com/codes/FUNCTION-CAPTCHA_44843.aspx
* @param Numeric iNbCaract : number of character
* @param Array aTextColor : Color code (RGB) separated by commas of the text
color.
* @param Array aBgColor : Color code (RGB) separated by commas of the
background color.
* @param Array aBorderColor : Color code (RGB)  separated by commas of the
border color.
*
* @return Image image maked
*/

function captcha ($iNbCaract,$aTextColor, $aBgColor, $aBorderColor ) {
//checking existance of the function
if ( !function_exists('imagecreatetruecolor') ){
return false;
}

//Parameters test
if (!is_int($iNbCaract))
$iNbCaract = 5;

if ( is_array($aTextColor) && count($aTextColor)=== 3 ){ // if it is a table
of 3
for($i=0; $i<3;$i++){
if ( $aTextColor[$i] < 0 || $aTextColor[$i] > 255 ){ // if it
does not lie between 0 and 255
$aTextColor[$i] = 0; // one puts at zero = white
}
}
}else { // that not a table of 3
$aTextColor = array(0,0,0);
}

if ( is_array($aBgColor) && count($aBgColor)=== 3 ){ // if it is a table of
3
for($i=0; $i<3;$i++){
if ( $aBgColor[$i] < 0 || $aBgColor[$i] > 255 ){ // if it does
not lie between 0 and 255
$aBgColor[$i] = 255; // one puts at 255 = black
}
}
}else { // that not a table of 3
$aBgColor = array(255,255,255);
}

if ( is_array($aBorderColor) && count($aBorderColor)=== 3 ){ // if it is a
table of 3
for($i=0; $i<3;$i++){
if ( $aBorderColor[$i] < 0 || $aBorderColor[$i] > 255 ){ //
if it does not lie between 0 and 255
$aBorderColor[$i] = 0; // one puts at zero = white
}
}
}else { // that not a table of 3
$aBorderColor = array(0,0,0);
}
//End of parameters test

//variables
$iWidth = $iNbCaract * 20;
$iHeight = 27;
$iFontSize = 5; // de 1 à 5

?>

$sRep = "./captcha/";
//end of variables

//number
$aCaractere = array();
for ($i=0; $i<=9; $i++)
$aCaractere[]  = $i;
//capital letter
for ($i=65; $i<=90; $i++)
$aCaractere[] = chr($i);
//tiny letter
for ($i=97; $i<=122; $i++)
$aCaractere[] = chr($i);

//random text
$sTexte = "";
$sTexteImg = "";
$iLenCaractere = sizeof($aCaractere)-1;
for ($cpt=0;$cpt<$iNbCaract;$cpt++) {
$iNum_caract=rand(0, $iLenCaractere );
$sTexte .= $aCaractere[$iNum_caract];
$sTexteImg .= $aCaractere[$iNum_caract] . " ";
}

//saving the text in the session
$_SESSION['captcha'] = $sTexte;

//creation of an image
$rImage = imagecreatetruecolor ($iWidth, $iHeight);

//text colour
if (count($aTextColor) === 3)
$cText_color = imagecolorallocate ($rImage, $aTextColor[0],
$aTextColor[1], $aTextColor[2]);

// background colour
if (count($aBgColor) === 3)
$cBg_color = imagecolorallocate ($rImage, $aBgColor[0],
$aBgColor[1], $aBgColor[2]);

// background colour
if (count($aBorderColor) === 3)
$cBorder_color = imagecolorallocate ($rImage, $aBorderColor[0],
$aBorderColor[1], $aBorderColor[2]);

// we draw border
imagefilledrectangle($rImage, 0, 0, $iWidth, $iHeight,$cBorder_color);
imagefilledrectangle($rImage, 1, 1, $iWidth-2, $iHeight-2,$cBg_color);

// we write the text
imagestring ($rImage, $iFontSize, 10, 5,  $sTexteImg, $cText_color);

// we make the image scrambled: fuzzy
imagefilter($rImage, IMG_FILTER_SMOOTH, 2); //IMG_FILTER_EMBOSS,
IMG_FILTER_SMOOTH

// Rotation
$rImage = imagerotate($rImage, 5, $cBg_color);

return imagepng($rImage);

imagedestroy ($rImage);
}

captcha.php :

<?php
include ("captcha.fct.php");
header('Content-type: image/png');
header('Last-Modified: ' . gmdate("D, d M Y H:i:s") . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
session_start();
echo captcha(5,array(0,0,0),array(255,255,255),array(0,250,125));
?>

‘ipquionvote.txt’包含有投票者IP的邮件列表。

现在测试一下这个安全的投票系统:

image10

0x400 其它学习资料
http://www.owasp.org/index.php/ (Open Web Application Security Project)
http://www.agents-codeurz.com/ (if you have a code problem…)
http://www.gnucitizen.org/xssdb/application.htm (Attack Database)
http://www.xssed.com (Mirror Archive of Vulnerable Websites)
http://ha.ckers.org/xss.html (XSS Cheat sheet Database)
http://php.net/manual/en/function.htmlentities.php
http://php.net/manual/en/function.htmlspecialchars.php
http://php.net/manual/en/function.strip-tags.php

相关日志

抢楼还有机会... 抢座Rss 2.0或者 Trackback

发表评论