南邮CTF平台WEB题writeup
平台地址:https://cgctf.nuptsast.com/login
1.签到题
F12查看网页源代码就有flag
2.md5 collision
附上题目给的源代码
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";}
这道题要求的是用GET方式提交一个变量a,如果a进行md5加密后能与QNKCDZO进行md5加密后的值相等,则能得到flag
这道题用了php弱类型这个知识点,附上网上的讲解
所以只需要传入的参数md5加密后是0e开头就行,附上一个参考链接http://www.219.me/posts/2884.html
3.签到2
输入它说的内容,发现输入到一定长度的时候无法再输入,F12查看原代码,更改最大输入长度
4.这道题不是WEB
打开链接,F12无果,burp抓包无果,想到不是WEB又有张图片,于是保存下来,这是一道杂项题图片隐写,16进制编辑器打开末尾就有flag
5.层层递进
方法一:
F12查看网络项(NetWork)发现有个特别的404错误页面,查看网页源代码得到flag
方法二:
F12查看源代码,发现链接里面有个网页,尝试访问
访问了过后继续查看源代码又有链接,一直访问,最后出现404.html,访问得到方法一那种效果图,F12查看源代码可得flag
6.AAencode
将代码放入控制台执行可得flag
7.单身二十年
点开链接,进入页面说这个页面永远不可能有flag,F12和burp抓包都没有结果,考虑上一个页面,F12查看元素,发现它说访问链接可以得到flag
于是在网页中访问,发现每一次访问都自动跳转到那个永远没有flag得页面,这种情况就使用burp抓包,发送到repeater,在地址栏添加内容如下,得到flag
8.php decode
该题给的代码如下
<?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;
}
eval(CLsI("+7DnQGFmYVZ+eoGmlg0fd3puUoZ1fkppek1GdVZhQnJSSZq5aUImGNQBAA=="));
?>
这道题直接将代码写出来运行看吧,把eval改为echo,得到flag
9.文件包含
都说了文件包含,,,进入后发现?file=show.php
,,,,,就直接使用php伪协议(php://filter/read=convert.base64-encode/resource=index.php)
读index.php吧,得到base64加密后得源码,解码后得到flag
10.单身一百年也没用
这些题目名字真牛逼。。
和单身20年一样的做法。。。
11.COOKIE
burp抓包,发现cookie:Login=0 改为1,得到flag
12.MYSQL
它说存在一个robots.txt,于是访问一下得到
查了一下intval函数的作用:获取变量的整数值,也就是21.2=21 32.5=32
根据提示访问sql.php,它说id=1024时返回错误,然而其它值的时候没有回显,于是考虑flag就在1024里面,想到有个intval函数,于是可以让id=1024.2,得到flag
13.GBK Injection
这道题flag被吃了,每个表都没有flag
方法一:
题目都说了是宽字节注入,于是用%df来
利用order by判断出2才行,然后联合查询
select group_concat(schema_name) from information_schema.schemata
查询,获取所有数据库,一共两个
然后爆表id=%df' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()
然后爆字段,具体的表名应该进行16进制编码才行
方法二:
用sqlmap跑,可以用上unmagicquotes.py脚本
14./x00
附上给出的代码
if (isset ($_GET['nctf'])) {
if (@ereg ("^[1-9]+$", $_GET['nctf']) === FALSE)
echo '必须输入数字才行';
else if (strpos ($_GET['nctf'], '#biubiubiu') !== FALSE)
die('Flag: '.$flag);
else
echo '骚年,继续努力吧啊~';
}
方法一:
根据代码可以得到以GET方式传入的参数nctf必须为数字并且需要包含字符串#biubiubiu
,如果赋值nctf
为123#biubiubiu
根据php弱类型自动转化为123
,所以这样使用%00截断
,构造?nctf=123%00%23biubiubiu
,#必须url编码为%23,这样又通过判断是数字,又包含字符串
方法二:
如果传入是一个数组,那么ereg会返回NULL,故不等于FALSE,所以绕过,strpos里面也是返回NULL,所以NULL!==FALSE
15.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加密后一样,利用php弱类型,传入的a和b进行md5加密后都是0x开头的
16.变量覆盖
它给了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 } ?>
于是post这两个值相等就行
17.伪装者
构造X-Forwarded-For就行
18.上传绕过
这道题上传一下发现是白名单,采用00截断上传
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nWoSD2dr-1606812441908)(http://www.ghtwf01.cn/usr/uploads/2019/10/847869062.png)]
成功上传得到flag
19.SQL注入1
附上给的源代码
<html>
<head>
Secure Web Login
</head>
<body>
<?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];
?>
<form method=post action=index.php>
<input type=text name=user value="Username">
<input type=password name=pass value="Password">
<input type=submit>
</form>
</body>
<a href="index.phps">Source</a>
</html>
这里面的if语句里面只判断了user是否为admin,已经给了sql语句,于是就闭合一下使用万能密码admin’) #这样也注释掉了后面的pw部分
20.pass check
附上给的代码
aaa@qq.com$_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函数比较两个字符串,如果相等则输出0,如果strcmp中比较的有数组则会返回NULL,而0和NULL在比较中相等,所以POST一个数组
21.起名字真难
附上题目给的源码
<?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';
?>
这道题目的要求是输出的值是54975581388,但是每一位又不能是数字,于是考虑将该数字进行16进制编码
前面加上0x赋值给key
22.密码重置
首先修改用户名,发现不能修改,然后发现url里面有个user1=Y3RmdXNlcg==是个base64加密数据,解密发现就是ctfuser
于是将admin进行base64编码后插入到url中,最后F12修改不能修改那个内容为admin,得到flag
23.SQL Injection
F12中可以看到源代码
<!--
#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;
-->
这道题提示了\可以转义’,让’实体化
这道题应该让username=\
,这样sql语句就变成了name=\''\'\' AND pass=\''
加粗那对单引号闭合,所以输入username=\&password=or 1=1 %23(#)
,万能密码登录
实际上sql语句:name='AND pass=' or 1=1 #'
(被注释)
24.综合题
打开题就发现一大页的jsfuck代码,放入控制台运行一下得到一个网页
于是访问一下,挺秀。。。
于是抓包看看响应头,发现tip
网上查询资料得知linux下的终端日志文件.bash_history,于是访问一下,得到flag压缩包文件下载解压可得flag
25.SQL注入2
附上给的代码
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>");
}
}
?>
这段代码的意思是要求用户输入的密码的md5值要和数据库中保存的密码相等,用户输入的密码的md5值我们可以控制,而数据库中保存的密码我们不知道,所以考虑修改数据库中保存的密码,也就是修改$query
,题目说了用union
,所以user='union select md5(1) #
这样$query
值就为md5(1)
,现在只需要将密码输为1,它的md5
值就和数据库中保存的密码$query
一致了
26.密码重置2
F12在head里面找到管理员邮箱
随便输入一个token试试
发现验证token的是submit.php文件
根据提示,用vi编辑器打开,然后非正常退出(可以用ctrl+Z),生成了一个.swp备份文件,submit.php的备份文件是.submit.php.swp(不要忘了最前面有个.),访问一下
发现token长度要为10,并且值要为0,于是赋值0000000000
得到
27.file_get_contents
F12查看到一串代码
<!--$file = $_GET['file'];
if(@file_get_contents($file) == "meizijiu"){
echo $nctf;
}-->
于是将file赋值为php:\\input
然后POST参数meizijiu
,得到flag
28.变量覆盖
附上代码
<!--foreach($_GET as $key => $value){
$$key = $value;
}
if($name == "meizijiu233"){
echo $flag;
}-->
这段代码的意思是将key的值作为变量名,再将value的值赋值给它
于是构造name=meizijiu233
上一篇: 字节跳动大调整背后,新流量时代来了