|
#1
|
|||
|
|||
Encrypted video file
Hello, first of all, sorry if the wrong session.
I have an application that downloads a video file and lets you see this video later. (The idea is somehow similar to Netflix). However, this video file is somehow encrypted and the standard tool like vlc can't open it. I know this file contains at least a video because there is the MPEG header but after 1mb of "random" data unfortunately even removing this 1mb of random data is still not a valid MPEG file. So current file struct is [1mb chunk] [MPEG header] I'm not so experienced in data analysis, so I'm wondering do you have any tips, resource about "data mining" Since there is an android application I will also give a try by decompiling the APK and see how the video player is doing. But I would like to extend my data analysis skills first rather than RE. Thanks in advance |
#2
|
|||
|
|||
Hi
Can you share your video file, app, ... ? |
#3
|
|||
|
|||
fr.tuto.com
You can register, download the app and download some free source. for video files, I don't know as they seem to have a lot of metadata that probably contain a user/hardware ID. I will download a file later on a VM with a fake account. Thanks a lot |
#4
|
|||
|
|||
https://www120.zippyshare.com/v/zYmL5gcV/file.html
https://www120.zippyshare.com/v/ndBGL6sq/file.html Samples of videos,nice site btw,would be great to find a solution.
__________________
I like this forum! |
#5
|
|||
|
|||
Nice site, let me try
|
#6
|
|||
|
|||
Ok seems to be an nodejs things built on top of ionic/angular and Cordova(for cross-platform?).
The source code is located in build/www/main.js The var TutorialPage class is interesting stuff. Video seems to be embedded in a vg_Player(with a crossorigin) as expect, read mp4 file. Code:
<video [vgMedia]="media" [vgDash]="source" [vgHls]="source" #media id="singleVideo" preload="auto" type="video/mp4" crossorigin playsinline>\n </video>\n </vg-player TutorialPage.prototype.play Which download the source, and sign/unsign it Code:
TutorialPage.prototype.play = function (video, autoplay, setCursor, customCursor) { var _this = this; this.source = ''; this.isBuffering = true; this.disableControl = false; ((video.download.status == __WEBPACK_IMPORTED_MODULE_4__providers_download_status__["a" /* DownloadStatus */].STATUS_DOWNLOADED) ? video.download .getPath(true) .mergeMap(function (directory) { var basePath = directory.basePath, filePath = directory.filePath; return _this._signerService.isSigned(basePath + '/' + filePath.substr(1)) .mergeMap(function (isSigned) { return isSigned ? _this._signerService.unsign(basePath + '/' + filePath.substr(1)) : __WEBPACK_IMPORTED_MODULE_13_rxjs_Observable__["Observable"].of(''); }) .map(function () { return directory; }); }) .do(function (directory) { var basePath = directory.basePath, filePath = directory.filePath; var source = basePath + '/' + filePath.substr(1); if (_this.device.platform === 'iOS') { source = Object(__WEBPACK_IMPORTED_MODULE_2_ionic_angular__["I" /* normalizeURL */])(source); } _this._setSource(source, autoplay, video, setCursor, customCursor); }) .do(function (directory) { var basePath = directory.basePath, filePath = directory.filePath; __WEBPACK_IMPORTED_MODULE_13_rxjs_Observable__["Observable"].timer(1000) .mergeMap(function () { return _this._signerService.sign(basePath + '/' + filePath.substr(1), video.id); }) .subscribe(function () { return null; }); }) : this._videoService .get(video.id) .do(function (data) { return _this._setSource(data.link, autoplay, video, setCursor, customCursor); })) .subscribe(function () { _this.api.getDefaultMedia().loadMedia(); video.stats.lastTime = video.stats.cursor; if (_this._completionSubscriber) { _this._completionSubscriber.unsubscribe(); } if (_this._playSubscriber) { _this._playSubscriber.unsubscribe(); } setTimeout(function () { _this.onStartup = true; _this._completionSubscriber = _this.api.getDefaultMedia().subscriptions.timeUpdate.subscribe(function () { return _this._updateStats(video); }); _this._playSubscriber = _this.api.getDefaultMedia().subscriptions.play.subscribe(function () { return _this._onPlay(video); }); }, 400); }); }; At least there is the sln file (without the .cc that would have been too nice) but the PDB is still there so it should be pretty trivial. Thanks for the support guys Last edited by yologuy; 04-01-2020 at 17:33. |
#7
|
|||
|
|||
Each videos are signed from and to the user account then?
Keep us informed,would be nice to find a solution.
__________________
I like this forum! |
#8
|
|||
|
|||
by editing the main.js and removing the sign video did the trick.
So now when I play the video, the file is decrypted and stays decrypted on the disk. Then comparing both files, only the header changed. So I look briefly within the compiled signer module. There is a encryptDecrypt method that really looks interesting since it operates only on a 15bytes buffer, the exact same size that was changed in my file. I will probably get more time tomorrow. But I guess I'm on the right track And of course copy/pasting the header to your video didn't work, so I guess its a kind of xor, of the first 15b of the file, I just need to find the key |
#9
|
|||
|
|||
So it read the last 48bytes Then do a 0x2E xor on it.
hxxps://i.ibb.co/bWtK403/ecrypt-decrypt.jpg Note that the user_id and the video_id is embedded within the file (also stored at the end of the file) So here is the data structure starting from the end: 48bytes xored with 0x2E corresponding to the header of the file. 8 null bytes(delimiter?) UnknowInt32 8 null bytes(delimiter?) UnknowInt32 UnknowInt32 8 null bytes(delimiter?) UnknowInt32 video_id (int32) user_id (int32) EOF (for the video file) x bytes[FileContent] 48bytes[] that needs to be replaced by the end bytes xored for the moment they seem to be useless. So by applying that I was able to retrieve your mp4 files which are from https://fr.tuto.com/after-effects/gratuit-initiation-complete-d-after-effects-after-effects,49795.html (I didn't remove your user_id/video_id) https://www.sendspace.com/filegroup/RMqSpPbmzMobgzR7U5kRGg Btw you can get your user_id, just connect to tuto.com, inspect the src code and at the bottom, there is your user_id Next step create a python script to automate this, but should be trivial will probably have more time next weekend Enjoy BTW hxxps://www.relyze.com/beta3.html is amazing and free for non-commercial project Last edited by yologuy; 04-05-2020 at 19:47. |
#10
|
|||
|
|||
Looks like I can't edit my post I don't know why.
Sorry for the double post. Here the python3 script, which also removes the user_id from the video Code:
import os import shutil headerSize = 48 def decrypt_file(encryptedFile, decryptedFile): shutil.copy(encryptedFile, decryptedFile) with open(decryptedFile, "r+b") as inputFile: # Remove the user ID videoIdEmplacement = headerSize * 2 - 3 inputFile.seek(-videoIdEmplacement, os.SEEK_END) inputFile.write(bytes([0x00, 0x00, 0x00, 0x00])) # Read the encrypted header inputFile.seek(-headerSize, os.SEEK_END) encryptedHeader = bytearray(inputFile.read(headerSize)) # Xor the header decryptedHeader = bytes([b ^ 0x2E for b in encryptedHeader]) # Write the original file header inputFile.seek(0, os.SEEK_SET) inputFile.write(decryptedHeader) inputVideoFile = r"inputVideoFile" mp4VideoFile = r"outputVideoFile.mp4" decrypt_file(inputVideoFile, mp4VideoFile) Note that looking at the app, the encryption seems different on android, so just in case I'm on a PC that may differ with a mac I don't know. |
The Following 8 Users Say Thank You to yologuy For This Useful Post: | ||
Abaddon (04-05-2020), bolo2002 (04-06-2020), cachito (04-07-2020), chants (04-07-2020), DominicCummings (09-09-2021), Mahmoudnia (04-05-2020), ziapcland (04-13-2020), Zipdecode (05-03-2020) |
#11
|
|||
|
|||
Well done thanks,videos are not mine just found it easy as they are free,time to make a standalone tool joke
__________________
I like this forum! |
#12
|
|||
|
|||
Well an XOR cipher on a handful of bytes is the most partial and Ancient encryption method . It makes sense given that encrypting video data itself with something strong especially would turn a computer into a space heater, and would probably cause stuttering and glitching. Encrypting selective consecutive frames or a good number of other options might work. Or hardware specially designed for the purpose perhaps. But the excess CPU on what is such a real time priority task makes a perfect solution impossible. Even AES with processor intrinsic would probably be too costly. Nice solutoon and script to go with it though
The post editing feature is only enabled for a fee minutes after posting, and it is beneficial since it's better to preserve mistakes and keep context in a thread then see history being rewritten to the point a thread no longer makes sense. In my experience, the edit timeout is always increasing quality of discussion. It's even used all over now, I've seen StackOverflow won't let me edit comments after some amount of minutes. Once you see the feature overused, and the difficulty it causes, you can understand the policy |
#13
|
|||
|
|||
@yologuy:
by investigating code,did you see some method to get paid courses with free account?
__________________
I like this forum! |
#14
|
|||
|
|||
Unfortually not, all data are sent to the server, I didn't bother trying anything, but their server may have issue but yeah, the client don't do a lot except redirect to a REST API.
|
#15
|
|||
|
|||
Quote:
I understand how java works but often not how to get what i want.
__________________
I like this forum! |
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Help with AES 128 encrypted file | phroyt | General Discussion | 6 | 04-28-2020 09:57 |
Reversing obfuscated and encrypted JAR file | Chuck954 | General Discussion | 8 | 10-11-2019 10:04 |
Is it possible to crack encrypted file? | wenij | General Discussion | 8 | 02-19-2005 20:20 |