Giter VIP home page Giter VIP logo

Comments (24)

valerierx avatar valerierx commented on August 11, 2024 7

It appears that BeReal stepped up their protection against reverse engineering, it now seems to detect HTTPToolkit on a rooted phone.

Using https://modules.lsposed.org/module/io.github.tehcneko.sslunpinning works and dumps the requests. I'll post them here tomorrow

from befake.

notmarek avatar notmarek commented on August 11, 2024 3

Seems like they started cert pinning in the iOS app so I was unable to research anything. I might archive this project as i don't have access to an Android device or a jailbroken iOS device.

from befake.

valerierx avatar valerierx commented on August 11, 2024 3

Here are the post upload requests and responses. I forgot to update the app tho, I'll check tomorrow if there's any differences between version 0.61.7 and 0.63.4.

Individual photo upload

Headers

cache-control: public,max-age=172800
connection: Keep-Alive
content-length: 100862
content-type: image/webp
host: storage.googleapis.com
x-goog-content-length-range: 1024,1048576

PUT
https://storage.googleapis.com/storage.bere.al/Photos/userid/post/test-test.webp?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=prod-backend-fasterstore%40alexisbarreyat-bereal.iam.gserviceaccount.com%2F20230219%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20230219T215032Z&X-Goog-Expires=172801&X-Goog-SignedHeaders=cache-control%3Bcontent-type%3Bhost%3Bx-goog-content-length-range&X-Goog-Signature=signature

post upload, url https://mobile.bereal.com/api/content/posts

Headers:

accept-encoding: gzip
authorization: Bearer key
bereal-app-language: fr
bereal-app-version: 0.61.7
bereal-device-id: deviceid
bereal-device-language: fr
bereal-os-version: 8.1.0
bereal-platform: android
bereal-timezone: Europe/Paris
connection: Keep-Alive
content-length: 445
content-type: application/json; charset=utf-8
host: mobile.bereal.com
user-agent: okhttp/4.10.0
x-datadog-origin: rum
x-datadog-parent-id: 12345678910
x-datadog-sampled: 1
x-datadog-sampling-priority: 1
x-datadog-trace-id: 12345678910

POST content:

{
  "frontCamera": {
    "bucket": "storage.bere.al",
    "path": "Photos/userid/post/test-test.webp",
    "width": 1500,
    "height": 2000
  },
  "backCamera": {
    "bucket": "storage.bere.al",
    "path": "Photos/userid/post/test2-test2.webp",
    "width": 1500,
    "height": 2000
  },
  "takenAt": "2023-02-19T21:28:43.367Z",
  "isLate": true,
  "visibility": [
    "friends-of-friends"
  ],
  "retakeCounter": 0,
  "location": {
    "longitude": xx,
    "latitude": xx
  }
}

Response:

{
  "user": {
    "id": "userid",
    "username": "username",
    "profilePicture": {
      "height": 500,
      "width": 500,
      "url": "https://cdn.bereal.network/Photos/userid/profile/userid-unixtimestamp-profile-picture.jpg"
    }
  },
  "primary": {
    "height": 2000,
    "width": 1500,
    "url": "https://cdn.bereal.network/Photos/userid/post/picture1.webp"
  },
  "secondary": {
    "height": 2000,
    "width": 1500,
    "url": "https://cdn.bereal.network/Photos/userid/post/picture2.webp"
  },
  "isLate": true,
  "lateInSeconds": seconds late,
  "moment": {
    "id": "moment-id",
    "region": "europe-west"
  },
  "id": "post id?",
  "location": {
    "longitude": xx,
    "latitude": xx
  },
  "caption": null,
  "retakeCounter": 0,
  "comments": {
    "sample": [],
    "total": 0
  },
  "realmojis": {
    "sample": [],
    "total": 0
  },
  "screenshots": {
    "sample": [],
    "total": 0
  },
  "createdAt": "same date format as before",
  "takenAt": "same date format as before",
  "visibility": [
    "friends",
    "friends-of-friends"
  ],
  "canDelete": true
}

Edit: I'm using a Nexus 5X running LineageOS 15.1 with latest magisk, zygisk LSPosed and the certificate unpinner above if you want to reproduce that.

from befake.

valerierx avatar valerierx commented on August 11, 2024 3

