CTF 流量包相关-流量分析(2) RSA密钥流 traffic讲解

声明一下

本文是根据b站-风二西大佬的视频边做题边总结写成的,可以去支持一下风佬,风佬太强辣!!!
风佬流量分析配套题与脚本

另外上一期其实也可以看看的说,这一篇是上一期的后续吧
传送门

然后后面那单独一道题,风佬也有视频在这里但老实说,我觉得风佬磁性的声音将起来有点抽象,自己理解还是好一点的,这里不是说风佬的不好啊(疯狂保命)

另外从第11个知识点往后基本就应该是一些题目的合集了,毕竟实战的话,战着战着就不知不觉能学到很多其他知识,特别是web知识,流量包肯定是和web知识相关的,有时间的可以看看web的相关知识点,这里就不指路了,我不是web手,还在学QAQ

11、RSA密钥

之前有说过TLS加密流量,那是一种ssl流量,但这一次是加入了其他元素,一个RSA算法

这涉及到了密码学,如果不是学密码学的话,只要懂一点知道怎么算RSA就行了,这里也只简单介绍一下,如果想了解原理的话,还请自行搜索

简单来说就是一个n(一般管这个叫做模)是两个素数的乘积,任意取一个大整数e,密文为d,φ=(p-1)*(q-1)
然后就有明文m = (c ^ d) mod n


说的话大概就是这个意思,还是做题容易理解一点:21.root

进流量包就可以看到又TLS协议

image-20230428212954735

但是之前讲过的TLS是直接给了你一个log密钥文件,这个什么都没给,看来只能去流量包中找信息了
还是老规矩,先搜一下flag,什么都没有很正常,因为流量包不大的原因,所以我尝试一个一个的去看了一下整个流量包里的协议
(后面看了风佬的视频之后才知道可以尝试搜一下文件名,可以直接定位到那里,我在这里确实花了不少时间,建议还是学风佬的方法吧,但这就要看你想不想得到这回事了)

image-20230428214313940

在这里找到了模n和大整数e,先复制出来,因为是16进制,复制出来后记得加个0x

0x726f6f7400000000000000000000000000000000001b000000000000000000000000001ffffb0000000000000000000000001ffffb0000000000000000000000001fffff7777777b00000000000000001ffffffffffffb00000000000000001ffffffffffb0000000000000000001ffffffffffb0000000000000000001ffffffffffffb00000000000000001fffff2222222b00000000000000001ffffb0000000000000000000000001ffffb0000000000000000000000001ffffb0000000000000000000000001ffffb0000000000000000000000001ffffb0000000000000000000000001ffffb0000000000000000000000001ffffb00000000000000265293c4422be3532638feeb2a635e865e5bccd4862d1491f8e46ed41afdab32ab1e913c296c45a723a371cc4ad218d273a494ac501a1c677576b84d3a1700b24e38f3d7c8090c952767f8a9da532eb4496a953fa2b2641f93af58321e491ad6b3e1f6600ea1757635a2d47562dff2f245bfc8ed511420931de246d56334d8897d6465b227f6c095ece1ad994c7551f08dbc21f8b40691ee51f5f72d052d9352062f90b0e7c52c2eb18196c2c985101af4eac67499396c6241ad4f2439ed11f87d67e73a239b865c45d65a61cf0f56082de831b97fb28ae8222a7195e0ec06c08281ffc16e7106e77e68b8c4510424beeb5582fe21cc345f53534682b75c368d73c9
转10进制:
119514949101869418903318873112867362646835071069241106524305309393065463453656568774743760570131693630159578791023971219610889380592598543536351234572467281587006324435481617535146537233169791976943380665697114009764947413190424965605151568078201516319476934559728328089096265594820785319942352507655193149106742096711100954500911687865197173709176323170965183162767042434738106978751911965481346436431672573623281881734153294758147557422163198312359915688282919868328721978258906227136067834058632472297370857579705187167410321575782375360591482072103305682978126915060591553714123014075758332542543138964874724542072396937584280625337262888775332970921021304750133076287918708895881009630077473404974677880966925170111450054682589858406625668247502091263399827525224215993035344424566568011928443888310172591327112851125472052921219080258671669993973898127049957265386657286586085405099815473365810806674154776699651214819118383817272562813199977233417411126959716068072338393084310289588450441128514416597910759814182527294940228828417785903441042114817369303389645545333054503129561885740632378715731405799144085706505382819066670726261358910837171602305916072912729756717338147737273166145500948558122541808933901885205278570148809

