CTF竞赛

CTF入门指南

CTF基础概念

CTF是一种网络安全竞赛形式,主要通过解密、逆向工程、网络攻击、隐写术等方式解决各种网络安全挑战。
CTF题型通常分为Jeopardy(解题型)和Attack-Defense(攻防型)两大类。Jeopardy题目常见分类有Web、Crypto、Pwn、Reverse、Forensics等。

考点

Web安全:学习基础Web漏洞(如XSS、SQL注入),逐步理解现代Web应用安全。
逆向工程(Reverse Engineering):熟悉汇编语言、调试工具,掌握静态和动态分析。
Pwn:学习二进制安全基础知识,如缓冲区溢出、格式化字符串漏洞。
密码学(Crypto):了解常见加密解密算法及其破解方式。
取证(Forensics):掌握文件分析、磁盘取证、内存分析的基本方法。
隐写术(Steganography):研究文件中的隐写信息,如图像、音频和文档。

常用工具

  • 逆向分析:IDA Pro、Ghidra、x64dbg
  • Web漏洞挖掘:Burp Suite、SQLmap、Nmap
  • 密码学工具:CyberChef、Hashcat、John the Ripper
  • 取证分析:Autopsy、Volatility
  • 隐写术工具:Stegsolve、Exiv2、Audacity

CTF题库和刷题平台

  • CTFHub:包含大量CTF题目,适合初学者练习和巩固基础。

  • Pwnable.kr:专注于Pwn题型的训练平台,有详细的解题指引。

  • Root-Me:拥有不同难度级别的安全挑战,涵盖Web、密码学、逆向工程等题型。

  • Cryptohack:专门提供密码学题目的练习平台。

  • WebGoat:OWASP维护的一个Web安全靶场,适合Web安全知识的系统化学习。

CTF资源与解题思路

  • CTF Wiki:一个全面的CTF学习资源库,涵盖各种题型的理论知识和工具使用。
  • SecWiki:网络安全资源平台,包含CTF题解、知识点总结及工具推荐。
  • CTF All-In-One:GitHub上的CTF学习项目,包含丰富的入门教程和进阶题解。

Nmap工具

默认nmap只扫描常用的1000的端口

要扫描所有端口需要在命令里加上-p-

扫描指定的端口使用-p端口来指定

以上两个都不会扫描UDP端口,要扫描UDP端口需要加上U,如下

T表示tcpU表示UDP

1
2
nmap -sT 目标
nmap -sU 目标

TCP扫描

正常的TCP建立连接需要进行三次握手,

主机发送SYN到目标主机,目标主机回复SYN ACK表示我收到了,主机收到后回复SYN开始建立连接

nmap -sT同样也会完成握手动作的,只不过当目标主机发送数据过来的时候,nmap不会发送正常的数据,而是会发送RST进行会话的中断

正常结束TCP会话是需要发送FIN

在TCP报文的报头中,有几个标志字段:

SYN ACK RST FIN
同步连接序号,请求建立连接 请求/应答状态 连线复位 结束连线。

1、 SYN:同步连接序号,TCP SYN报文就是把这个标志设置为1,来请求建立连接;
2、 ACK:请求/应答状态。0为请求,1为应答;
3、 FIN:结束连线。如果FIN为0是结束连线请求,FIN为1表示结束连线;
4、 RST:连线复位,首先断开连接,然后重建;
5、 PSH:通知协议栈尽快把TCP数据提交给上层程序处理。


详细TCP三次握手

引用一文读懂TCP的三次握手(详细图解)_tcp三次握手图解-CSDN博客

详细TCP三次握手过程:

在学习TCP三次握手的过程前,首先熟悉几个缩写简称:

状态 功能
TCB 传输控制块,打开后服务器/客户端进入监听(LISTEN)状态
SYN TCP报文标志位,该位为1时表示发起一个新连接
ACK TCP报文标志位,该位为1时,确认序号有效,确认接收到消息。TCP规定,在连接建立后所有报文的传输都必须把ACK置1
seq sequence number,报文初始序列号,代表发送的第一个字节的序号
ack acknowledgement number,报文确认序号,代表希望收到的下一个数据的第一个字节的序号
熟悉上面几个标志位和序列号含义后,下面来看TCP的三次握手过程:

先上几个帮助理解的点:
不管请求还是应答,都是带两种数据:请求号SYN/应答号ACK + 数据包报文号;

请求时要发请求号SYN,应答时要发送应答号ACK在数据包传送时,发送方要发送当前数据包报文号seq和确认收到上一个数据包的确认报文号ack。

第一次握手:客户端——请求(发送请求SYN+数据包当前序列号seq,无需应答)

客户端创建传输控制块TCB,进入监听LISTEN状态。
设置SYN=1,表示这是握手报文,并发送给服务器
设置发送的数据包序列号seq=x
此时客户端处于同步已发送SYN-SENT状态

第二次握手:服务器——确认(发送应答ACK+请求SYN+确认收到上一个数据包的确认号ack+ 当前数据包序列号seq)
设置ACK=1,表示确认应答。
设置ack=x+1,表示已收到客户端x之前的数据,希望下次数据从x+1开始
设置SYN=1,表示握手报文,并发送给客户端
设置发送的数据包序列号seq=y
此时服务器处于同步已接收SYN-RCVD状态

第三次握手:客户端——确认服务器的确认(发送应答ACK+确认收到上一个数据包的确认号ack+ 当前数据包序列号seq ,连接已建立,无需请求)
设置ACK=1,表示确认应答。
设置ack=y+1,表示收到服务器发来的序列号为seq=y的数据包,希望下次数据从y+1开始
设置seq=x+1,表示接着上一个数据包seq=x继续发送
至此三次握手结束,连接建立


同样是以TCP数据段里表示会话的状态的,使用nmap sT会存在一定的副作用,

1
nmap -sT 127.0.0.1

首先因为需要完成握手的整个动作的过程,因此比较花时间,其次目标主机通常会对完成握手的会话进行日志的记录,扫描的时候容易留下痕迹,我们也不能完全否认nmap -sT的作用,因为只要目标主机发送了SYN/ACK包过来,nmap就可以标记这个端口是open开放状态的了,如果目标主机返回的不是SYN/ACK包,而是RST包,nmap则会记录这个端口为closed关闭状态,如果nmap发送SYN包以后没有收到回复的话,那就很有可能被防火墙阻挡了,此时nmap就会标记端口为filtered被过滤状态了,为了不留下明显的痕迹需要用高级一点的nmap -sS

当收到目标主机发送过来的SYN/ACK的时候nmap不会走完整个TCP握手过程,不会发送FIN而是发送RST,在收到目标主机的SYN/ACK的时候,其实也是确认了访问这个的端口是开放的,既然目的达到了,自然就用RST赶紧结束会话了,如果收到的不是SYN/ACK而是RST,则表示目标主机的这个端口关闭了,如果连RST都没收到,什么都没有收到的话,那大概率是被防火墙拦截了,也就是会标记为“过滤”,另外收到ICMP报错消息,也会被标记为“过滤”。

如果直接发送RST不是更省事吗,但是目标主机会以为你没有收到SYN/ACK,导致目标主机重传,nmap在这里只是想要了解信息,并不是要进行破坏或者资源的浪费,因为nmap -sS没有完成整个握手过程,因此被称为“半连接”扫描,或者“半开”扫描,还可以叫做SYN扫描,对于nmap的TCP扫描来说,nmap的SYN扫描能够更快达到目的,而且因为没有完成握手的过程,相对来说不被保存日志的几率会更低,就更不容易留下痕迹了

如果直接用nmap进行扫描,默认会进行TCP连接扫描,如果加上sudo,默认则是用SYN半连接进行扫描

UDP扫描