I have some really bad news: the login process has gotten even more complicated, with the use of SafetyNet and other google stuff. Can someone with access to a jailbroken IOS device dump the login endpoints to see if they can be used by this library?

from befake.

valerierx avatar valerierx commented on August 11, 2024 3

Uh I just tried logging in using the master branch and it just works?? Maybe someone using an Iphone can dump the newest user-agents and iOS receipt.

from befake.

valerierx avatar valerierx commented on August 11, 2024 2

Btw is anyone planning on creating a GTK4 frontend using this library? I just recently got a Pinephone Pro and having BeReal on it would be awesome πŸ˜ƒ

from befake.

notmarek avatar notmarek commented on August 11, 2024 1

I don't have time nowadays but when I get a second i will download the latest TestFlight version and try to reverse engineer the API again😬

from befake.

notmarek avatar notmarek commented on August 11, 2024 1

Seems like i will be able to do it tomorrow since I've fallen sick.

from befake.

valerierx avatar valerierx commented on August 11, 2024 1

Edit: I've discovered the endpoint to generate the picture upload API. Gonna add it to my private fork and make a pull request soon.

from befake.

s-alad avatar s-alad commented on August 11, 2024 1

I think I posted pythonic code for Signed picture uploads earlier if you would like to take a look

from befake.

albertopasqualetto avatar albertopasqualetto commented on August 11, 2024

In the code, Post class is not instantiated

from befake.

valerierx avatar valerierx commented on August 11, 2024

Yeah program does not work at all, completely unusable

from befake.

h7ndrx avatar h7ndrx commented on August 11, 2024

any updates on this?

from befake.

h7ndrx avatar h7ndrx commented on August 11, 2024

Ok thanks @notmarek 😬

from befake.

albertopasqualetto avatar albertopasqualetto commented on August 11, 2024

@notmarek good to know, as I said some comments before, the problem seems to be with the Post class, I think the apis were not changed because I posted something with another website, I cannot give you more info since it happened some months ago.

from befake.

h7ndrx avatar h7ndrx commented on August 11, 2024

There has been a fix for uploading as well as the login captcha already on a fork

from befake.

ArtrenH avatar ArtrenH commented on August 11, 2024

@notmarek In the past I was able to monitor requests using android studio emulator and this project: https://github.com/shroudedcode/apk-mitm
But it didn't work the last time I used it, probably because of a stupid mistake I made, I currently don't have enough time to investigate...

from befake.

ArtrenH avatar ArtrenH commented on August 11, 2024

@h7ndrx What fork is it?

from befake.

s-alad avatar s-alad commented on August 11, 2024

They

Seems like they started cert pinning in the iOS app so I was unable to research anything. I might archive this project as i don't have access to an Android device or a jailbroken iOS device.

You can use AVD on android studio and root using https://github.com/newbit1/rootAVD and unpin the ssl then proxy straight to your computer.

The new post code was first found by hubertoschusch I believe in this playground.

Logging in has also been bypassed by Rvaidan, I believe he is using google cloud functions as a proxy generator or something like that. However when I use mitm to proxy login requests, its still dependent on different Certs from ios and android so Im quite unsure how he is bypassing the recaptcha.

Bereal is definitely stepping up

Heres my pythonic version of the posting that matches this project somewhat:

@app.route("/signedpostinstant/<token>/<uid>/", methods=["POST"])
@app.route("/signedpostinstant/<token>/<uid>/<caption>", methods=["POST"])
def signedpostinstant(token:str, uid:str, caption:str=''):
    #==============================================================================================
    print(request.form.to_dict())
    print(request.files)
    print(caption)
    #==============================================================================================

    ispublic = json.loads(request.form.to_dict()['public'].lower())
    latitude = request.form.to_dict()['latitude']
    longitude = request.form.to_dict()['longitude']
    haslocation = json.loads(request.form.to_dict()['haslocation'].lower())
    print(ispublic, type(ispublic))
    print(latitude, type(latitude))
    print(longitude, type(longitude))
    print(haslocation, type(haslocation))

    #file manipulation
    def get_data(version):  
        version_data = io.BytesIO()
        version.save(version_data, format="JPEG", quality=90)
        version_data = version_data.getvalue()
        return version_data
    
    def extension(img):
        mime_type = Image.MIME[img.format]
        if mime_type != "image/jpeg":
            if not img.mode == "RGB":
                img = img.convert("RGB")
        return img

    p = request.files['primary'] 
    primary = Image.open(io.BytesIO(p.read()))
    primary = extension(primary)
    prim_data = get_data(primary) #this is the primary image file
    primarysize = str(len(prim_data))

    s = request.files['secondary']
    secondary = Image.open(io.BytesIO(s.read()))
    secondary = extension(secondary)
    sec_data = get_data(secondary) #this is the secondary image file
    secondarysize = str(len(sec_data))
    #==============================================================================================

    apiurl = f"https://mobile.bereal.com/api/content/posts/upload-url?mimeType=image%2Fwebp"
    headers = {
        "authorization": "Bearer {}".format(token),
        "accept-encoding": "gzip",
        "user-agent": "okhttp/4.10.0",
        "if-none-match": 'W/"507-M16WxEgA1LffRgMAGSRIlonfNV8"'
    }
    signed_upload_res = requests.get(url=apiurl, headers=headers)
    print("----- SIGNED UPLOAD -----")
    print(signed_upload_res)
    print(signed_upload_res.json())
    if signed_upload_res.status_code != 200: return signed_upload_res.json()
    print('----- END -----')

    signed_upload_res = signed_upload_res.json()
    signed_upload_res = signed_upload_res["data"]

    prim_path = signed_upload_res[0]["path"]
    sec_path = signed_upload_res[1]["path"]

    def intostorage(signed_res, file):
        bucket = signed_res['bucket']
        expires = signed_res['expireAt']
        image_path = signed_res['path']
        bucket_headers = signed_res['headers']
        bucket_url = signed_res['url']

        print("----- BUCKET INFO -----")
        print(bucket, "\n >>>>")
        print(expires, "\n >>>>")
        print(image_path, "\n >>>>")
        print(bucket_headers, "\n >>>>")
        print(bucket_url, "\n >>>>")
        print('----- END -----')

        ret = requests.put(url=bucket_url, headers=bucket_headers, data=file)
        print("----- BUCKET PUT RESP -----")
        print(ret)
        print(ret.text)
        print('----- END -----')
        if ret.status_code != 200: raise Exception(f"Error uploading image: {ret.status_code}, {ret.text}")
        return ret

    prim_bucket_ret = intostorage(signed_upload_res[0] ,prim_data)
    sec_bucket_ret = intostorage(signed_upload_res[1] ,sec_data)
    print("----- BUCKET RET -----")
    print(prim_bucket_ret)
    print(">>>>>")
    print(sec_bucket_ret)
    print('----- END -----')

    now = pendulum.now()
    taken_at = f"{now.to_date_string()}T{now.to_time_string()}Z"

    payload = {
        "isPublic": ispublic,
        "isLate": False,
        "retakeCounter": 0,
        "takenAt": taken_at,
        #"location": location,
        "caption": caption,
        "backCamera": {
            "bucket": "storage.bere.al",
            "height": 2000,
            "width": 1500,
            "path": prim_path,
        },
        "frontCamera": {
            "bucket": "storage.bere.al",
            "height": 2000,
            "width": 1500,
            "path": sec_path,
        },
    }
    if haslocation: payload["location"] = {"latitude": latitude,"longitude": longitude,}

    complete_res = requests.post(url=api_url+'/content/post',json=payload,headers={"content-type" : "application/json", "authorization": token},)
    print(complete_res)
    print(complete_res.json())

    return complete_res.json()

from befake.

NicoWeio avatar NicoWeio commented on August 11, 2024

Maybe throwing the BeReal APK into https://www.decompiler.com/ gives enough insight for reverse-engineering? I've made some good experiences with that approach.

from befake.

h7ndrx avatar h7ndrx commented on August 11, 2024

Thank you @VxlerieUwU

from befake.

LCB0B avatar LCB0B commented on August 11, 2024

@VxlerieUwU any idea of how to fix the login ? :)

from befake.

valerierx avatar valerierx commented on August 11, 2024

I'll investigate and post some endpoints here soon this week. I think BeReal is making their platform much secure and harder to reverse engineer, we'll have to dump the api endpoints whenever a new update goes public.

from befake.

valerierx avatar valerierx commented on August 11, 2024

Btw the Picture class here needs to be completely rewritten, uploads are now for both primary and secondary image at the same time, and at a seperate endpoint for Realmojis.

from befake.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.