然后可以利用工具比如yafu,直接把模分解:

image-20230504161908869

p=345709341936068338730678003778405323582109317075021198605451259081268526297654818935837545259489748700537817158904946124698593212156185601832821337576558516676594811692389205842412600462658083813048872307642872332289082295535733483056820073388473845450507806559178316793666044371642249466611007764799781626418800031166072773475575269610775901034485376573476373962417949231752698909821646794161147858557311852386822684705642251949742285300552861190676326816587042282505137369676427345123087656274137257931639760324708350318503061363031086796994100943084772281097123781070811610760735943618425858558459014484742232018933
q=345709341936068338730678003778405323582109317075021198605451259081268526297654818935837545259489748700537817158904946124698593212156185601832821337576558516676594811692389205842412600462658083813048872307642872332289082295535733483056820073388473845450507806559178316793666044371642249466611007764799781626418800031166072773475575269610775901034485376573476373962417949231752698909821646794161147858557311852386822684705642251949742285300552861190676326816587042282505137369676427345123087656274137257931639760324708350318503061363031086796994100943084772281097123781070811610760735943618425858558459014484742232019973

然后写脚本解key:

import libnum
from Crypto.PublicKey import RSA
n = 0x726f6f7400000000000000000000000000000000001b000000000000000000000000001ffffb0000000000000000000000001ffffb0000000000000000000000001fffff7777777b00000000000000001ffffffffffffb00000000000000001ffffffffffb0000000000000000001ffffffffffb0000000000000000001ffffffffffffb00000000000000001fffff2222222b00000000000000001ffffb0000000000000000000000001ffffb0000000000000000000000001ffffb0000000000000000000000001ffffb0000000000000000000000001ffffb0000000000000000000000001ffffb0000000000000000000000001ffffb00000000000000265293c4422be3532638feeb2a635e865e5bccd4862d1491f8e46ed41afdab32ab1e913c296c45a723a371cc4ad218d273a494ac501a1c677576b84d3a1700b24e38f3d7c8090c952767f8a9da532eb4496a953fa2b2641f93af58321e491ad6b3e1f6600ea1757635a2d47562dff2f245bfc8ed511420931de246d56334d8897d6465b227f6c095ece1ad994c7551f08dbc21f8b40691ee51f5f72d052d9352062f90b0e7c52c2eb18196c2c985101af4eac67499396c6241ad4f2439ed11f87d67e73a239b865c45d65a61cf0f56082de831b97fb28ae8222a7195e0ec06c08281ffc16e7106e77e68b8c4510424beeb5582fe21cc345f53534682b75c368d73c9
p = 345709341936068338730678003778405323582109317075021198605451259081268526297654818935837545259489748700537817158904946124698593212156185601832821337576558516676594811692389205842412600462658083813048872307642872332289082295535733483056820073388473845450507806559178316793666044371642249466611007764799781626418800031166072773475575269610775901034485376573476373962417949231752698909821646794161147858557311852386822684705642251949742285300552861190676326816587042282505137369676427345123087656274137257931639760324708350318503061363031086796994100943084772281097123781070811610760735943618425858558459014484742232018933
q = 345709341936068338730678003778405323582109317075021198605451259081268526297654818935837545259489748700537817158904946124698593212156185601832821337576558516676594811692389205842412600462658083813048872307642872332289082295535733483056820073388473845450507806559178316793666044371642249466611007764799781626418800031166072773475575269610775901034485376573476373962417949231752698909821646794161147858557311852386822684705642251949742285300552861190676326816587042282505137369676427345123087656274137257931639760324708350318503061363031086796994100943084772281097123781070811610760735943618425858558459014484742232019973
e = 31337