UDP不像TCP扫描和SYN那样,都以收到SYN/ACK来判断端口的开放。UDP没有ACK这样的确认机制 ,也就是说,UDP只能依靠目标主机的回复做出判断

问题是对于大部分端口,nmap发送的数据包没有负载,对方相当于收到一个空包,这样的数据包一般不会收到主机目标的回复,另外如果防火墙丢了你的包,一般也不作回复,因此在使用UDP扫描的时候会经常看到openfiltered一起显示,此时端口可能开放了,也可能被防火墙阻挡了

那如果UDP包收到回复了呢,此时并不是有鬼,而是如果UDP端口关闭了,一般会回复类型和代码为3的ICMP

那我们如何判断UDP端口是开放还是被过滤了呢

小技巧是使用nmap -sUV 这里加的V会进行版本扫描,nmap会在open|filtered的端口中做探测 ,确认运行的软件版本

,从而明确端口为开放的状态,使用UDP会有一个痛点就是慢,毕竟目标主机不会回复没有负载的UDP包,加上防火墙以及限流的关系,导致诸多不确定因素,因此同一端口nmap一般会出现太多次探测请求的情况,UDP扫描最好配合其他选项进行探测,例如

1
nmap -sUV --top-ports

意思是扫描常用的端口,如果加上数字100,则表示扫描常用的100个UDP端口

1
nmap -sUV --top-ports 100

icmp和ping扫描

端口扫描是nmap的核心功能,主机发现也是一个重点,一般是先探测有哪些主机是在运行,然后再对正在运行的主机进行端口扫描,查看它开放了什么服务以及放行了哪些端口。

在没有学习nmap之前我们一般用ping命令,来查看是否能和目标主机连通,从而确定目标主机是否在运行

在nmap里直接用nmap -sn就可以进行ping扫描了 ,和直接用ping命令不同的是,单独的ping命令一次只能ping一个地址

而nmap在这里可以用-表示IP的范围,当然也可以用CIDR的方式来指明范围

1
2
nmap -sn 192.168.122.1-100
nmap -sn 192.168.122.0/24

不管是本地,还是远程的网络我们都可以用nmap -sn来进行,不同的是,扫描本地网络实际上用了ARP协议进行请求,扫描远程网络则用了ICMP协议,还会利用TCP SYNTCP ACK进行主机发现,可是遇到用windows服务器就要注意了比如2016,2019,2022这样的版本防火墙会默认屏蔽掉所有ICMP包 ,如果继续用nmap -sn就会进入死胡同了

此时nmap -Pn会更实用,-Pn相当于No Ping,不要ping了,以此来绕过防火墙的阻挡

但是这个命令非常耗时间,因为nmap会假设目标主机是正在运行的,如果目标主机没有在运行,会导致nmap重复探测

sqlmap常用参数

1
2
3
sqlmap -u "地址" --current-db --batch
sqlmap -u "地址" -D 库名 --tables --batch
sqlmap -u "地址" -D 库名 -T 表名 --dump --batch
  • –current-db获取当前使用的数据库
  • –batch保持默认选项
  • -D参数用来指定库名
  • –tables用来获取-D参数指定的库下的所有表名
  • –tables用来获取-D参数指定的库下的所有表名
  • –dump表示获取表的数据

1.基本参数

  • -u <URL>:指定目标URL-u "http://example.com/vuln?id=1"

  • -r <请求文件>:从

  • -m <文件>:从文件读取

  • --data <数据>:发送POST请求数据

  • --cookie <cookie>:指定要发送的 Cookie

  • --user-agent <agent>:设置User-Agent

  • --random-agent:随机选择User-Agent

  • --referer <referer>:设置

    检测选项

