Schwarz 发表于 2023-6-3 22:28

【js逆向】某习通座位预约加密分析(新手向)

本帖最后由 Schwarz 于 2023-10-20 00:16 编辑



---
## 应要求更新完整代码,有些地方需要更改

```python
import requests
import requests.utils
from lxml import etree
import re
from Crypto.Cipher import AES
from Crypto.Hash import MD5
import base64
from datetime import datetime
from fake_useragent import UserAgent
import time

# 登录的加密函数
def encrpytByAES(message, key):
    key = "u2oh6Vu^HWe4_AES"
    iv = key.encode("utf-8")
    message = message.encode("utf-8")

    # 使用PKCS7Padding填充
    BS = AES.block_size
    padding = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS).encode()
    cipher = AES.new(iv, AES.MODE_CBC, iv)
    ciphertext = cipher.encrypt(padding(message))
    return base64.b64encode(ciphertext).decode('utf-8')


# 使用session保存cookies
def getCookies(data, headers):
    url = "https://passport2.chaoxing.com/fanyalogin"
    # proxy = {"http": "http://127.0.0.1:8080"}
    resp = requests.session()
    resp.headers = headers
    resp.post(url, data=data)
    url1 = "https://office.chaoxing.com/front/apps/seatengine/index?seatId=xxx" # 自己的seatId
    resp.get(url=url1)
    return resp


def getToken(session, today):
    # proxy = {"http": "http://127.0.0.1:8080"}
    url = f"http://office.chaoxing.com/front/third/apps/seatengine/select?id=1901&day={today}&backLevel=2&seatId=796"
    resp = session.get(url)
    res = etree.HTML(resp.text)
    script = res.xpath('/html/body/script/text()')
    pattern = re.compile("token = '(?P<token>.*?)'")
    token = pattern.search(script)
    if token:
      token = token.group('token')
      return token
    else:
      return None


def getSeat(sess, roomId, startTime, endTime, day, seatNum, token, enc):
    # proxy = {"http": "http://127.0.0.1:8080"}
    seatNum1 = str(seatNum).rjust(3, '0')
    url = f'http://office.chaoxing.com/data/apps/seatengine/submit?roomId={roomId}&startTime={startTime}&endTime={endTime}&day={day}&captcha=&seatNum={seatNum1}&token={token}&enc={enc}'
    resp = sess.get(url)
    print(resp.text)


def getData(info):
    data = {
      'fid': '-1',
      'uname': encrpytByAES(info, 0),
      'password': encrpytByAES(info, 0),
      'refer': 'https://office.chaoxing.com/front/apps/seatengine/index?seatId=xxx', # 填写自己的
      't': 'true',
      'forbidotherlogin': '0',
      'validate': '',
      'doubleFactorLogin': '0',
      'independentId': '0'
    }
    return data


def getEnc(today, endTime, seatNum, startTime, token, roomId):
    content = "[%sd`~7^/>N4!Q#){kuohao}'']".format(
      today, endTime, roomId, seatNum, startTime, token, kuohao="{")
    result = MD5.new()
    result.update(content.encode('utf-8'))
    return result.hexdigest()


def main():
    ua = UserAgent()
    ua = ua.random
    headers = {
      'user-agent': ua
    }

    info = [['姓名(可写可不写)', '手机号', '密码']] # 登录信息

    # 获取data
    mdata = getData(info)

    # 获取session
    msession = getCookies(mdata, headers)

    today = datetime.now().strftime('%Y-%m-%d')

    # 获取必要的token
    mtoken = getToken(msession, today)

    # enc获取
    roomId = "1901"

    ct = []# session,座位号,开始时间,结束时间,token,roomId

    # 添加enc
    for item in ct:
      seatNum = str(item).rjust(3, '0')# 传入的座位号为0xx
      startTime = item
      endTime = item
      token = item
      roomId = item
      item.append(getEnc(today, endTime, seatNum, startTime, token, roomId))

    while True:
      t = datetime.now().strftime("%H:%M:%S")
      if t:
            print(datetime.now())
            for session, seatNum, startTime, endTime, token, roomId, enc in ct:
                getSeat(session, roomId, startTime, endTime, today, seatNum, token, enc)
            print(datetime.now())
            break
      else:
            time.sleep(0.2)


if __name__ == '__main__':
    try:
      main()
    except Exception as e:
      print(e)
# 44 7 * * * /home/ubuntu/chaoxing.py >> /home/ubuntu/script.log

