DASCTF_Login
Login
这道题里面给了两个文件,一个作为了客户端,一个作为服务器,两个程序之间相互传输数据,对登录的token、password以及verify这三个数进行了验证。
验证的主逻辑是在check程序之中,这里有三中加密(RSA、Hill、AES),这次的AES进行了魔改,解密的脚本不得不自己来码代码!!
两个程序的交互
提供了两个文件,一个文佳时客户端界面,一个时服务器界面,要实现两个页面的交互
打开的是两个程序,一个程序作为的是客户端(login),一个作为的是服务器(check)
在这两个程序之中找到start函数,然后打开第一个参数,就是main函数
login程序:
- 和服务器进行一系列的交互
- 一个while循环向服务器发送和接受消息
- 其中的if语句会根据接受到的参数,来做出特定的反应
连接服务器:
客户端和服务器间的交互:
if语句发送数据:
客户端:
连接客户端:
进入main函数之中,和客户端进行交互,验证三个数据
rsa解密
大素数:
1 | 13123058934861171416713230498081453101147538789122070079961388806126697916963123413431108069961369055630747412550900239402710827847917960870358653962948282381351741121884528399369764530446509936240262290248305226552117100584726616255292963971141510518678552679033220315246377746270515853987903184512948801397452104554589803725619076066339968999308910127885089547678968793196148780382182445270838659078189316664538631875879022325427220682805580410213245364855569367702919157881367085677283124732874621569379901272662162025780608669577546548333274766058755786449491277002349918598971841605936268030140638579388226573929 |
分解的质数:
1 | p = 98197216341757567488149177586991336976901080454854408243068885480633972200382596026756300968618883148721598031574296054706280190113587145906781375704611841087782526897314537785060868780928063942914187241017272444601926795083433477673935377466676026146695321415853502288291409333200661670651818749836420808033 |
密文:
1 | c = 0x2e7469206873696c6f70206577206e6f697461737265766e6f63207962202c646e696d2065687420686369726e6520657720676e6964616572207942 |
解密脚本:
1 | import gmpy2 |
明文:
1 | token = 11963777321199993924175387978397443935563034091716786597947508874393819454915798980986262132792605021295930274531653741552766395859285325677395421549163602968276475448835066393456449574469736327622969755801884982386140722904578598391534204834007447860153096480268812700725451958035204357033892179559153729604237187552716580637492579876006993181920209114166153317182827927606249871955662032809256743464460825303610341043145126848787575238499023185150429072724679210155061579052743238859739734301162335989939278904459012917375108407803445722785027315562371588439877746983153339473213449448259686486917983129418859935686 |
hill解密
密钥矩阵:
1 | 0xA34C0F7A2E25DB71,0x7AA91B6E29AA226A,0x56AA0EF0802F278A,0x9AF6F2A9005859F7,0xC9481C4E |
密文随机数(GF(255)):
1 | 1804289383,846930886,1681692777,1714636915,1957747793,424238335,719885386,1649760492,596516649,1189641421,1025202362,1350490027,783368690,1102520059,2044897763,1967513926,1365180540,1540383426,304089172,1303455736,35005211,521595368,294702567,1726956429,336465782,861021530,278722862,233665123,2145174067,468703135,1101513929,1801979802,1315634022,635723058,1369133069,1125898167,1059961393,2089018456,628175011,1656478042,1131176229,1653377373,859484421,1914544919,608413784,756898537,1734575198,1973594324,149798315,2038664370,1129566413,184803526,412776091,1424268980,1911759956,749241873,137806862,42999170,982906996,135497281,511702305,2084420925,1937477084,1827336327,572660336,1159126505,805750846,1632621729,1100661313,1433925857,1141616124,84353895,939819582,2001100545,1998898814,1548233367,610515434,1585990364,1374344043,760313750,1477171087,356426808,945117276,1889947178,1780695788,709393584,491705403,1918502651,752392754,1474612399,2053999932,1264095060,1411549676,1843993368,943947739,1984210012,855636226,1749698586,1469348094,1956297539 |
密文矩阵:
1 | [[0xa3,0x97,0xa2,0x55,0x53,0xbe],[0xf1,0xfc,0xf9,0x79,0x6b,0x52],[0x14,0x13,0xe9,0xe2,0x2d,0x51],[0x8e,0x1f,0x56,0x08,0x57,0x27],[0xa7,0x05,0xd4,0xd0,0x52,0x82],[0x77,0x75,0x1b,0x99,0x4a,0xed]] |
使用sage解矩阵的乘法运算
问题:这个函数的作用为什么是将输入的password(明文)转换成array形式
计算得到数据:
1 | [ 81 50 210 2 195 45] |
将上面的token和login的数据输入之后登录成功:
运行调试两个程序
如果需要动调:
ida之中动调的对象是服务器端口:
在Linux之中 使用./linux_server64 -p 1234 监听1234端口
在ida之中设置的端口号也应该是1234
在Linux之中运行一下这两个程序
先将服务端运行起来 ./check
然后将客户端运行起来 ./login 127.0.0.1 // 因为服务端是在本地运行的,所以ip address 就是127.0.0.1
客户端需要输入ip address
AES解密
魔改的部分:
- S盒子和逆S盒交换着使用了
- 密钥扩展中异或的部分魔改了
- 在进入加密器之前进行了和IV向量的异或运算
这里面数据提取和处理的方法也要注意
S盒
S盒的生成:S盒的大小规格是16*16 = 256的
客户端接受到的数据是:
1 | 52096ad53036a538bf40a39e81f3d7fb7ce339829b2fff87348e4344c4dee9cb547b9432a6c2233dee4c950b42fac34e082ea16628d924b2765ba2496d8bd12572f8f66486689816d4a45ccc5d65b6926c704850fdedb9da5e154657a78d9d8490d8ab008cbcd30af7e45805b8b34506d02c1e8fca3f0f02c1afbd0301138a6b3a9111414f67dcea97f2cfcef0b4e67396ac7422e7ad3585e2f937e81c75df6e47f11a711d29c5896fb7620eaa18be1bfc563e4bc6d279209adbc0fe78cd5af41fdda8338807c731b11210592780ec5f60517fa919b54a0d2de57a9f93c99cefa0e03b4dae2af5b0c8ebbb3c83539961172b047eba77d626e169146355210c7d |
利用接受到的数据生成S盒
1 | 0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38,0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb,0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87,0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb,0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d,0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e,0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2,0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25,0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16,0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92,0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda,0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84,0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a,0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06,0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02,0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b,0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea,0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73,0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85,0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e,0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89,0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b,0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20,0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4,0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31,0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f,0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d,0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef,0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0,0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61,0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26,0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d |
pass_token的获取
token的数组数据:(按照char的类型来取值)
1 | token = "11963777321199993924175387978397443935563034091716786597947508874393819454915798980986262132792605021295930274531653741552766395859285325677395421549163602968276475448835066393456449574469736327622969755801884982386140722904578598391534204834007447860153096480268812700725451958035204357033892179559153729604237187552716580637492579876006993181920209114166153317182827927606249871955662032809256743464460825303610341043145126848787575238499023185150429072724679210155061579052743238859739734301162335989939278904459012917375108407803445722785027315562371588439877746983153339473213449448259686486917983129418859935686" |
pass的数组数据:
1 | 0x51,0x32,0xd2,0x02,0xc3,0x2d,0x95,0xb9,0xf9,0x78,0xd5,0x14,0xe3,0x29,0x42,0x20,0x51,0x3b,0x15,0x62,0x34,0x82,0xb4,0xc0,0x2e,0x9a,0xfd,0xe8,0xba,0xd5,0xec,0x07,0x48,0x6a,0x54,0x88 |
随机数:
1 | 1804289383,846930886,1681692777,1714636915,1957747793,424238335,719885386,1649760492,596516649,1189641421,1025202362,1350490027,783368690,1102520059,2044897763,1967513926,1365180540,1540383426,304089172,1303455736,35005211,521595368,294702567,1726956429,336465782,861021530,278722862,233665123,2145174067,468703135,1101513929,1801979802,1315634022,635723058,1369133069,1125898167,1059961393,2089018456,628175011,1656478042,1131176229,1653377373,859484421,1914544919,608413784,756898537,1734575198,1973594324,149798315,2038664370,1129566413,184803526,412776091,1424268980,1911759956,749241873,137806862,42999170,982906996,135497281,511702305,2084420925,1937477084,1827336327,572660336,1159126505,805750846,1632621729,1100661313,1433925857,1141616124,84353895,939819582,2001100545,1998898814,1548233367,610515434,1585990364,1374344043,760313750,1477171087,356426808,945117276,1889947178,1780695788,709393584,491705403,1918502651,752392754,1474612399,2053999932,1264095060,1411549676,1843993368,943947739,1984210012,855636226,1749698586,1469348094,1956297539 |
生成pass_token:(IV和密钥)这里的随机数使用的是第36个随机数之后的数,因为在程序的前面生成过一次36个随机数。
1 | token = "11963777321199993924175387978397443935563034091716786597947508874393819454915798980986262132792605021295930274531653741552766395859285325677395421549163602968276475448835066393456449574469736327622969755801884982386140722904578598391534204834007447860153096480268812700725451958035204357033892179559153729604237187552716580637492579876006993181920209114166153317182827927606249871955662032809256743464460825303610341043145126848787575238499023185150429072724679210155061579052743238859739734301162335989939278904459012917375108407803445722785027315562371588439877746983153339473213449448259686486917983129418859935686" |
密钥扩展和逆S盒
这里和常规的AES的密钥扩展是进行了魔改的(对比常规的AES加密的代码就能知道,密钥扩展这部分的代码需要自己写)
生成SBox的逆矩阵:
1 | revSBox = [ |
1 | // 进行密钥扩展 |
CBC模式的初始化向量的IV
作为IV的pass_token的后16*2个字节,每次使用16个字节
密文:
1 | c ={0xfe,0xf9,0xe7,0x3e,0xf6,0xa1,0x23,0xcc,0x57,0x61,0xc1,0x15,0x77,0xfb,0x9c,0xbb,0xca,0x2f,0xb1,0xe8,0x4f,0xd9,0x07,0xd8,0x0c,0x6b,0xea,0xcf,0xe8,0x42,0xa2,0xfa} |
1 | // 加密过程第一步的异或运算(但是里面的数据还需要思考一下) 传入的参数是数据加密的轮数 |
AES加密的主逻辑
字节代换
这里用的S盒是revDate(SBox)
逆字节代换(要用revSBox)
1 | // 逆字节代换() |
行移位
行移位操作:
行移位的逆运算:
1 | // 行移位的逆运算 第一行不移动 第二行循环右移1位 |
列混合
列混合:
用到的矩阵(4*4)
1 | 0x02, 0x03, 0x01, 0x01, |
GF之中的运算:
逆列混合使用到的矩阵:
1 | 0xe, 0xb, 0xd, 0x9, |
逆列混合:
1 | // 列混合 |
轮密钥加
轮密钥加:
在10轮加密之前会使用一个拓展密钥(进行一次轮密钥加)
10轮加密之中每一轮会用一个拓展密钥
10轮加密之后会使用一个拓展密钥
逆轮密钥加:
1 | // 轮密钥加(传入的参数是每一轮使用的密钥的第一个数的索引) |
AES解密脚本
AES解密脚本:
1 |
|
所以flag是 DASCTF{7026271d7bb5d404d63a72b88e6b4d63}