2.检测选项

  • --level <level>:设置检测
  • --risk <risk>:设置风险
  • --technique <tech>指定地点:BE(报错)U(联合查询)、``S(堆T`(时间盲
  • --time-sec <seconds>:设置时间盲注

3.杂

  • --dbs:枚举。
  • --tables:参加研究的--tables -D testdb
  • --columns:体育节目的--columns -D testdb -T users
  • --dump--dump -D testdb -T users
  • --dump-all:導
  • --search:搜索数据库

4. 绕过

  • --tamper <scripts>:指定--tamper=space2comment
  • --delay <秒>:设置每次请求
  • --timeout <秒>:设置请求

5.认证参数

  • --auth-type <类型>:设置认证类型,支持Basic摘要DigestNTLM`等。
  • --auth-cred <用户:密码>
  • --proxy <代理>:设置HTTP--proxy=http://127.0.0.1:8080
  • --tor

6. 输出控制

  • --batch:自动接受默认
  • -o:保存扫描
  • --output-dir <目录>:指定

7. 实例

例如,使用sqlmap进行

1
sqlmap -u "http://example.com/vuln?id=1" --dbs

这个命令会尝试检测目标页面的 SQL 注入漏洞并推出可用的数据库。

[SWPUCTF 2021 新生赛]jicao

访问主页是一段php代码,包含了flag.php文件,设定了一个POST请求的id和GET请求的json语句会对GET请求的数据进行json解码。如果id和json变量的值都等于设定字符串,打印flag

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

直接使用hacker插件进行传参

传参

利用方法在网址内里输入命令

1
http://1.1.1.1/index.php?m=design&c=api&token=ba0VXPBUXu&id=4&format=&cmd=system('cat /etc/passwd');

cmd与前面=号需要用&连接

RSA

摩斯密码音频隐写

工具解密

使用像Audacity这样的音频处理软件打开文件,然后可以在音道的最上边看到一些特殊的:

img

看起来是一个摩斯电码,短线代表 .,长线代表 -,最后摩斯电码翻译如下:

1
.... -... -.-. ----. ..--- ..... -.... ....- ----. -.-. -... ----- .---- ---.. ---.. --.- ..... ..--- . -.... .---- --... -.. --... ----- ----. ..--- ----. .---- ----. .---- -.-.

摩斯电码解码得到:

1
HBC925649CB0188Q52E617D70929191C

md5解密得到valar dohaeris

试了不对,又试了md5值的小写,通过了

flag:5bc925649cb0188f52e617d70929191c

Python摩斯电码解密

摩斯电码解密可以使用诸多在线网站,当然也可以用Python进行解密:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# -*- coding:utf-8 -*-
s = input("input the cipher_text Enclose with quotes:")
codebook = {
'A':".-",
'B':"-...",
'C':"-.-.",
'D':"-..",
'E':".",
'F':"..-.",
'G':"--.",
'H':"....",
'I':"..",
'J':".---",
'K':"-.-",
'L':".-..",
'M':"--",
'N':"-.",
'O':"---",
'P':".--.",
'Q':"--.-",
'R':".-.",
'S':"...",
'T':"-",
'U':"..-",
'V':".--",
'W':".--",
'X':"-..-",
'Y':"-.--",
'Z':"--..",
'1':".----",
'2':"..---",
'3':"...---",
'4':"....-",
'5':".....",
'6':"-....",
'7':"--...",
'8':"---..",
'9':"----.",
'0':"-----",
'.':".━.━.━",
'?':"..--..",
'!':"-.-.--",
'(':"-.--.",
'@':".--.-.",
':':"---...",
'=':"-...-",
'-':"-....-",
')':"-.--.-",
'+':".-.-.",
',':"--..--",
'\'':".----.",
'_':"..--.-",
'$':"...-..-",
';':"-.-.-.",
'/':"-..-.",
'\"':".-..-.",
}
clear = ""
cipher = ""

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
while 1:
ss = s.split(" ");
for c in ss:
for k in codebook.keys():
if codebook[k] == c:
cipher+=k
print(cipher)
break;

有时候可以观察出来

img

图谱可以看到flag