phi = (p - 1) * (q - 1)
d = libnum.invmod(e, phi)
rsa_components = (n, e, d, p, q)
keypair = RSA.construct(rsa_components)
with open("key.pem", "wb") as f:	# 注意这里要是pem格式,不然后面的key可能导不进去
    f.write(keypair.exportKey())

然后去wireshark把文件给导进来

image-20230504162931008

然后重新加载一下(视图里面或者c+R)就可以得到看到加密的数据了
这里是多出来一个http流量:

image-20230504163401852

按照往常的套路来,到处先找找,没有发现什么,尝试跟踪流的时候发现可以跟踪TLS流,于是先试一下

image-20230504163539576

发现一串新东西,整体浏览一下发现后面66,6c,61,67不就是对应hex的flag吗,复制下来解码:

image-20230504163746669

这flag倒是挺长的,这题我觉得就确实有正常CTF题的那种水平了,有点吃综合能力?


之后的题就越来越难了,再来一题:22.说我作弊需要证据

打开流量包,一片的TCP协议,搜flag也没有,但给了个提示

题目来源: ISCC-2017
题目描述:X老师怀疑一些调皮的学生在一次自动化计算机测试中作弊,他使用抓包工具捕获到了Alice和Bob的通信流量。狡猾的Alice和Bob同学好像使用某些加密方式隐藏通信内容,使得X老师无法破解它,也许你有办法帮助X老师。X老师知道Alice的RSA密钥为(n, e) = (0x53a121a11e36d7a84dde3f5d73cf, 0x10001) (192.168.0.13)?,Bob的RSA密钥为(n, e) =(0x99122e61dc7bede74711185598c7, 0x10001) (192.168.0.37)

既然这么明显的告诉你是RSA加密了,那就先按照上一题的解题思路去算算,看能出什么东西:

import libnum
from Crypto.PublicKey import RSA

n1 = 1696206139052948924304948333474767     # (192.168.0.13)
p1 = 38456719616722997
q1 = 44106885765559411

n2 = 3104649130901425335933838103517383     # (192.168.0.37)
p2 = 49662237675630289
q2 = 62515288803124247

e = 65537

phi1 = (p1 - 1) * (q1 - 1)
d1 = libnum.invmod(e, phi1)
rsa_components1 = (n1, e, d1, p1, q1)
keypair1 = RSA.construct(rsa_components1)
with open("key.pem", "wb") as f:
    f.write(keypair1.exportKey())

phi2 = (p2 - 1) * (q2 - 1)
d2 = libnum.invmod(e, phi2)
rsa_components2 = (n2, e, d2, p2, q2)
keypair2 = RSA.construct(rsa_components2)
with open("key.pem", "wb") as f:
    f.write(keypair2.exportKey())

然后放进wireshark中,但并没有什么多出来的东西,然后思路就断了,其实我也知道原因,毕竟这个里面没有一个TLS加密协议,你光有密钥,没有密文怎么解,所以需要换种思路

然后就屁颠屁颠的跑去看风佬视频了,然后就发现流量包里有很多,base64加密的数据

image-20230504200105935

解码看看:

SEQ = 13; DATA = 0x3b04b26a0adada2f67326bb0c5d6L; SIG = 0x2e5ab24f9dc21df406a87de0b3b4L;

多解了几个,发现SEQ是序列号的意思,DATA不用说了就是数据,SIG的话就是签名的意思
有签名,然后是数据,联想到数字签名

简单说明一下就是有两个数据,分别称为公钥和私钥(更正式一点应该被成为公钥签名合私钥签名)

公钥加密的数据只能用私钥解密
私钥加密的数据只能用公钥解密

这就是数字签名加密中的非对称加密

