2022DASCTF x SU-Re-login(Socket&RSA&Hill&AES)
前言
就是想复现
前置知识
前置知识就是这一张图,我们的两个文件一个是客户端一个是服务器端,check应该是服务器端。
代码的复原
我们看了上面的图,可以基本判定,服务器端就是check,猜测客户端的就是应该为输入数值,然后传输到TCP端进行一个check
我们将两个文件都进行一个反编译
我们先分析check,先根据start找到main函数,进行一个重命名
因为这个是一个静态链接的东西,一些函数都是作者自己写的
我们跟进函数然后去看看:
这些肯定不是作者自己去写的函数,是socket协议的一个东西,然后我们回去看刚才我们的那个流程图
然后我们往后看
发现了这样的一个函数,正对应了上面的流程图的东西,
我们就根据这个流程图去重命名一下这个函数中的流程
大概就是这样,然后我们就同理复原一下login
恢复结构体
我们可以知道在socket中,有个这样的东西
int bind(int sock, struct sockaddr *addr, socklen_t addrlen);
其中有一个结构体struct sockaddr *addr,sockaddr 结构体变量的指针存储的是我们需要传输的一些信息
但是我们的ida并不知道这个结构体在哪需要我们去手动恢复一下这个结构体
修复了之后我们可以看到有些东西就十分明了了
动态调试分析socket
在动调的时候我们发现,会在这个地方强制退出,敲
(由于太菜了我去请教了一下大佬。
是因为在sin_port的地方有一个反调试,解决方法就是在remote调试的端口中,把端口改成本地存在的地方,我们通过调试的找到本地的端口。我们在上一个端口上看到了socket port端口我们跟进去看一下
port是1234
然后我们将调试的端口整成1234
这样的话我们就可以连上继续调试了
下面就可以正常的通过了bin这个检测
我们继续往下调试,一直到接受的那里
到这里我们调试不动了,这个时候我们就应该去运行我们的login文件了
然后可以继续往下调试
这里让我们输入一个token,我们先随便输入一个1234
又有密码,同样是输入1234
然后输入错了哈哈哈
然后我们发现了一处奇特的地方
像这两句话,是存在于check文件中的,而这里室友login打印出来的,所以说这样的交互就是,一句话利用socket将这句话打印出来,然后输入出入给check进行一个检查,大概就是这一个工作流程。我们也就可以通过一个这样的工作流程去逆向。
逆向获得token和passwd
我们linkstar的函数里面分析出来的函数为
我们在进入到第三个if的时候,只要是我们不让程序输出v20,那么我们就成功了
那么我们就要通过这个检测。
然后我们去看login中,同理恢复一下login的函数,大概就是这个样子。
然后的话我们就需要双线程的进行分析了。
然后到了下面,就是接受一个数据然后发送给服务器端
那这个就是第一次输入的一个token,同理也是这么接受的passwd
然后我们就是跟进刚才的那个判断。
我们先分析token_check
这里应该是一种加密,但是不知道是什么emmm,,,我们发现了10001,10001容易让我想到rsa确实,搜一下就RSA,那么我们就可以整一下进行一个加密。
然后我们进行一个rsa的解密
在线网站分解一下n
有脚本
import gmpy2
n = 13123058934861171416713230498081453101147538789122070079961388806126697916963123413431108069961369055630747412550900239402710827847917960870358653962948282381351741121884528399369764530446509936240262290248305226552117100584726616255292963971141510518678552679033220315246377746270515853987903184512948801397452104554589803725619076066339968999308910127885089547678968793196148780382182445270838659078189316664538631875879022325427220682805580410213245364855569367702919157881367085677283124732874621569379901272662162025780608669577546548333274766058755786449491277002349918598971841605936268030140638579388226573929
p = 98197216341757567488149177586991336976901080454854408243068885480633972200382596026756300968618883148721598031574296054706280190113587145906781375704611841087782526897314537785060868780928063942914187241017272444601926795083433477673935377466676026146695321415853502288291409333200661670651818749836420808033
q = 133639826298015917901017908376475546339925646165363264658181838203059432536492968144231040597990919971381628901127402671873954769629458944972912180415794436700950304720548263026421362847590283353425105178540468631051824814390421486132775876582962969734956410033443729557703719598998956317920674659744121941513
e = 0x10001
phi = (q-1)*(p-1)
c = b'By reading we enrich the mind, by conversation we polish it.'
c = int.from_bytes(c,'little')
d = gmpy2.invert(e,phi)
m = gmpy2.powmod(c,d,n)
print(m)
#11963777321199993924175387978397443935563034091716786597947508874393819454915798980986262132792605021295930274531653741552766395859285325677395421549163602968276475448835066393456449574469736327622969755801884982386140722904578598391534204834007447860153096480268812700725451958035204357033892179559153729604237187552716580637492579876006993181920209114166153317182827927606249871955662032809256743464460825303610341043145126848787575238499023185150429072724679210155061579052743238859739734301162335989939278904459012917375108407803445722785027315562371588439877746983153339473213449448259686486917983129418859935686
这样是得出了token。
再看passwd_check
是一个hill加密,套板子解出就可以了吼吼。
5132d202c32d95b9f978d514e3294220513b15623482b4c02e9afde8bad5ec07486a5488
这样的话我们就通过了检测
然后才来到了flag的检测。
逆向出flag
大概之后是从这里面开始,接受一串数据,就是我们输入的flag,我们发下这边只有一个接受,之前并没有send什么东西,这就是意味着在login中有一个特殊的发送
我们分析login发现在login中有一个发送
发送了一个这个东西
那么我们接受了这串数据之后就存放进了这个全局变量里面
我们再来看4058D8这个函数,跟进
分析可知,这个就是将我们得到的数据转换成数组的作用
我们上百度搜一下
这就是AES了呗哈哈哈哈。
然后我们需要找到检验的密文,那我们就知道这个函数是一个AES加密
十分生猛的AES加密,所以这里面也是比较复杂的需要分析。
分析省略,过程太复杂了呜呜呜。
最后得到的flag为
7026271d7bb5d404d63a72b88e6b4d63