CTF部分学习笔记
初衷:对自己ctf相关学习做一个笔记/记录?(只是一个菜?而已)
PHP方面
1.变量覆盖:
<?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 } ?>
S
E
R
V
E
R
[
"
R
E
Q
U
E
S
T
M
E
T
H
O
D
"
]
=
=
"
P
O
S
T
"
即
用
P
o
s
t
提
交
上
来
的
请
求
e
x
t
r
a
c
t
(
_SERVER["REQUEST_METHOD"] == "POST" 即用Post提交上来的请求 extract(
SERVER["REQUESTMETHOD"]=="POST"即用Post提交上来的请求extract(_POST); extract函数是一个典型的变量覆盖漏洞的函数,关于其解释:
extract() 函数从数组中将变量导入到当前的符号表。
**该函数使用数组键名作为变量名,使用数组键值作为变量值。针对数组中的每个元素,将在当前符号表中创建对应的一个变量**。
在本题中把POST上来的东西导入当前符号表,然后去判断pass(我们的输入)和thepassword_123(后台用于验证的密码)是否相等,在此处有一个变量覆盖。
payload:pass=&$thepassword_123=
2.简单的审计(题不难,分析一下代码)
<?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!";
}
?>
首先,@符号是一个错误控制符**屏蔽掉出错信息,有@时就算连接出错,也不会报错的,防止别人根据错误提示信息来推测出你的数据库结构进行注入攻击一类的黑客行为 **
而strcmp是比较两个字符串大小(大小写敏感),相关链接PHP中的strcmp
这个函数的相关漏洞strcmp相关漏洞,简而言之当你传上来的数据类型有问题时,他会直接return 0;相当于判断两个相等了(简直nc)
payload:pass[]=1
PHP is the best 语言!
题面:
<?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';
?>
ord函数是返回一个字符的ascii码值
其实就是对number里的每一个字符判断,如果是数字,就false 而number是我们传入的key变量。
在for的外层进行了一个逻辑比较return $number == '54975581388';
也就是说 我们输入的key应该等于这个字符串,可是又不允许有数字。
考点是一个16进制的绕过,将54975581388转16进制然后输入,php在解析0x开头的字符串的时候会先变成10进制再比较。key=0xccccccccc,ccccccccc这个16进制是没有数字的,那么就会绕过for的比较。
HTTP相关
1.ip伪造:X-Forwarded-For的相关知识:X-Forwarded-For
SQL注入相关
1.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 = $_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 "<p>Logged in! Key: ntcf{**************} </p>";
}
else {
echo("<p>Log in failure!</p>");
}
}
?>
分析一下:大致就是post上来两个变量user和pass然后pass经过md5后与数据库中的pw字段中的密码比较;
获得flag条件:1.pw字段可以被查询到。2.md5后的pass与数据库中的密码一致。
tip说用union:如果sql语句中 " select username from user where username = ‘aaa’ union select md5(3);"的前面的一个查询不正确,后面一个查询结果将会在前面一个查询字段里.user=' union select md5(2)#&pass=2