这下思路就清晰很多了,用用公钥和私钥解出密文,然后因为是考试作弊,就简单的理解为对答案了,对的答案一样才是正确的flag,也就是看匹配了

先把所有数据提取出来,随便对着一个TCP流追踪流

image-20230504201118628

把里面的base64全复制出来单独丢到一个文本里,然后用脚本解码一下:

with open("1.txt", "rb") as f:
    a = f.readlines()
    for i in range(len(a)):
        # print(a[i].strip())
        b = base64.b64decode(a[i]).decode()
        print(b)

把结果单独复制到一个文本里,可以看到SEQ序列是乱的,所以还要先进行一下排序,风佬也不会写脚本,这里直接用Excel了,会用是真放便
在SEQ一栏为个位数的项在前面补个0,保持两位数,这样排出来的才对

image-20230504202021646

排序好的也复制到一个文本中

这里的DATA就是Alice用Bob的公钥加密后的密文,然后Bob就可以用SIG私钥解密Alice的密文得到明文
即DATA用Bob的私钥解码,SIG用Alice的公钥解码,如果两个相等就说明传对了答案

脚本:

import re
import libnum

n1 = 1696206139052948924304948333474767     # (192.168.0.13)
p1 = 38456719616722997
q1 = 44106885765559411
n2 = 3104649130901425335933838103517383     # (192.168.0.37)
p2 = 49662237675630289
q2 = 62515288803124247
e = 65537
phi1 = (p1 - 1) * (q1 - 1)
phi2 = (p2 - 1) * (q2 - 1)

d1 = libnum.invmod(e, phi1)
d2 = libnum.invmod(e, phi2)


with open("1.txt", "rb") as f:
    for i in f.readlines():
        # print(i.strip())
        data_re = re.search(rb'DATA = (.*?)L;', i.strip()).group(1).decode()
        # print(data_re)
        sig_re = re.search(rb'SIG = (.*?)L;', i.strip()).group(1).decode()
        # print(sig_re)
        c2 = int(data_re, 16)
        m2 = pow(c2, d2, n2)
        # print(m2)
        m1 = int(sig_re, 16)
        c1 = pow(m1, e, n1)
        # print(c1)
        if m2 == c1:
            print(chr(m2), end="")

这个确实很抽象,刚上手可能确实听不懂,建议有哪个不懂搞做过一个题目后就去总结一下,这样好一些

好了我去总结一下了先


第一期题目

然后的话风佬的基础教学基本就完事了,紧接着的就是题目的实战演练了。然后个人认为吧,这个难度直接飙升,涉及到很多其他的知识,建议做好心理准备,有能力的话还是得去学学web方面的知识,因为流量包这方面很难不和web知识挂钩。
然后的话,毕竟我也算是那种刚学的人,遇到比较难的题心态多少有点难以坚持,也正常,多学多搜嘛

然后的话,因为题目难度加大的原因,有些题我也需要去了解一些知识点,所以肯定更得会比较慢,而且后续每一期的题目应该也会比较少,见谅吧🙏

这一期只有一题,但一题更比三题强


23.traffic

本题涉及到三个知识点:SQL盲注、菜刀流量、冰蝎流量

是不是看到题目所属知识点就有些懵了?很正常因为我也是这样,顶多也是听实验室学长提过几嘴
没办法慢慢来吧

打开压缩包,然后就是一坨绿绿的http和tcp协议甩你脸上
无所谓,总之既然这么多的话,先看看http请求,的确比较多,所以统计会比较慢,一分多钟的样子?

image-20230519163950549

一打开来就是厚礼蟹,还真是一坨直接飞你脸上来了,玩笑归玩笑,该注意的还是要注意一下
发现里面都带有一些关键词,sql_blind但凡会点英语的应该就知道这是SQL盲注了

讲一下最简单的定义:

SQL注入:将用户输入的内容当成代码执行了
盲注:没有任何错误回显消息的情况下,通过SQL查询逐渐推断出数据库中的敏感信息

总之知道是一个一个一个推出来的就行了,具体如果还想了解的话,还是放个别人的传送门在这里吧

