这里刚入门ctf小白一枚 如果有什么地方说错了或者有待改进的地方欢迎指出喔(-w-)
打开题目我们看到题目让给我们输入口令:zhimakaimen
可是输入了之后依然报错呢F12看一下网页源代码
在maxlength处限制了我们输入字符的长度 我们将它改成11
重新输入 “zhimakaimen” 获取flag
题目中我们已经给出了源码
$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";}
1.变量md51的值是字符串“QNKCDZO"经MD5加密后的值
2.变量a以get方式传入
3.md52的值是变量a经md5加密后的密文
4.我们又看到第二个if判断:当a不等于’QNKCDZO’但是a加密后的值要和’QNKCDZO’加密后的值一样 我们才能拿到flag
这里就涉及到一个 php弱类型的题目
参考资料:php 弱类型总结
== 在进行比较的时候,会先将字符串类型转化成相同再比较
如果比较一个数字和字符串或者比较涉及到数字内容的字符串,则字符串会被转换成数值并且比较按照数值来进行
我们利用在线加密 可以看到字符串经加密是0e开头的(想到科学计数法) 也就是说它在比较的时候会被转换成0
也就是说只要我们令变量a的值是一个经md5加密后的密文是0e开头的就好了(这样的值在上文给出的链接里面有很多)
题目中已经给出提示 依旧是弱类型的题目
点开就可以看到页面的源码
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.';
}
利用fastcoll生成!
1)新建一个md5.txt文件 写入任意内容
2)在cmd中输入指令:fastcoll_v1.0.0.5.exe -p md5.txt -o md51.txt md52.txt
3)散列值生成中
4)
由于生成的是乱码 我们利用python:
from urllib import parse
result = parse.quote(open('md51.txt','rb').read())
print(result)
result2 = parse.quote(open('md52.txt','rb').read())
print(result2)
显然这是一道图片隐写题解法1:利用winhex查看文件被隐藏起来的数据
winhex下载链接
拉到最下面就可以看到我们的flag啦
解法2:直接用记事本打开题目的图片
拉到最下面也能看到flag
F12查看页面源码 发现可疑路径 SO.html
访问 在网页源码看到可疑路径S0.html
接着访问 看到第三个可疑路径 SO.htm
接着访问 然后看到第四个可疑路径 S0.htm
访问 然后看到可以路径404.html
接着访问该链接 然后查看页面源码 就可以看到flag
打开题目看到是一串乱码 将页面保存到桌面 打开看看
可以看到是一串颜文字 我们用Firefox浏览器的控制台解码得到flag
题目给出一个类似解密器的代码 //从decode看出的(逃
function CLsI($ZzvSWE) {
$ZzvSWE = gzinflate(base64_decode($ZzvSWE));
//base64解密
for ($i = 0; $i < strlen($ZzvSWE); $i++) {
$ZzvSWE[$i] = chr(ord($ZzvSWE[$i]) - 1);
//遍历每一个字符输出它的ascii码减一的值
}
return $ZzvSWE;//只要我们将return改成echo就输出了我们想要的数据
}
eval(CLsI("+7DnQGFmYVZ+eoGmlg0fd3puUoZ1fkppek1GdVZhQnJSSZq5aUImGNQBAA=="));//定义一个字符串并返回它经过解密的值
?>
将代码改成如下,并将其存到phpstudy的WWW目录下
function CLsI($ZzvSWE) {
$ZzvSWE = gzinflate(base64_decode($ZzvSWE));
for ($i = 0; $i < strlen($ZzvSWE); $i++) {
$ZzvSWE[$i] = chr(ord($ZzvSWE[$i]) - 1);
}
echo $ZzvSWE;
}
CLsI("+7DnQGFmYVZ+eoGmlg0fd3puUoZ1fkppek1GdVZhQnJSSZq5aUImGNQBAA==");
?>
打开phpstudy
访问http://127.0.0.1/phpdecode.php 拿到flag
由题目给出的提示可知这是一道利用LFI文件包含漏洞的问题(也可以从URL的“file=”看出)。
根据题目的意思来到了这个界面
首先我们尝试基本的LFI攻击:使用(…/)或简单地(/)从目录中直接读取文件的内容
似乎看不出什么(挠头
看了一个师傅的博客 博客链接
想到可以利用php伪协议查看经base64加密过后的index.php的源码
http://4.chinalover.sinaapp.com/web7/index.php?file=php://filter/read=convert.base64-encode/resource=index.php
顺着题目的意思来到了这个页面
我们可以看到这时候是跳转到了no_key_is_here_forever.php
但是我们回到原来的页面查看源码 发现它本应该跳转到./search_key.php
利用BP抓包
在HTTP history里面找到访问的记录 获取flag
ps:还有个题目叫“单身一百年也没用“跟这道题做法相同 就不记录啦~
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]);//以get方式传入变量id并对其取整
$query = @mysql_fetch_array(mysql_query("select content from ctf2 where id='$id'"));//sql查询语句
if ($_GET[id]==1024) {
echo "no! try again
";//限制id不可以等于整数的1024
}
else{
echo($query[content]);//我们想要查询的是id=1024里面的内容
}
}
?>
这里给了一个提示:sql.php 说明我们要先进去这个文件
这里我们要说到intval函数有一个特点:1024.0会被认为是整数1024,所以我们只要get一个id变量等于1024.1即可
题目直接给了源码
if (isset ($_GET['nctf'])) {
if (@ereg ("^[1-9]+$", $_GET['nctf']) === FALSE)
echo '必须输入数字才行';//限制nctf必须由数字组成
else if (strpos ($_GET['nctf'], '#biubiubiu') !== FALSE)
die('Flag: '.$flag);//限制nctf中必须有#biubiubiu
else
echo '骚年,继续努力吧啊~';
}
利用/x00截断正则匹配 获取flag
payload:
?nctf=1%00%23biubiubiu
截取源码的关键部分进行分析
if ($_SERVER["REQUEST_METHOD"] == "POST") { ?>
extract($_POST);
if ($pass == $thepassword_123) { ?>
<div class="alert alert-success">
<code> echo $theflag; ?></code>
</div>
} ?>
} ?>
这里有一个extract() 函数 将post进去的键值对定义为变量,但是如果原来就存在同名的变量,这个函数会将其覆盖。 也就是说,原来有pass变量和thepassword_123变量并且这两个变量一定是不相等的,新post进去的会将其原来的覆盖掉。
所以我们post两个相等的值 就获取了flag
题目提示我们要本地访问,也就是我们的ip地址要是127.0.0.1
参考资料:CTF中伪造IP的几种方法
题目提示我们要上传文件 我们上传一个一句话木马看看
提示我们要上传的文件类型
上传一张图看看
又说让咱们传php文件(挠头
请教了npy。。他告诉我用00截断试试。。
1)先将上传的文件名改成xx.php.jpg(我这里直接改成muma.php.jpg)
2)上传 抓包
3)在uploads文件夹下添加我们上传的文件名
4)去Hex查看,找到uploads目录下的我们上传的文件名,将.jpg的"."对应的十六进制的值改成00 返回Raw查看 就可以看到原来的.变成了一个小方框,表示我们截断成功,也就是说我们上传的文件可以被识别为.jpg文件但是上传之后是一个.php文件。
5)放包 获取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!";
}
?>
大概的意思就是当post进的pass和原先设定的pass1相等输出flag
这里考察的就是一个strcmp函数的漏洞:在5.3版本前,如果传入的不是字符串(比如传入数组),那么会报错,并且return 0,在本题中就输出flag了
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';
?>
1.ord()函数:它以一个字符(长度为1的字符串)作为参数,返回对应的 ASCII 数值。
2.for循环判断我们传入的变量key是否由数字组成,如果是的话 返回false,不是的话 令参数等于54975581388并返回1,为了绕过这个for循环我们将54975581388转换成十六进制发现是ccccccccc,刚好可以绕过for循环。
题目要求我们重置的账号是:admin
发现账号名改不了 但是url里面显示了一串bas64加密后的密文
解密之后发现刚好是我们的账号名ctfuser
抓包
我们加密admin
Send to Repeater 改包之后 GO
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 ''.$sql;
$query = mysql_fetch_array(mysql_query($sql));
if($query[user]=="admin") {
echo "Logged in! flag:********************
";
}
if($query[user] != "admin") {
echo("You are not admin!
");
}
}
题目限制我们输入的用户名必须是admin
关键语句:
$sql="select user from ctf where (user='".$user."') and (pw='".$pass."')"
可以用最基本的sql注入:admin’) or 1=1#(密码任意 因为已经被#注释掉了)
原理是这样的:
这里记得一定要加右括号 否则user前面的左括号无法闭合
提交查询
题目已经提示我们考察的是union联合查询。
看看关键代码行:
$user = $_POST[user];
$pass = md5($_POST[pass]);
$query = @mysql_fetch_array(mysql_query("select pw from ctf where user='$user'"));
if (($query[pw]) && (!strcasecmp($pass, $query[pw]))) {
echo "Logged in! Key: ntcf{**************}
";
}
我们输入的密码经md5加密之后跟数据库中找到的pw比较,如果存在这样的pw并且两者相同的话输出flag
即post : user=‘ union select md5(2)#&pass=2
获取flag
查看页面源代码 关注一下关键代码段
$query='SELECT * FROM users WHERE name=\''.$username.'\' AND pass=\''.$password.'\';';
\是一个转义符 后面加上‘仅仅就是表示一个单引号 不再起闭合作用了。
这样我们能清楚看到这行代码中有四个单引号被转义了。
我们不知道这个数据库中都有那些数据 但是题目要求我们查询到存在的值才能输出flag,所以我们考虑get name=admin\ or 1=1#来进行sql注入。
我们的语句就变成了这样:(为了便于观察 我把转义的单引号先去掉了)
SELECT * FROM users WHERE name='admin\' AND pass=' or 1=1#';
这样我们get一个name变量值为admin’ AND pass= 不管这个变量是否能在数据库中查询到 我们后面执行的恒真句1=1总能让我们成功绕过登陆验证。
将这些个玩意儿复制到控制台执行看看
接着访问
尝试抓包
发现有tip:history of bash
回到一开始 访问:
http://teamxlc.sinaapp.com/web3/b0b0ad119f425408fc3d45253137d33d/.bash_history
teamxlc.sinaapp.com/web3/b0b0ad119f425408fc3d45253137d33d/flagbak.zip