```

# 前言
之前写过图书馆预约抢座,那个时候虽然有加密参数,但是没有校验加密,就放在服务器上自动运行,但是突然有一天开始校验,导致有一天差点没地方学习

作为一个懒货和考研党,怎么可能忍?为了我宿舍里的儿子们不用早起蹲点抢位置,于是乎开始下面的逆向旅途

**本人是个新手,虽然以前是web渗透的,但是对js逆向并不熟悉,如果有什么说的不对的地方请各位斧正**

# 目标
学某通图书馆座位预约系统
每个学校不同可能参数也不同,下面是个样例

*选座界面*:
https://office.xxxx.com/front/third/apps/seatengine/select?id=xxxx&day=2023-06-03&backLevel=2&seatId=xxx

# 过程
打开选座界面,刚F12打开调试界面就发现有反调试,直接两个一律不在此处暂停



首先提交一次预约请求,很明显,以下请求就是这次逆向的主体


https://office.xxxx.com/data/apps/seatengine/submit?roomId=1901&startTime=18%3A30&endTime=19%3A00&day=2023-06-03&captcha=&seatNum=022&token=818a0f43a1a64bc98acb3f572fb64336&enc=4e66e0f4a1f3db313ad08288b9c379da

经过小小的测试,token在进入页面就自带,直接爬取网页源代码就可以获得,所以主要的目标是`enc`
首先通过xhr提取断点


当我们断上点了,准备在调用栈一层一层往前找参数来源


看到传递的参数,但还要往前找到来源


很明显这是混淆的一个函数,后面传的参数是所有其他参数字段,大概率enc就是来源于这里


找一下这个函数的来源,点击直接跳转




好家伙,往上一看,专门加密过了,还有个网址,作为一个小白,还真不知道这个加密,去网上仔细搜索了一波,发现还是挺流行的一个免费加密,看了几个解密的文章,看的头昏脑胀,作为一个懒货,自然是不可能直接开始从头解密的


接下来,就请出调试断点大法,当然猜也是必不可少的
由上面就知道`_0x6d646b`应该就是主要的加密函数,毕竟调用的就是这个函数,又从网上的解密文章得知,该版本加密特征分几段,最下面一段就是被加密的源代码,那么这里的代码从`define`开始就是被加密的源代码了


本人出身是物联网,后来自学web渗透,对js并不是很熟悉,还好最近AI崛起,我直接询问chatgpt,发现`define(...`这一句是下面需要引用库,控制台已查询,是md5库,不出意外是MD5


为了节省时间,我尝试能不能直接一站到底,我在`_0x6d646b`函数中尝试寻找关键点,如果找不到,就需要一步一步调试了,幸运的是,发现调用md5的地方,果断断了点,重新提交


看着这行字符串,很明显是前面所有url中的参数添加进来进行重新排列拼接,感觉这不就来了
```javascript
"[%sd`~7^/>N4!Q#){'']"
```

直接往前追溯`_0x4aaee5_`中的函数,发现就是个废话函数,直接就是md5加密就行,不过是为了混淆添加了几步
为了确保这里排列的顺序不变,又多试了几次,发现顺序是一样的,那么接下来就毫无悬念了,毕竟虽然混淆十分令人害怕,好几百行代码,但是最后就是个最简单的md5加密,直接进行Python复现
```python
from Crypto.Hash import MD5

def getEnc(today, endTime, seatNum, startTime, token):
content = "[%sd`~7^/>N4!Q#){'']".format(
today, endTime, seatNum, startTime, token)
result = MD5.new()
result.update(content.encode('utf-8'))
return result.hexdigest()
```
传参进去发现,确实和enc一样

这样某通图书馆预约座位系统被我们扒光了,又可以愉快的抢座预约了,考研党永不为奴

zhongshisan 发表于 2023-8-11 12:12

我学校图书馆预约完,需要到图书馆扫码签到,或者刷脸签到。扫码用的二维码是在网页刷新的,只有图书馆局域网才能打开刷新,所以一直没找到什么方法破解。

libw 发表于 2023-6-5 18:35

jsjiamiv5和v6好像都可以被直接还原了:https://github.com/NXY666/Jsjiemi

minibeetuaman 发表于 2023-6-5 22:02

这种程度的混淆可以用AST还原,目前的攻坚都在jsvm上了

xixicoco 发表于 2023-6-6 00:49

还是不错哈,学以致用

loveu1316 发表于 2023-6-6 07:57

不错,学习学习哈

fan37257978 发表于 2023-6-6 08:24

自己也是前端爱好者,感谢楼主,学习很多

wzyl 发表于 2023-6-6 22:00

感谢楼主分享精神 向楼主学习

bandishui 发表于 2023-6-7 09:32

学习一下, 看的还很晕乎

无言Y 发表于 2023-6-7 11:28

感谢分享

catoo1 发表于 2023-6-7 21:16

感谢分享 学习一下
页: [1] 2
查看完整版本: 【js逆向】某习通座位预约加密分析(新手向)