在简单的浏览过后不难发现,这一堆盲注里面有一些带有flag字符的查询。大抵那一串就是有关flag的盲注了

image-20230519165839413

另外,建议还是不要找到一个线索了就先去埋头干这一个,你这http全部的请求还没看完呢,总之还是先看看下面有什么东西,没东西了再去埋头干也不迟

image-20230519170356730

在文件的最后看到几个可以的php文件,先记着

然后的话,直接先过滤到http流量,找到刚刚看见flag的那里
先看看具体长什么样,URL解码之后

image-20230519192305110

比如上面这一串就是指向了51,对应的ASCII码是3
毕竟要看所有的,总之先把流量包包含flag的全部打印出来看看

import urllib.parse

a1 = []
with open("traffic.pcapng", "rb") as f:
    for i in f.readlines():
        tmp = urllib.parse.unquote(i.strip())		# 这里是URL解码
        if "flag" in tmp:
            a1.append(tmp)
for i in range(len(a1)):
    print(a1[i])

仔细观察会发现包含AND 'BIoz'='BIoz&Submit=Submit HTTP/1.1这一串字符串的项中,盲注了有28个字符,比较符合flag的长度格式

image-20230519194215895

所以在上面的脚本中改进一下把包含那一串字符串的项提出来看看

import urllib.parse

a1 = []
with open("traffic.pcapng", "rb") as f:
    for i in f.readlines():
        tmp = urllib.parse.unquote(i.strip())
        if "AND 'BIoz'='BIoz&Submit=Submit HTTP/1.1" in tmp:
            a1.append(tmp)
for i in range(len(a1)):
    print(a1[i])

先看看flag的格式:

image-20230519195222560

然后去新生成的字符串中去找找这些flag对应字符出现的位置
分别在第6条,第11条,第19条,第25条,第31条
空看确实看不出什么共同特征,去流量包中找到对应的http协议看看发送包和返回包
发现它们共同的特征是返回包的Content-Length项都是5201

image-20230519200621945

为了验证这一猜想,把上面每一个协议的返回包中的Content-Length项也都提取出来,改进一下脚本:

import urllib.parse

a1 = []
with open("traffic.pcapng", "rb") as f:
    for i in f.readlines():
        tmp = urllib.parse.unquote(i.strip())
        if "AND 'BIoz'='BIoz&Submit=Submit HTTP/1.1" in tmp or "Content-Length" in tmp:
            a1.append(tmp)
for i in range(len(a1)):
    print(a1[i])

image-20230519200816537

发现确实是这样的,但是好像同为5201的也有其他的非flag的部分,再小观察一下,发现是盲注每个字符的最后一个5201

image-20230519201407961

这样就好办了,人懒的话可以直接手搓出来,即flag对应每个盲注字符中Content-Length项为5201的最后一项

我就是属于懒人的那一种,毕竟写脚本的能力还有待加强,没怎么写过流量包的脚本,这里贴一下风佬的脚本吧(我小改过一点,感觉这样好理解一些)

import re
import urllib
import urllib.parse

# 打印出flag的可疑相关项
a1 = []
with open("traffic.pcapng", "rb") as f:
    for i in f.readlines():
        tmp = urllib.parse.unquote(i.strip())
        if "AND 'BIoz'='BIoz&Submit=Submit HTTP/1.1" in tmp or "Content-Length" in tmp:
            a1.append(tmp)
for i in range(len(a1)):
    print(a1[i])
print("------------------------------------")

# 把两项合成为一项,便于后续正则匹配操作
a2 = []
for i in range(len(a1)):
    if "flag" in a1[i]:
        a2.append(a1[i] + a1[i + 1])
for i in range(len(a2)):
    print(a2[i])
print("------------------------------------")

# 正则匹配搜索关键字符并打印出来
a3 = {}
for i in a2:
    f = re.search(r"(\d+),1\)\)>(\d+) AND 'BIoz'='BIoz&Submit=Submit HTTP/1.1Content-Length: (\d+)", i)
    print(f[1], f[2], f[3])
    if f[3] == "5201":
        a3[f[1]] = f[2]
