这次hgame几乎都是靠写一些脚本跑出几道简单的密码题来得分,想学习web却无从下手;
Web
easy_auth
查看wp才会
这是关于鉴权方面的问题。
鉴权(authentication)是指验证用户是否拥有访问系统的权利。传统的鉴权是通过密码来验证的。这种方式的前提是,每个获得密码的用户都已经被授权。在建立用户时,就为此用户分配一个密码,用户的密码可以由管理员指定,也可以由用户自行申请。这种方式的弱点十分明显:一旦密码被偷或用户遗失密码,情况就会十分麻烦,需要管理员对用户密码进行重新修改,而修改密码之前还要人工验证用户的合法身份。
为了克服这种鉴权方式的缺点,需要一个更加可靠的鉴权方式。目前的主流鉴权方式是利用认证授权来验证数字签名的正确与否。
逻辑上,授权发生在鉴权之后,而实际上,这两者常常是一个过程。
我们常用的鉴权有四种:
1、HTTP Basic Authentication
2、session-cookie
3、Token 验证
4、OAuth(开放授权)
这题是用的Token 验证
认证过程:
- 用户输入登陆凭据;
- 服务器验证凭据是否正确,然后返回一个经过签名的token;
- 客户端负责存储token,可以存在localstorage,或者cookie中
- 对服务器的请求带上这个token;
- 服务器对JWT进行解码,如果token有效,则处理该请求;
- 一旦用户登出,客户端销毁token。
我们先找到必需的token之后在对他进行JWT解码
需要密码的部分清空,这题不需要密码
利用题目已知的admin,猜测ID,得到flag的token
替换原来的token,不用多久就会显现flag
蛛蛛…嘿嘿♥我的蛛蛛
爬虫爬
这里用正则更快一点
payload
1 | import requests |
webpack-engine
JavaScript脚本正变得越来越复杂。大部分源码(尤其是各种函数库和框架)都要经过转换,才能投入生产环境。
常见的源码转换,主要是以下三种情况:
1)压缩,减小体积。比如jQuery 1.9的源码,压缩前是252KB,压缩后是32KB。
2)多个文件合并,减少HTTP请求数。
3)其他语言编译成JavaScript。最常见的例子就是CoffeeScript。
jQuery 1.9压缩后只有3行,每行3万个字符,所有内部变量都改了名字。你看着报错信息,感到毫无头绪,根本不知道它所对应的原始位置。
这就是Source map想要解决的问题。
简单说,Source map就是一个信息文件,里面储存着位置信息。也就是说,转换后的代码的每一个位置,所对应的转换前的位置。
有了它,出错的时候,除错工具将直接显示原始代码,而不是转换后的代码。这无疑给开发者带来了很大方便。
目前,暂时只有Chrome浏览器支持这个功能
如何使用Source map呢?其实只要在转换后的代码尾部,加上一行就可以了。
1 | //@ sourceMappingURL=/path/to/file.js.map |
map文件可以放在网络上,也可以放在本地文件系统。
Source map的格式,它大概是这个样子:
1 | { |
那么回到正文,这题我们提示用Chrome打开去看看。
发现源文件里多出一个文件夹,这是webpack打包js时开启了sourcemap,而chrome又还原了源码
两次base64解码后得到: hgame{D0nt_f0r9et_2_ClOs3_S0urce_m@p}
Crypto
Easy RSA
源码
1 | from math import gcd |
这题其实很好理解,就是要我们求出被encrypt()函数加密的flag
payload
1 | from math import gcd |
RSA Attack
源码
1 | from Crypto.Util.number import getPrime |
yafu分解大数n
payload
1 | import gmpy2 |
RSA Attack2
1 | import re |
output
1 | # task1 |
payload
1 | import gmpy2 |
在此普及一下
低加密指数分解攻击
e=2把密文c开平方求解
RSA加密,由于e只有2,相当于把明文m平方而已,得到的c也比n小很多。尝试把c开根号看能否得到明文。一般的python开根号方法精度较低,对大整数开出来的根号准确度低。发现使用gmpy2库可以对大整数开根号。iroot
e=2 Rabin加密中的N可被分解
e==2,并不都是Rabin加密,但是e==2是Rabin加密典型特征
共模攻击
明文m、模数n相同,公钥指数e、密文c不同,gcd(e1,e2)==1
对同一明文的多次加密使用相同的模数和不同的公钥指数可能导致共模攻击。
Multi Prime RSA
源码
1 | from Crypto.Util.number import getPrime |
e太大 可使用算法从e中快速推断出d的值。 可使用Wiener’s Attack进行解d
求出d可直接求m
在此贴一个维纳攻击的脚本
1 | import ContinuedFractions, Arithmetic, RSAvulnerableKeyGenerator |
ECC
在网安数学的教材上看到过椭圆曲线加密,海量的公式+复杂的绘图。嗯,这一定很BT
这道题的源码如下
1 | from Crypto.Util.number import getPrime |
真真看不懂,去百度也都是比这道题更难理解的,实在是难以入门;
搜罗到一些ECC的原理,可以看一下。
找出两个“很大”的质数:P & Q
N = P * Q
M = (P – 1) * (Q – 1)
找出整数E,E与M互质,即除了1之外,没有其他公约数
找出整数D,使得 ED 除以 M 余 1,即 (E D) % M = 1,等价于ED-1=KM
经过上述准备工作之后,可以得到:
E是公钥,负责加密
D是私钥,负责解密
N负责公钥和私钥之间的联系
加密算法,假定对X进行加密
(X ^ E) % N = Y
解密算法,根据费尔马小定义,可以使用以下公式完成解密
(Y ^ D) % N = X
简单而言,椭圆曲线是基于解决离散问题的算法;给定K和G,算出k。(点G称为基点,K=kG [其中 K,G为Ep(a,b)上的点,k为小于n(n是点G的阶)的整数])
1、用户A选定一条椭圆曲线Ep(a,b),并取椭圆曲线上一点,作为基点G。
2、用户A选择一个私有密钥k,并生成公开密钥K=kG。
3、用户A将Ep(a,b)和点K,G传给用户B。
4、用户B接到信息后 ,将待传输的明文编码到Ep(a,b)上一点M(编码方法很多,这里不作讨论),并产生一个随机整数r。
5、用户B计算点C1=M+rK;C2=rG。
6、用户B将C1、C2传给用户A。
7、用户A接到信息后,计算C1-kC2,结果就是点M。因为 C1-kC2=M+rK-k(rG)=M+rK-r(kG)=M
再对点M进行解码就可以得到明文。
在这个加密通信中,如果有一个偷窥者H ,他只能看到Ep(a,b)、K、G、C1、C2,而通过K、G 求k 或通过C2、G求r 都是相对困难的,因此,H无法得到A、B间传送的明文信息。
等待wp后
payload:
1 | from libnum import n2s |