ctf中常见php漏洞
<h1 id="php特性漏洞">PHP特性漏洞</h1><h2 id="一intval函数---获取变量的整数值">一.intval()函数---获取变量的整数值</h2>
<h3 style="color: rgba(255, 0, 0, 1)">函数说明</h3>
<p>int <strong>intval</strong>(mixed <code>$var</code> [, int <code>$base</code> = 10] ) :通过使用指定的进制 <code>base</code> 转换(默认是十进制),返回变量 <code>var</code> 的 integer 数值。<strong>intval()</strong> 不能用于 object,否则会产生<strong><code>E_NOTICE</code></strong> 错误并返回 1。</p>
<p>如果base是0,则通过检测var的格式来决定使用的进制:</p>
<ol>
<li>如果字符串包括'0x'或者('0X')的前缀,使用16进制(hex);</li>
<li>如果字符串以 "0" 开始,使用 8 进制(octal);</li>
<li>否则,使用10进制(decimal).</li>
</ol>
<p>返回值 : 成功时返回var的integer值,失败时返回0。空的array返回0,非空的array返回1。</p>
<p>最大的值取决于操作系统。 32 位系统最大带符号的 integer 范围是 -2147483648 到 2147483647。举例,在这样的系统上, <em>intval('1000000000000')</em> 会返回2147483647。64 位系统上,最大带符号的 integer 值是9223372036854775807</p>
<h3 style="color: rgba(255, 0, 0, 1)">绕过思路总结</h3>
<ol>
<li>
<p>当某个数字被过滤时,可以使用它的 8进制/16进制来绕过;比如过滤10,就用012(八进制)或0xA(十六进制)。</p>
</li>
<li>
<p>对于弱比较(a==b),可以给a、b两个参数传入空数组,使弱比较为true。</p>
</li>
<li>
<p>当某个数字被过滤时,可以给它增加小数位来绕过;比如过滤3,就用3.1(转换小数类型时,只返回个位数,不遵循四舍五入的原则)</p>
</li>
<li>
<p>当某个数字被过滤时,可以给它拼接字符串来绕过;比如过滤3,就用3ab。(GET请求的参数会自动拼接单引号)</p>
</li>
<li>
<p>当某个数字被过滤时,可以两次取反来绕过;比如过滤10,就用~~10。</p>
</li>
<li>
<p>当某个数字被过滤时,可以使用算数运算符绕过;比如过滤10,就用 5+5 或 2*5。</p>
</li>
</ol>
<p>7.科学计数法:经过本地测试,在php版本小于等于7.0.9时,intval("1e2")的结果是1,即转换字符串时,遇到字母停止,但是intval("1e2"+1)的结果却是101,这种特性可以绕过诸如intval($num)>2020&&intval($num)>2021。但是当php版本>7.0.9时,这种方法就失效了,因为intval("1e2")和intval(1e2)的值均为100。</p>
<p>8.intval()函数允许正数前面加空格和+,比如intval("+244")和intval(" 244"),其值均为244。(<strong>此方法可用于绕过stripos函数对传入参数某个位置的过滤</strong>)</p>
<p>根据这个特性,还可以延伸到类似intval($num,0)===4476(适用于任何php版本)和intval($num)===4476(php -v<=7.0.9)的区别:<br>
<img src="https://images.cnblogs.com/cnblogs_com/blogs/794456/galleries/2354675/o_231029145727_image.png" alt="image-20231029225203218" loading="lazy"><br>
<img src="https://images.cnblogs.com/cnblogs_com/blogs/794456/galleries/2354675/o_231029145741_image.png" alt="image-20231029225440571" loading="lazy"></p>
<h2 id="二is_numeric函数---获取变检测变量是否为数字或数字字符串">二.is_numeric()函数---获取变检测变量是否为数字或数字字符串</h2>
<h3 style="color: rgba(255, 0, 0, 1)">函数说明</h3>
<p>如果var是数字或数字字符串则返回 <strong><code>TRUE</code></strong>,否则返回 <strong><code>FALSE</code></strong>。</p>
<h3 style="color: rgba(255, 0, 0, 1)">绕过思路总结</h3>
<p>1.加字母绕过</p>
<pre><code class="language-php"> if(!is_numeric($_GET['key5']) && $_GET['key5'] > 2023){
$flag4 = True;
}else{
die("nope,this is level 4");
}
</code></pre>
<p>这时,就可以通过传入key5=2024a(不是纯数字字符串)绕过(一个大于2023的数字加上任意字母)</p>
<p>2.16进制绕过</p>
<p><img src="https://images.cnblogs.com/cnblogs_com/blogs/794456/galleries/2354675/o_231029093527_image.png" alt="image-20231029141635633" loading="lazy"></p>
<p>php版本大于等于7.0.9时:当我们传入0x2时,var_dump(is_numeric('0x2'));会返回bool(false)</p>
<p>但是当php版本小于7时,则可以利用,例如:</p>
<pre><code class="language-php"><?php
highlight_file(__FILE__);
$a = $_GET['a'];
if(is_numeric($a)){
echo 'flag';
}
?>
</code></pre>
<p>传入a=0x1可以绕过,如图:</p>
<p><img src="https://images.cnblogs.com/cnblogs_com/blogs/794456/galleries/2354675/o_231029093600_image.png" alt="image-20231029143941820" loading="lazy"></p>
<p>3.科学计数法(is_numeric()配合(int)强制类型转换绕过)(php -v<=7.0.9)</p>
<p>例如:</p>
<pre><code class="language-php"><?php
show_source(__FILE__);
$flag = "xxxx";
if(isset($_GET['time'])){
if(!is_numeric($_GET['time'])){
echo 'The time must be number.';
}else if($_GET['time'] < 60 * 60 * 24 * 30 * 2){
echo 'This time is too short.';
}else if($_GET['time'] > 60 * 60 * 24 * 30 * 3){
echo 'This time is too long.';
}else{
sleep((int)$_GET['time']);
echo $flag;
}
echo '<hr>';
}
?>
</code></pre>
<p>由题目可知:5184000<time<7776000,此时,可以利用:(int),不能正确转换的类型有十六进制型字符串、科学计数法型字符串;而<br>
is_numeric()支持普通数字型字符串、科学记数法型字符串、部分支持十六进制0x型字符串。构造payload如下:</p>
<pre><code class="language-php">time=7e6
</code></pre>
<h2 id="三strcmp函数---比较字符串大小php--v53">三.strcmp()函数---比较字符串大小(php -v<5.3)</h2>
<h3 style="color: rgba(255, 0, 0, 1)">函数说明</h3>
<p>int<strong>strcmp</strong>( string <code>$str1</code> , string <code>$str2</code> )</p>
<p>返回值:如果 <code>str1</code> 小于<code>str2</code> 返回 < 0; 如果 <code>str1</code>大于 <code>str2</code> 返回 > 0;如果两者相等,返回 0。</p>
<h3 style="color: rgba(255, 0, 0, 1)">绕过思路总结</h3>
<p>1.弱类型比较</p>
<pre><code class="language-php"><?php
error_reporting(0);
//关闭错误提示
if (isset($_GET['a'])) {
//判断是否以get形式为a赋值
if (strcmp($_GET['a'], $flag) == 0)
//比较a变量和flag的字符,再将结果与0【false】比较
echo 'flag{strcmp_pass}';
else
print 'you are failure';
}
?>
</code></pre>
<p>由于strcmp只会处理字符串,如果给个数组的话呢,就会返回NULL。而NULL==0,则可以成功得到flag。</p>
<h2 id="四hash比较缺陷---md5sha1">四.hash比较缺陷---md5,sha1</h2>
<h3 id="一md5弱类型比较md5amd5b">一.md5弱类型比较(md5($a)==md5($b))</h3>
<p>1.数组绕过:由于md5不能加密数组,在加密数组的时候会返回NULL,所以我们可以传入两个数组。数组绕过适用于源码中没有判断类型和内容,如果题目中加入了过滤函数,便不能使用了。</p>
<p>2.科学计数法绕过:可以传入两个md5加密后是0e开头的字符串,需要注意的地方是,这个以0e开头的字符串只能是纯数字,这样php在进行科学计算法的时候才会将它转化为0。可以自己写脚本:</p>
<pre><code class="language-python">import hashlib
for i in range(1,10**9):
i=str(i)
md=hashlib.md5(i.encode()).hexdigest()
if(md[:2]=="0e" and md.isdigit()):
print("num={},md5={}".format(i,md))
</code></pre>
<p>要注意的是,int型没有encode属性,所以务必加上i=str(i)。其次,该脚本只能跑出数字型的答案,字符串的暂时无法跑出。</p>
<p>常见字符串如下:</p>
<p>纯数字类:</p>
<p>240610708 0e462097431906509019562988736854</p>
<p>314282422 0e990995504821699494520356953734</p>
<p>571579406 0e972379832854295224118025748221</p>
<p>903251147 0e174510503823932942361353209384</p>
<p>1110242161 0e435874558488625891324861198103</p>
<p>1320830526 0e912095958985483346995414060832</p>
<p>1586264293 0e622743671155995737639662718498</p>
<p>2302756269 0e250566888497473798724426794462</p>
<p>2427435592 0e067696952328669732475498472343</p>
<p>2653531602 0e877487522341544758028810610885</p>
<p>3293867441 0e471001201303602543921144570260</p>
<p>3295421201 0e703870333002232681239618856220</p>
<p>3465814713 0e258631645650999664521705537122</p>
<p>3524854780 0e507419062489887827087815735195</p>
<p>3908336290 0e807624498959190415881248245271</p>
<p>4011627063 0e485805687034439905938362701775</p>
<p>4775635065 0e998212089946640967599450361168</p>
<p>4790555361 0e643442214660994430134492464512</p>
<p>5432453531 0e512318699085881630861890526097</p>
<p>5579679820 0e877622011730221803461740184915</p>
<p>5585393579 0e664357355382305805992765337023</p>
<p>6376552501 0e165886706997482187870215578015</p>
<p>7124129977 0e500007361044747804682122060876</p>
<p>7197546197 0e915188576072469101457315675502</p>
<p>7656486157 0e451569119711843337267091732412</p>
<p>大写字母类:</p>
<p>QLTHNDT 0e405967825401955372549139051580</p>
<p>QNKCDZO 0e830400451993494058024219903391</p>
<p>EEIZDOI 0e782601363539291779881938479162</p>
<p>TUFEPMC 0e839407194569345277863905212547</p>
<p>UTIPEZQ 0e382098788231234954670291303879</p>
<p>UYXFLOI 0e552539585246568817348686838809</p>
<p>IHKFRNS 0e256160682445802696926137988570</p>
<p>PJNPDWY 0e291529052894702774557631701704</p>
<p>ABJIHVY 0e755264355178451322893275696586</p>
<p>DQWRASX 0e742373665639232907775599582643</p>
<p>DYAXWCA 0e424759758842488633464374063001</p>
<p>GEGHBXL 0e248776895502908863709684713578</p>
<p>GGHMVOE 0e362766013028313274586933780773</p>
<p>GZECLQZ 0e537612333747236407713628225676</p>
<p>NWWKITQ 0e763082070976038347657360817689</p>
<p>NOOPCJF 0e818888003657176127862245791911</p>
<p>MAUXXQC 0e478478466848439040434801845361</p>
<p>MMHUWUV 0e701732711630150438129209816536</p>
<p>byGcY</p>
<p>0e591948146966052067035298880982</p>
<p>QNKCDZO</p>
<p>0e830400451993494058024219903391</p>
<p>s878926199a</p>
<p>0e545993274517709034328855841020</p>
<p>s155964671a</p>
<p>0e342768416822451524974117254469</p>
<p>s214587387a</p>
<p>0e848240448830537924465865611904</p>
<p>s214587387a</p>
<p>0e848240448830537924465865611904</p>
<p>s878926199a</p>
<p>0e545993274517709034328855841020</p>
<p>s1091221200a</p>
<p>0e940624217856561557816327384675</p>
<p>s1885207154a</p>
<p>0e509367213418206700842008763514</p>
<p>3.MD5和双MD5以后都是0e开头的:(但是后面不是$\color{#FF3030}{纯数字}$,不太好用)</p>
<p>CbDLytmyGm2xQyaLNhWn</p>
<p>770hQgrBOjrcqftrlaZk</p>
<p>7r4lGXCH2Ksu2JNT3BYM</p>
<p>4.一个数自己和MD5值均以0e开头:</p>
<p>num=0e215962017,md5=0e291242476940776845150308577824 脚本如下:</p>
<pre><code class="language-python">import hashlib
for i in range(1,10**40):
i='0e'+str(i)
md=hashlib.md5(i.encode()).hexdigest()
if md[:2]=="0e" and md.isdigit():
print('num={},md5={}'.format(i,md))
break
</code></pre>
<p>其中,第5行还可以写成md=hashlib.new('md5',i.encode()).hexdigest();之所以要编码,是因为ython3默认编码是unicode,而不是字节码bytes。hash是要基于bytes的,因此需要encode()函数编码。因为需要进行下标访问,而刚才的返回值又是hash类型,所以应该使用函数将md变成一个字符串。一开始的时候,我还在想为什么只能用hexdigest()函数使其成为16进制字符串呢,后来再一看,哦,原来是需要出现"0e",那必然不能用digest()函数变成2进制了呀。当然了,又出现了一个小小的疑问,isdigit()和isnumeric(),isdecimal()的区别是什么呢?查资料发现:</p>
<p>isdecimal:是否为十进制数字符,包括Unicode数字、双字节全角数字,不包括罗马数字、汉字数字、小数;</p>
<p>isdigit:是否为数字字符,包括Unicode数字,单字节数字,双字节全角数字,不包括汉字数字,罗马数字、小数</p>
<p>isnumeric:是否所有字符均为数值字符,包括Unicode数字、双字节全角数字、罗马数字、汉字数字,不包括小数。</p>
<p><strong>以下值在sha1加密后以0E开头:</strong></p>
<ul>
<li>aaroZmOk</li>
<li>aaK1STfY</li>
<li>aaO8zKZF</li>
<li>aa3OFF9m</li>
<li>0e1290633704</li>
<li>10932435112</li>
</ul>
<h3 id="二md5强类型比较md5amd5b">二.md5强类型比较(md5($a)===md5($b))</h3>
<p>方法一:数组绕过</p>
<p>因为是强类型比较,用0e开头的字符串是没办法绕过的了,但是PHP自身的特性使得可以提交一个数组而md5函数传入数组的返回值都是NULL,这样就可以绕过强类型比较了。</p>
<p>方法二:MD5强碰撞绕过</p>
<p>具体原理很复杂,但是实现方法不难,是通过<strong>fastcoll_v1.0.0.5.exe.zip这个工具,创造两个txt文件,然后进行二进制md5加密,可以获得两个数值和类型都相等的字符串。由于加密后存在不可见字符,因此需要进行URL编码,下面给出两组碰撞结果:</strong></p>
<pre><code class="language-php+HTML">p1=1%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%A3njn%FD%1A%CB%3A%29Wr%02En%CE%89%9A%E3%8EF%F1%BE%E9%EE3%0E%82%2A%95%23%0D%FA%CE%1C%F2%C4P%C2%B7s%0F%C8t%F28%FAU%AD%2C%EB%1D%D8%D2%00%8C%3B%FCN%C9b4%DB%AC%17%A8%BF%3Fh%84i%F4%1E%B5Q%7B%FC%B9RuJ%60%B4%0D7%F9%F9%00%1E%C1%1B%16%C9M%2A%7D%B2%BBoW%02%7D%8F%7F%C0qT%D0%CF%3A%9DFH%F1%25%AC%DF%FA%C4G%27uW%CFNB%E7%EF%B0
p2=1%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%A3njn%FD%1A%CB%3A%29Wr%02En%CE%89%9A%E3%8E%C6%F1%BE%E9%EE3%0E%82%2A%95%23%0D%FA%CE%1C%F2%C4P%C2%B7s%0F%C8t%F28zV%AD%2C%EB%1D%D8%D2%00%8C%3B%FCN%C9%E24%DB%AC%17%A8%BF%3Fh%84i%F4%1E%B5Q%7B%FC%B9RuJ%60%B4%0D%B7%F9%F9%00%1E%C1%1B%16%C9M%2A%7D%B2%BBoW%02%7D%8F%7F%C0qT%D0%CF%3A%1DFH%F1%25%AC%DF%FA%C4G%27uW%CF%CEB%E7%EF%B0
</code></pre>
<pre><code class="language-php+">p1=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%00%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1U%5D%83%60%FB_%07%FE%A2
p2=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%02%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1%D5%5D%83%60%FB_%07%FE%A2
</code></pre>
<p>sha1碰撞绕过----<strong>两个SHA1值相同而不一样(SHA256的值不同)的pdf文件</strong>__</p>
<pre><code class="language-php">a=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01%7FF%DC%93%A6%B6%7E%01%3B%02%9A%AA%1D%B2V%0BE%CAg%D6%88%C7%F8K%8CLy%1F%E0%2B%3D%F6%14%F8m%B1i%09%01%C5kE%C1S%0A%FE%DF%B7%608%E9rr/%E7%ADr%8F%0EI%04%E0F%C20W%0F%E9%D4%13%98%AB%E1.%F5%BC%94%2B%E35B%A4%80-%98%B5%D7%0F%2A3.%C3%7F%AC5%14%E7M%DC%0F%2C%C1%A8t%CD%0Cx0Z%21Vda0%97%89%60k%D0%BF%3F%98%CD%A8%04F%29%A1
b=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01sF%DC%91f%B6%7E%11%8F%02%9A%B6%21%B2V%0F%F9%CAg%CC%A8%C7%F8%5B%A8Ly%03%0C%2B%3D%E2%18%F8m%B3%A9%09%01%D5%DFE%C1O%26%FE%DF%B3%DC8%E9j%C2/%E7%BDr%8F%0EE%BC%E0F%D2%3CW%0F%EB%14%13%98%BBU.%F5%A0%A8%2B%E31%FE%A4%807%B8%B5%D7%1F%0E3.%DF%93%AC5%00%EBM%DC%0D%EC%C1%A8dy%0Cx%2Cv%21V%60%DD0%97%91%D0k%D0%AF%3F%98%CD%A4%BCF%29%B1
</code></pre>
<h2 id="五json绕过">五.json绕过</h2>
<p>先了解一下什么是JSON:</p>
<p>JSON: <strong>J</strong>ava<strong>S</strong>cript <strong>O</strong>bject <strong>N</strong>otation(JavaScript 对象表示法)</p>
<p>JSON 是存储和交换文本信息的语法,类似 XML。</p>
<p>JSON 比 XML 更小、更快,更易解析。</p>
<p>JSON 易于人阅读和编写。</p>
<p>C、Python、C++、Java、PHP、Go等编程语言都支持 JSON。</p>
<p>JSON语法:JSON 语法是 JavaScript 对象表示语法的子集。</p>
<ul>
<li>数据在<strong>名称/值</strong>对中</li>
<li>数据由逗号 <strong>,</strong> 分隔</li>
<li>使用斜杆 *<em>*</em> 来转义字符</li>
<li>大括号 <strong>{}</strong> 保存对象</li>
<li>中括号 <strong>[]</strong> 保存数组,数组可以包含多个对象</li>
</ul>
<pre><code class="language-php"><?php
if (isset($_POST['message'])) {
$message = json_decode($_POST['message']);
$key ="*********";
if ($message->key == $key) {
echo "flag";
}
else {
echo "fail";
}
}
else{
echo "~~~~";
}
?>
</code></pre>
<p>输入一个json类型的字符串,json_decode函数解成一个数组,判断数组中key的值是否等于 $key的值,但是$key的值我们不知道,<strong>但是可以利用0==”admin”这种形式绕过</strong>.</p>
<p>payload:</p>
<pre><code class="language-php">message={"key":0}
</code></pre>
<h2 id="六parse_str变量覆盖">六.parse_str()变量覆盖</h2>
<h3 style="color: rgba(255, 0, 0, 1)">函数说明</h3>
<p>parse_str — 将字符串解析成多个变量:void <strong>parse_str</strong> ( string <code>$encoded_string</code> [, array <code>&$result</code>] )</p>
<p><strong>如果设置了第二个变量 result,变量将会以数组元素的形式存入到这个数组,作为替代。</strong></p>
<p>example:</p>
<pre><code class="language-php"><?php
parse_str($"My Value=Something");
echo $My_Value; // Something
parse_str($"My Value=Something", $output);
echo $output['My_Value']; // Something
?>
</code></pre>
<p>解析字符串并注册成变量,在注册变量之前不会验证当前变量是否存在,所以直接覆盖掉已有变量,当parse_str()函数的参数值可以被用户控制时,则存在变量覆盖漏洞。</p>
<pre><code class="language-php"><?php
error_reporting(0);
if(empty($_GET['id'])) {
show_source(__FILE__);
die();
} else {
$a = "www.xxx.com";
$id = $_GET['id'];
@parse_str($id);
if ($a != 'QNKCDZO' && md5($a) == md5('QNKCDZO')) {
echo 'flag';
} else {
exit('so easy!');
}
}
?>
</code></pre>
<p>由上述描述,易得payload:</p>
<pre><code class="language-php">?id=a=s878926199a (s878926199a被md5加密后,以0e开头)
</code></pre>
<h2 id="七extract函数">七.extract()函数</h2>
<pre><code class="language-html">extract()函数从数组中将变量到导入到当前符号表
该函数使用数组键名作为变量名,使用数组键值作为变量值。针对数组中的每个元素,将在当前符号表创建对应的一个变量
</code></pre>
<pre><code class="language-php"><?php
error_reporting(0);
echo "同目录下有个test.txt,猜猜里面写了什么,猜对了奖励你flag哦~<br>";
$text='test.txt';
extract($_GET);
if(isset($a)){
$content=trim(file_get_contents($text));
if($a==$content){
echo "<br>骗你的,根本没有test.txt哈哈<br>flag{Y0u_G0t_1t!}";
}
else{
echo "Not like that, think again";
}
}
</code></pre>
<p>由于我们并不知道test.txt的内容,因此我们只需要利用extract函数将$text的值覆盖为空,再把$a赋值为空即可即可</p>
<h2 id="八in_array函数">八.in_array()函数</h2>
<p>用途:用来判断一个值是否在某一个数组列表里面</p>
<p>缺陷:当第三个参数不设置为true时(即严格模式),存在自动类型转换(<strong>弱比较</strong>) ,当输入数字1后再紧跟其他字符串能够Bypass检测数组的功能</p>
<p>例题:</p>
<pre><code class="language-php"><?php
$id = $_GET['id'];
if (in_array($id, array(1,2,3,4,5,6,7,8,9,0))) {
$sql = "Select a From users Where Id='".$id."'";
echo $sql;
} else {
echo "No...";
}
?>
</code></pre>
<pre><code class="language-html">payload:1' union select * from users#
</code></pre>
<p><img src="https://images.cnblogs.com/cnblogs_com/blogs/794456/galleries/2354675/o_231029093639_image.png" alt="image-20231029170653524" loading="lazy"></p>
<h2 id="九ereg函数和eregi函数php4php5">九.ereg()函数和eregi()函数(php4,php5)</h2>
<p>用于正则匹配,两者的区别在于是否区分大小写 使用指定的模式搜索一个字符串中指定的字符串,如果匹配成功则返回true,否则返回false</p>
<p>该函数可被<code>%00</code>截断来Bypass 传入数组之后,ereg是返回NULL</p>
<pre><code class="language-php"><?php
$passwd = $_GET['passwd'];
if (@ereg("^+$", $passwd)) {
$sql = "Select username From users Where password='".$passwd."'";
echo $sql;
} else {
echo "No...";
}
?>
</code></pre>
<p><img src="https://images.cnblogs.com/cnblogs_com/blogs/794456/galleries/2354675/o_231029093655_image.png" alt="image-20231029171105770" loading="lazy"></p>
<h2 id="十导致变量覆盖">十.$$导致变量覆盖</h2>
<p>$$导致变量覆盖的问题一般出现在foreach遍历数组当中,使用foreach来遍历数组中的值,然后再将获取到的数组键名作为变量名,数组中的键值作为变量的值。因此就产生了变量覆盖漏洞。</p>
<pre><code class="language-php"><?php
error_reporting(0);
$name='Testing';
foreach ($_GET as $key => $value)
$$key = $value;
var_dump($key);
var_dump($value);
var_dump($$key);
echo $name;
</code></pre>
<p><img src="https://images.cnblogs.com/cnblogs_com/blogs/794456/galleries/2354675/o_231029093714_image.png" alt="image-20231029171904688" loading="lazy"></p>
<p>此时,当我们传入name=dtwin时,$name的值被覆盖为dtwin</p>
<h2 id="总结">总结</h2>
<p>以上十个漏洞是php中较为常见的,另外的漏洞比如<code>import_request_variables()</code>变量覆盖,<code>register_globals</code>全局变量覆盖,这些都在php5以后就废除了,ctf和实战中都很难再遇到,故不在此列出。</p><br><br>
来源:https://www.cnblogs.com/dtwin/p/17796132.html
頁:
[1]