print("------------------------------------")

# 根据规则打印flag
flag = ""
for i in range(1, 28):
    flag += chr(int(a3[str(i)]))
print(flag)

得到一个flag:flag{fakeflag2333333333333}
心脏骤停,忙活半天是个假flag,所以我说做这题需要一个强大的心态


调整一下,既然盲注没有的话还记得之前那个几下来的可疑php文件吗,就是这个时候用的了
翻翻找找:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gPRfELl6-1684503294735)(null)]

发现一个可疑压缩包,先去前面的发送包里面看看

image-20230519203352968

把这一串显示分组字节流,然后解码看看:

666=@eval(@base64_decode($_POST[i9b0bda93fc2d1]));
&i9b0bda93fc2d1=@ini_set("display_errors", "0");
@set_time_limit(0);
function asenc($out) {
	return $out;
};
function asoutput() {
	$output=ob_get_contents();
	ob_end_clean();
	echo "d4b800";
	echo @asenc($output);
	echo "e3714f0abcdd";
}
ob_start();
try {
	$F=base64_decode(get_magic_quotes_gpc()?stripslashes($_POST["n01133279493be"]):$_POST["n01133279493be"]);
	$fp=@fopen($F,"r");
	if(@fgetc($fp)) {
		@fclose($fp);
		@readfile($F);
	} else {
		echo("ERROR:// Can Not Read");
	};
}
catch(Exception $e) {
	echo "ERROR://".$e->getMessage();
};
asoutput();
die();
&n01133279493be=C:/phpstudy/WWW/DVWA/hackable/uploads/flag.zip

稍微美化了一下,很明显最后有个flag.zip那么返回包里面的那个zip应该就是个flag了,直接导出分组字节流
打开的时候却发现不能打开,拖到010里面看看

image-20230519204126536

下面的提示6位先记下来,这里的话是zip文件头损坏的原因,建议自己压一个6位密码的zip把两个自拍对比一下就知道怎么修改损坏文件头了

image-20230519204513326

image-20230519204634660

然后就可疑正常打开了

image-20230519204712557

经典加密压缩包,既然说了是6位密码,所以就开始无脑爆破
出来密码是123456

image-20230519204846895

hh,也是假的,然后还提示一个冰蝎,那么就是上面说的最后一个知识点冰蝎流量了

还是回流量包继续看,老实说看这么多边确实有些倦了,但没办法,人活着不是在受苦就是在受苦的路上,继续吧


现在的话http流量就只剩下最后一点了,希望能出东西
依旧是翻翻找找:

image-20230519211835261

这里是直接给出了冰蝎流量的密码了:84319025cf3bd993

至于数据的话,应该就是下面发送包里卖弄POST的数据了,因为之前就下好了风佬解冰蝎流量的工具,所以解起来还是很顺利的,这里就不卖关子了,正确的流量在倒数第二个

image-20230519212318823

这里异或解密,出来的base64解密后会发现最后有个7z,再次base64解码看看:

image-20230519212432217

最终得到flag:flag{ne7WORK_traffIc_i5_int3r3sing_1433223}
也总算是得到flag了,一题更比三题强,前提是你坚持得下来,老实说这个应该还不算比较难的流量包,单个考点算是比较简单的,而且一眼就能看得出考点。那种难的流量包你一眼是看不出考点的,这题就这样了,确实涉及到比较多的web知识,建议好好整理一下,有时间的可以具体去学一下,这里就不具体指路了吧,因为这些相关知识的文章可太多了,我也不知道哪些文章比较好

这一期就这样吧,还是那句话,学也是要时间的捏,要真正理解一个题目中的所有知识点是真不容易(叹气)
感谢支持,并感谢有耐心看到这里🙏

顺便贴个图放这里应该没事吧,小小的奖励(◠ڼ◠)

在这里插入图片描述

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值