攻防世界刷题笔记
攻防世界刷题笔记
背景
最近博客好久没更新了。CTFHUB web基础部分刷完很久了,提高部分的题目太难了,而且量也少。看了一眼阮行止学长提供的刷题顺序。打算开始做攻防世界。攻防世界在很久以前刚接触CTF的时候做了一些题目。当时每道题几乎都是看的wp,基础知识太薄弱了。现在做应该会好些。
view_source
1 |
|
页面禁用了右键。用Ctrl + U
或者F12
或者加view-souce:
前缀都可以获得flag。
robots
1 |
|
简单的robots.txt隐藏信息。
backup
页面提示你知道index.php的备份文件名吗?
以下为常用的index.php
备份文件。
1 |
|
在这道题中为index.php.bak
。
Cokkie
开局提示你知道什么是cookie吗?
。
我一共知道三种方式来看Cokkie,实际上就是HTTP的响应包。
-
Burpsuite。这比较麻烦,懒得开Burp 2333。
-
浏览器开发者工具->网络->标头
-
利用curl命令直接看(非常优雅
1
2curl -h
-I, --head Show document info only
disabled_button
按钮被设置了disabled
属性无法点击。在F12里删除后点击即可。
weak auth
Burp Cluster Bomb集束炸弹爆破。
账号admin 密码123456
simple_php
1 |
|
php弱类型绕过。
我们先看a。如果我们a传递一个0
会怎么样呢?这里有一个常识需要记住,$_GET
方式传递的值应该是没法传递整数的,也就是我们在浏览器地址栏的输入的数字实际上也是字符型串。
如果我们a传值为0
。比较 的时候也就是"0" == 0
。在PHP中的==
表示类型转化后是否相等。PHP中如果一个数字和一个数字字符串进行比较 ,那么就会自动按照数值进行比较,所以两者是相等的。但是我们无法获得flag,因为在php中"0"
是等于的FALSE
的。
所以我们传一个0,无法获得flag,这里可以用"0a"
来绕过"0a"
首先是一个字符串,但是它不是数字字符串,因为它不符合数字的规则,但是PHP在8.0版本之前,如果一个字符串和一个数字/数字字符串(php 5.6版本下失败) 进行比较时,会自动将字符串转化为数值。一个字符串如何转化为数值呢?其实就是根据它字符串中的最大数字字符串前缀来决定的。如下面的例子。
123a
的最大数字字符串前缀为123
。a123
没有数字字符串的前缀,因为它第一个字符就是字母,所以它的等效数值为0。1e2a
的前缀是科学计数法的1e2
,所以它的等效数值为100。
了解了这些,我们很容易就想到一些payload来得到第一部分的flag。
1 |
|
再看 第二部分,首先b
不能为数字 ,但是它要大于1234
。用1235a
就可以了。因为字符串1235a
在和1234比较的时候会自动转化为数值1235,比1234大,同时它还不是数字,实现绕过。
最终paylaod
1 |
|
POST&GET
可以用Hackerbar来发请求。这里写个request脚本吧。
1 |
|
xff_referer
题目提示说ip地址必须是123.123.123.123,还必须来自https://www.google.com
X-Forwarded-For(XFF)是用来识别通过HTTP代理或负载均衡方式连接到Web服务器的客户端最原始的IP地址的HTTP请求头字段。
Referer
字段实际上告诉了服务器,用户在访问当前资源之前的位置。这往往可以用来用户跟踪。一个典型的应用是,有些网站不允许图片外链,只有自家的网站才能显示图片,外部网站加载图片就会报错。它的实现就是基于Referer
字段,如果该字段的网址是自家网址,就放行。
这道题里在请求包里加上两个属性即可。
webshell
蚁剑直连即可。
command_execution
常见的命令执行题,利用命令分割符实现命令联合执行。
1 |
|
1 |
|
simple_js
开局让你输密码,但是无论你输什么,它都会弹出这句话。
查看源代码,发现一个长相丑陋的js代码。
1 |
|
我们发现在此代码中有一些奇怪的数值,比如70,65,85,88,32,80,65,83,83,87,79,82,68,32,72,65,72,65
和\x35\x35\x2c\x35\x36\x2c\x35\x34\x2c\x37\x39\x2c\x31\x31\x35\x2c\x36\x39\x2c\x31\x31\x34\x2c\x31\x31\x36\x2c\x31\x30\x37\x2c\x34\x39\x2c\x35\x30"
。
观察第一个,怀疑是ascii码值。这里写一个简易脚本。
1 |
|
这样我们就可以得知了,这个狗屁不同的js代码写了这么多,实际的功能就是把ascii码转化为字符,然后输出出来,不管我们输入的"密码"究竟是什么。
ok,那我么再分析第二个可以字符串,它是十六进制编码,我们可以用python直接print出来。
原来这里又藏了一些ascii码,只要再用上面的脚本跑一下就能出flag了。
配合上题目秒数里的flag格式,即可得到最终flag。
baby_web
题目描述:想想初始页面是哪个
打开来的页面是1.php
。这十分奇怪,我们手动访问index.php
也会自动跳转到1.php
。
于是我们利用优雅的命令行curl
来康康有什么玄机。
1 |
|
能藏哪呢?只能响应包的标头里了吧2333
成功得到flag。同时我们也知道了跳转的原因了,是Location
在起作用。
php如何添加头部信息呢?十分方便,用header
函数即可。
1 |
|
Training-WWW-Robots
简单的robots.txt藏信息,这不是和之前的robots
题目重复了嘛2333。
php_rce
ThinkPHP漏洞利用。
github有漏洞合集。SkyBlueEternal/thinkphp-RCE-POC-Collection: thinkphp v5.x 远程代码执行漏洞-POC集合 (github.com)
1 |
|
随便找一个paylaod,试一下,得到准确版本。V5.0.20
利用github里的5.0.21的命令执行漏洞即可。
1 |
|
观察payload,发现运行的命令就是最后的id
。只需要在这里改成其他的命令,我们就能命令执行了。
1 |
|
1 |
|
得到flag后我还尝试了以下写木马2333。之前很多题都不能写,估计设置了权限。这道题可以。
首先把一句话木马base64加密一下,防止写文件时$
被shell认为是特殊符号的问题(当然用单引号也可解决这个问题)
1 |
|
然后写文件。
1 |
|
成功连接。
我们可以看见Thinkphp的网站根目录是在/var/www/public
里的。
Web_php_include
这道题考察伪协议php://input
的利用。
1 |
|
include
函数的参数是一个文件名,也就是我们可以控制包含的一个文件名。但是显然,我们知道的文件只有index.php
本身,自己包含自己没有意思,我们最好能够包含一个可以执行命令的php文件。
php://input
伪协议就可以帮助我们实现这个想法,它可以读取一个数据流。这个输入流是用POST方式传递的。
也就是这样一个过程。
- 我们往page里写
php://input
,同时POST传递我们自己的php代码。 - index.php include的时候发现,这不是普通的文件名,而是一个数据流,就把我们POST发送的php代码给包含了,这就实现了远程命令执行。
php://input
生效的条件是allow_url_fopen
和allow_url_include
都设置为On
。
题目其实还给了个phpinfo.php文件,这是后来命令执行的时候发现的,下次做题还是得先扫,掌握更多的信息。
同时考虑到这道题对php://
进行了循环检测,一直置空,普通的双拼是无法绕过的。但是它用的strstr
函数和stristr
,大小写敏感,所以我们用Php://
大写绕过即可。
这道题最后cat fl4gisisish3re.php
的时候,是看不到flag的,因为这个文件它内部是一个php的赋值语句,index.php include之后,没有echo 语句,照样看不到。有两种方法解决。
-
cat 的时候加上base64加密。
1
2# POST
<?php system("cat fl4gisisish3r3.php | base64"); ?> -
利用php://filter 直接读base64加密后的源码。
1
?page=Php://filter/read=convert.base64-encode/resource=fl4gisisish3r3.php
此外,其实这道题按理还有一种做法,那就是远程包含一个url文件。
但是这道题输入一个url后直接崩溃了,不知道什么情况。我在我服务器上尝试是可以的。
ics-06
描述:云平台报表中心收集了设备管理基础服务的数据,但是数据被删除了,只有一处留下了入侵者的痕迹。
页面有个id。
sql注入做多了,就以为是注入,但是手动试了很多都不行,没有回显,用sleep函数也失效。貌似输入除了非数字的都会跳转到id=1
。因为它的标头里有个Localtion
。
自然sqlmap也扫不出来。
无奈看wp,看到一半突然知道直接爆破id即可。
当id为2333时,即可获得flag。
warmup
1 |
|
这道题之前刚接触ctf的时候做过,当时很难理解。现在很好理解了。
首先这道题有个hint.php
,提示flag在ffffllllaaaagggg
而souce.php
中有include
文件包含函数,我们可以想办法绕过,然后去包含这个flag文件即可。
题目中有这样一个语句
1 |
|
也就是把你传的哪个文件名里问号前面的部分截取出来(如果没有问号就全取)。但是一般来说正常文件名也没有问号呀2333,所以这道题还是挺刻意的。
它会去验证问好前面的部分是不是source.php
或者hint.php
,只有这两个文件是白名单。
那么很显然payload就是这样的。
1 |
|
但是非常可惜,没有输出。
被迫看wp,原来这个flag文件在根目录下,hint倒是说清楚呀2333。
1 |
|
同时这道题还可以二次url加密,形成一个payload,没啥意思。也能得到flag。
这道题让我比较感兴趣的一点在于目录遍历的时候,文件名后加个?
竟然能够毫无阻碍得继续向上级目录进发,仿佛没有这个问号似的。
在linux里是无法实现类似操作的。
我用本地环境试了一下,发现还蛮有道理的。
1 |
|
1 |
|
这是为什么呢?看完下一个payload你就懂了。
1 |
|
我在poc.py?后面又乱打了一堆东西仍然能够正常得到flag。
实际上在php眼里这几个paylaod都是一样的,因为它们都是通过当前目录下的某个文件,一开始是poc.py
,然后是poc.py?
,最后是poc.py?sdjfljdflsldfjasklfjweiohfuuwejvsdv6513544
,来进入上级目录,我们这种目录遍历的形式实际上把哪个文件看成了文件夹。
所以这时哪个文件具体的内容,甚至说存不存在这个文件都已经没有关系了,因为我们只是把它当跳板,显然php也是这么想的。
所以我们在这道题里输的source.php?
,php会把它看成一个文件夹,虽然它不存在,而我们以这个虚空的文件夹为基础跳板,得到了根目录下的flag。
web2
看似是一道web题,实际上是一道密码题2333。对应写出逆就行了。
1 |
|
解密脚本
1 |
|
这里发现了一个有趣的函数,str_rot13,实际上就是移位密码,每个字母往后移13位。因为字母个数是26位,所以再移一次就移回来了,故其逆函数就是本身。