yasint 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- yasint-0.3.0/CHANGELOG.md +56 -0
- yasint-0.3.0/LICENCES/MIT-Soxoj.txt +21 -0
- yasint-0.3.0/MANIFEST.in +12 -0
- yasint-0.3.0/NOTICE +5 -0
- yasint-0.3.0/PKG-INFO +177 -0
- yasint-0.3.0/README.md +132 -0
- yasint-0.3.0/pyproject.toml +3 -0
- yasint-0.3.0/requirements-dev.txt +9 -0
- yasint-0.3.0/requirements.txt +8 -0
- yasint-0.3.0/run.py +5 -0
- yasint-0.3.0/setup.cfg +4 -0
- yasint-0.3.0/setup.py +49 -0
- yasint-0.3.0/tests/test_cli_hilevel.py +195 -0
- yasint-0.3.0/tests/test_cookies.py +77 -0
- yasint-0.3.0/tests/test_core_hilevel.py +233 -0
- yasint-0.3.0/tests/test_report.py +97 -0
- yasint-0.3.0/tests/test_report_hilevel.py +130 -0
- yasint-0.3.0/tests/test_session_recorder.py +114 -0
- yasint-0.3.0/yasint/__init__.py +2 -0
- yasint-0.3.0/yasint/__main__.py +8 -0
- yasint-0.3.0/yasint/_version.py +1 -0
- yasint-0.3.0/yasint/cli.py +260 -0
- yasint-0.3.0/yasint/core.py +860 -0
- yasint-0.3.0/yasint/executor.py +120 -0
- yasint-0.3.0/yasint/report.py +219 -0
- yasint-0.3.0/yasint.egg-info/PKG-INFO +177 -0
- yasint-0.3.0/yasint.egg-info/SOURCES.txt +29 -0
- yasint-0.3.0/yasint.egg-info/dependency_links.txt +1 -0
- yasint-0.3.0/yasint.egg-info/entry_points.txt +2 -0
- yasint-0.3.0/yasint.egg-info/requires.txt +8 -0
- yasint-0.3.0/yasint.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.3.0
|
|
4
|
+
|
|
5
|
+
- Fetch profile pictures safely and consistently
|
|
6
|
+
- Better cookie handling
|
|
7
|
+
- Add PyPI build metadata
|
|
8
|
+
- Rename project
|
|
9
|
+
- Update README
|
|
10
|
+
- Sunset pictures/
|
|
11
|
+
|
|
12
|
+
## 0.2.1
|
|
13
|
+
|
|
14
|
+
- High-level tests
|
|
15
|
+
- Fix Unicode issue in file put()
|
|
16
|
+
- Make relevant cookie loading status explicit with colourised output.
|
|
17
|
+
- Update README
|
|
18
|
+
- Update .gitignore
|
|
19
|
+
|
|
20
|
+
## 0.2.0
|
|
21
|
+
|
|
22
|
+
- Implement a case system utilizing timestamps for reports
|
|
23
|
+
- Fix stale `run.py` wrapper to delegate to the package CLI entrypoint.
|
|
24
|
+
- Make zero-lead results explicit in console, TXT, and CSV reports
|
|
25
|
+
- Save auxiliary TXT and CSV evidence reports inside each session folder
|
|
26
|
+
- Show the full per-session reports path in output
|
|
27
|
+
- Fix HTML metadata handling per encodings.
|
|
28
|
+
- Implement test-driven CI/CD.
|
|
29
|
+
|
|
30
|
+
## 0.1.0
|
|
31
|
+
|
|
32
|
+
- Fix Cookie handling
|
|
33
|
+
- Turn into a pip-installable package.
|
|
34
|
+
|
|
35
|
+
## 0.0.8
|
|
36
|
+
|
|
37
|
+
- Add per-input UTC-timestamped response sessions
|
|
38
|
+
- Save all attempted HTTP responses to session folders
|
|
39
|
+
- Embed response headers in saved HTML output where possible
|
|
40
|
+
- Save non-HTML responses as raw header-plus-body files
|
|
41
|
+
- Track progress by attempted URL hits per session
|
|
42
|
+
|
|
43
|
+
## 0.0.4
|
|
44
|
+
|
|
45
|
+
- Fixes to asyncio usage for Python 3.14 (Python 3.8 or higher), while maintaining backwards compatibility.
|
|
46
|
+
- Fix relative import in `__main__.py`
|
|
47
|
+
- Add URLs and request-method information to the final summary
|
|
48
|
+
- Add missing requirements to `requirements.txt`
|
|
49
|
+
- Fix flimsy packaging entrypoint
|
|
50
|
+
- Misc: Create changelog
|
|
51
|
+
- Misc: Update User-Agent
|
|
52
|
+
- Bump version
|
|
53
|
+
|
|
54
|
+
## 0.0.3
|
|
55
|
+
|
|
56
|
+
- ...
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021 Soxoj
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
yasint-0.3.0/MANIFEST.in
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
include CHANGELOG.md
|
|
2
|
+
include MANIFEST.in
|
|
3
|
+
include NOTICE
|
|
4
|
+
include PUBLISHING.md
|
|
5
|
+
include README.md
|
|
6
|
+
include requirements.txt
|
|
7
|
+
include requirements-dev.txt
|
|
8
|
+
include run.py
|
|
9
|
+
recursive-include LICENCES *.txt
|
|
10
|
+
recursive-include tests *.py
|
|
11
|
+
global-exclude __pycache__
|
|
12
|
+
global-exclude *.py[cod]
|
yasint-0.3.0/NOTICE
ADDED
yasint-0.3.0/PKG-INFO
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: yasint
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Yandex profile OSINT tool
|
|
5
|
+
Home-page: https://github.com/TAbdiukov/YaSINT
|
|
6
|
+
Author: Tim Abdiukov
|
|
7
|
+
Project-URL: Source, https://github.com/TAbdiukov/YaSINT
|
|
8
|
+
Project-URL: Issues, https://github.com/TAbdiukov/YaSINT/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/TAbdiukov/YaSINT/blob/main/CHANGELOG.md
|
|
10
|
+
Classifier: Environment :: Console
|
|
11
|
+
Classifier: Intended Audience :: Information Technology
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
22
|
+
Classifier: Topic :: Security
|
|
23
|
+
Requires-Python: >=3.8
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: NOTICE
|
|
26
|
+
License-File: LICENCES/MIT-Soxoj.txt
|
|
27
|
+
Requires-Dist: socid-extractor>=0.0.8
|
|
28
|
+
Requires-Dist: aiohttp>=3.8.0
|
|
29
|
+
Requires-Dist: requests>=2.0.0
|
|
30
|
+
Requires-Dist: charset-normalizer>=2.0.0
|
|
31
|
+
Requires-Dist: termcolor
|
|
32
|
+
Requires-Dist: colorama
|
|
33
|
+
Requires-Dist: tqdm
|
|
34
|
+
Requires-Dist: aiohttp-socks>=0.11.0
|
|
35
|
+
Dynamic: author
|
|
36
|
+
Dynamic: classifier
|
|
37
|
+
Dynamic: description
|
|
38
|
+
Dynamic: description-content-type
|
|
39
|
+
Dynamic: home-page
|
|
40
|
+
Dynamic: license-file
|
|
41
|
+
Dynamic: project-url
|
|
42
|
+
Dynamic: requires-dist
|
|
43
|
+
Dynamic: requires-python
|
|
44
|
+
Dynamic: summary
|
|
45
|
+
|
|
46
|
+
# YaSINT
|
|
47
|
+
|
|
48
|
+
[](https://github.com/TAbdiukov/YaSINT)
|
|
49
|
+
[](https://pypi.org/project/YaSINT)
|
|
50
|
+

|
|
51
|
+
|
|
52
|
+
[](https://www.buymeacoffee.com/tabdiukov)
|
|
53
|
+
|
|
54
|
+
YaSINT is a command line OSINT ttolkit for looking up public Yandex account information by username, email address, or Yandex public ID.
|
|
55
|
+
|
|
56
|
+
It is a greatly updated package based on the original YaSeeker project. YaSINT is now intended to be installed as a Python package and run with a command, although it can still be run directly from a source checkout.
|
|
57
|
+
|
|
58
|
+
## Artifacts
|
|
59
|
+
|
|
60
|
+
Depending on what public Yandex pages and APIs return, YaSINT may find:
|
|
61
|
+
|
|
62
|
+
* full name;
|
|
63
|
+
* profile photo or other possible avatar URLs;
|
|
64
|
+
* gender;
|
|
65
|
+
* Yandex UID;
|
|
66
|
+
* Yandex public ID;
|
|
67
|
+
* linked social accounts;
|
|
68
|
+
* public activity information;
|
|
69
|
+
* account flags, such as verified, banned, deleted, restricted, or business status.
|
|
70
|
+
|
|
71
|
+
Some services return useful information only when valid Yandex cookies are
|
|
72
|
+
provided. See [Cookies](#cookies).
|
|
73
|
+
|
|
74
|
+
## Installation
|
|
75
|
+
|
|
76
|
+
Python 3.8 or newer is required.
|
|
77
|
+
|
|
78
|
+
Install from PyPI:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
python -m pip install yasint
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
If you already downloaded the source code, install it from the project directory:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
python -m pip install .
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
After installation, the `yasint` command should be available:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
yasint --version
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
If you do not want to install the package, you can run it from the source
|
|
97
|
+
directory instead:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
python -m pip install -r requirements.txt
|
|
101
|
+
python -m yasint login
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Usage
|
|
105
|
+
|
|
106
|
+
Give YaSINT one or more targets:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
yasint TARGET
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Examples:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
yasint login
|
|
116
|
+
yasint login@yandex.ru
|
|
117
|
+
yasint c48fhxw0qppa50289r5c9ku4k4
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
The tool recognises the target type automatically. Email addresses
|
|
121
|
+
are supported. A 26-character value is treated as a Yandex public ID.
|
|
122
|
+
|
|
123
|
+
For many targets, put one target per line in a text file:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
yasint --target-list targets.txt
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Results
|
|
130
|
+
|
|
131
|
+
For every target, YaSINT creates a per-session folder under `reports/`.
|
|
132
|
+
The folder name contains a UTC timestamp and the target value.
|
|
133
|
+
|
|
134
|
+
```text
|
|
135
|
+
reports/20260101T120000Z_login/
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
The session folder keeps the evidence collected during the run, including saved
|
|
139
|
+
responses where possible and auxiliary TXT/CSV reports. The console output gives
|
|
140
|
+
you the human-readable summary.
|
|
141
|
+
|
|
142
|
+
You can also write your own report files:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
yasint login -oT report.txt -oC report.csv
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
A `No leads found` result means the checked sources did not return useful
|
|
149
|
+
profile data for that target. It does not prove that the account does not exist.
|
|
150
|
+
|
|
151
|
+
## Cookies
|
|
152
|
+
|
|
153
|
+
Some Yandex services require cookies before they return useful API responses.
|
|
154
|
+
YaSINT can read browser cookies exported in Netscape `cookies.txt` format.
|
|
155
|
+
|
|
156
|
+
1. Log in to Yandex in your browser.
|
|
157
|
+
2. Export your Yandex cookies as `cookies.txt` ([Chrome](https://chromewebstore.google.com/detail/get-cookiestxt-locally/cclelndahbckbenkjhflpdbgdldlbecc), [Firefox](https://addons.mozilla.org/en-US/firefox/addon/cookies-txt/)).
|
|
158
|
+
3. Put `cookies.txt` in the directory where you run YaSINT.
|
|
159
|
+
4. Run YaSINT normally.
|
|
160
|
+
|
|
161
|
+
You can also pass a custom cookie file path:
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
yasint login --cookie-jar-file /path/to/cookies.txt
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
When cookies are loaded, YaSINT prints whether any of them match the
|
|
168
|
+
Yandex domains queried by the tool.
|
|
169
|
+
|
|
170
|
+
## SOWEL classification
|
|
171
|
+
|
|
172
|
+
This tool uses the following OSINT techniques:
|
|
173
|
+
|
|
174
|
+
* [SOTL-1.4. Analyze Internal Identifiers](https://sowel.soxoj.com/internal-identifiers)
|
|
175
|
+
* [SOTL-2.2. Search For Accounts On Other Platforms](https://sowel.soxoj.com/other-platform-accounts)
|
|
176
|
+
* [SOTL-6.1. Check Logins Reuse To Find Another Account](https://sowel.soxoj.com/logins-reuse)
|
|
177
|
+
* [SOTL-6.2. Check Nicknames Reuse To Find Another Account](https://sowel.soxoj.com/nicknames-reuse)
|
yasint-0.3.0/README.md
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# YaSINT
|
|
2
|
+
|
|
3
|
+
[](https://github.com/TAbdiukov/YaSINT)
|
|
4
|
+
[](https://pypi.org/project/YaSINT)
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
[](https://www.buymeacoffee.com/tabdiukov)
|
|
8
|
+
|
|
9
|
+
YaSINT is a command line OSINT ttolkit for looking up public Yandex account information by username, email address, or Yandex public ID.
|
|
10
|
+
|
|
11
|
+
It is a greatly updated package based on the original YaSeeker project. YaSINT is now intended to be installed as a Python package and run with a command, although it can still be run directly from a source checkout.
|
|
12
|
+
|
|
13
|
+
## Artifacts
|
|
14
|
+
|
|
15
|
+
Depending on what public Yandex pages and APIs return, YaSINT may find:
|
|
16
|
+
|
|
17
|
+
* full name;
|
|
18
|
+
* profile photo or other possible avatar URLs;
|
|
19
|
+
* gender;
|
|
20
|
+
* Yandex UID;
|
|
21
|
+
* Yandex public ID;
|
|
22
|
+
* linked social accounts;
|
|
23
|
+
* public activity information;
|
|
24
|
+
* account flags, such as verified, banned, deleted, restricted, or business status.
|
|
25
|
+
|
|
26
|
+
Some services return useful information only when valid Yandex cookies are
|
|
27
|
+
provided. See [Cookies](#cookies).
|
|
28
|
+
|
|
29
|
+
## Installation
|
|
30
|
+
|
|
31
|
+
Python 3.8 or newer is required.
|
|
32
|
+
|
|
33
|
+
Install from PyPI:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
python -m pip install yasint
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
If you already downloaded the source code, install it from the project directory:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
python -m pip install .
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
After installation, the `yasint` command should be available:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
yasint --version
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
If you do not want to install the package, you can run it from the source
|
|
52
|
+
directory instead:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
python -m pip install -r requirements.txt
|
|
56
|
+
python -m yasint login
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Usage
|
|
60
|
+
|
|
61
|
+
Give YaSINT one or more targets:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
yasint TARGET
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Examples:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
yasint login
|
|
71
|
+
yasint login@yandex.ru
|
|
72
|
+
yasint c48fhxw0qppa50289r5c9ku4k4
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The tool recognises the target type automatically. Email addresses
|
|
76
|
+
are supported. A 26-character value is treated as a Yandex public ID.
|
|
77
|
+
|
|
78
|
+
For many targets, put one target per line in a text file:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
yasint --target-list targets.txt
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Results
|
|
85
|
+
|
|
86
|
+
For every target, YaSINT creates a per-session folder under `reports/`.
|
|
87
|
+
The folder name contains a UTC timestamp and the target value.
|
|
88
|
+
|
|
89
|
+
```text
|
|
90
|
+
reports/20260101T120000Z_login/
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
The session folder keeps the evidence collected during the run, including saved
|
|
94
|
+
responses where possible and auxiliary TXT/CSV reports. The console output gives
|
|
95
|
+
you the human-readable summary.
|
|
96
|
+
|
|
97
|
+
You can also write your own report files:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
yasint login -oT report.txt -oC report.csv
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
A `No leads found` result means the checked sources did not return useful
|
|
104
|
+
profile data for that target. It does not prove that the account does not exist.
|
|
105
|
+
|
|
106
|
+
## Cookies
|
|
107
|
+
|
|
108
|
+
Some Yandex services require cookies before they return useful API responses.
|
|
109
|
+
YaSINT can read browser cookies exported in Netscape `cookies.txt` format.
|
|
110
|
+
|
|
111
|
+
1. Log in to Yandex in your browser.
|
|
112
|
+
2. Export your Yandex cookies as `cookies.txt` ([Chrome](https://chromewebstore.google.com/detail/get-cookiestxt-locally/cclelndahbckbenkjhflpdbgdldlbecc), [Firefox](https://addons.mozilla.org/en-US/firefox/addon/cookies-txt/)).
|
|
113
|
+
3. Put `cookies.txt` in the directory where you run YaSINT.
|
|
114
|
+
4. Run YaSINT normally.
|
|
115
|
+
|
|
116
|
+
You can also pass a custom cookie file path:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
yasint login --cookie-jar-file /path/to/cookies.txt
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
When cookies are loaded, YaSINT prints whether any of them match the
|
|
123
|
+
Yandex domains queried by the tool.
|
|
124
|
+
|
|
125
|
+
## SOWEL classification
|
|
126
|
+
|
|
127
|
+
This tool uses the following OSINT techniques:
|
|
128
|
+
|
|
129
|
+
* [SOTL-1.4. Analyze Internal Identifiers](https://sowel.soxoj.com/internal-identifiers)
|
|
130
|
+
* [SOTL-2.2. Search For Accounts On Other Platforms](https://sowel.soxoj.com/other-platform-accounts)
|
|
131
|
+
* [SOTL-6.1. Check Logins Reuse To Find Another Account](https://sowel.soxoj.com/logins-reuse)
|
|
132
|
+
* [SOTL-6.2. Check Nicknames Reuse To Find Another Account](https://sowel.soxoj.com/nicknames-reuse)
|
yasint-0.3.0/run.py
ADDED
yasint-0.3.0/setup.cfg
ADDED
yasint-0.3.0/setup.py
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
exec(open('yasint/_version.py', encoding='utf-8').read())
|
|
4
|
+
|
|
5
|
+
with open('requirements.txt', encoding='utf-8') as rf:
|
|
6
|
+
requires = [
|
|
7
|
+
line.strip()
|
|
8
|
+
for line in rf
|
|
9
|
+
if line.strip() and not line.lstrip().startswith('#')
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
with open('README.md', encoding='utf-8') as fh:
|
|
13
|
+
long_description = fh.read()
|
|
14
|
+
|
|
15
|
+
setup(
|
|
16
|
+
name="yasint",
|
|
17
|
+
version=__version__,
|
|
18
|
+
description="Yandex profile OSINT tool",
|
|
19
|
+
long_description=long_description,
|
|
20
|
+
long_description_content_type="text/markdown",
|
|
21
|
+
url="https://github.com/TAbdiukov/YaSINT",
|
|
22
|
+
author="Tim Abdiukov",
|
|
23
|
+
entry_points={'console_scripts': ['yasint = yasint.cli:run']},
|
|
24
|
+
packages=find_packages(),
|
|
25
|
+
include_package_data=True,
|
|
26
|
+
install_requires=requires,
|
|
27
|
+
python_requires=">=3.8",
|
|
28
|
+
license_files=["NOTICE", "LICENCES/MIT-Soxoj.txt"],
|
|
29
|
+
project_urls={
|
|
30
|
+
"Source": "https://github.com/TAbdiukov/YaSINT",
|
|
31
|
+
"Issues": "https://github.com/TAbdiukov/YaSINT/issues",
|
|
32
|
+
"Changelog": "https://github.com/TAbdiukov/YaSINT/blob/main/CHANGELOG.md",
|
|
33
|
+
},
|
|
34
|
+
classifiers=[
|
|
35
|
+
"Environment :: Console",
|
|
36
|
+
'Intended Audience :: Information Technology',
|
|
37
|
+
"Operating System :: OS Independent",
|
|
38
|
+
"Programming Language :: Python :: 3",
|
|
39
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
40
|
+
"Programming Language :: Python :: 3.8",
|
|
41
|
+
"Programming Language :: Python :: 3.9",
|
|
42
|
+
"Programming Language :: Python :: 3.10",
|
|
43
|
+
"Programming Language :: Python :: 3.11",
|
|
44
|
+
"Programming Language :: Python :: 3.12",
|
|
45
|
+
"Programming Language :: Python :: 3.13",
|
|
46
|
+
"Programming Language :: Python :: 3.14",
|
|
47
|
+
"Topic :: Security",
|
|
48
|
+
],
|
|
49
|
+
)
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import csv
|
|
2
|
+
import io
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
import yasint.cli as cli
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
PUBLIC_ID = 'c48fhxw0qppa50289r5c9ku4k4'
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _no_lead_results(input_data):
|
|
14
|
+
return [
|
|
15
|
+
cli.OutputDataList(
|
|
16
|
+
item,
|
|
17
|
+
[cli.OutputData(item.value, {'platform': 'Music'}, None)],
|
|
18
|
+
session_dir='',
|
|
19
|
+
)
|
|
20
|
+
for item in input_data
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _lead_results(input_data, session_dir=''):
|
|
25
|
+
return [
|
|
26
|
+
cli.OutputDataList(
|
|
27
|
+
item,
|
|
28
|
+
[cli.OutputData(item.value, {'platform': 'Music', 'username': item.value}, None)],
|
|
29
|
+
session_dir=session_dir,
|
|
30
|
+
)
|
|
31
|
+
for item in input_data
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class FakeProcessor:
|
|
36
|
+
instances = []
|
|
37
|
+
result_builder = _no_lead_results
|
|
38
|
+
|
|
39
|
+
def __init__(self, *args, **kwargs):
|
|
40
|
+
self.args = args
|
|
41
|
+
self.kwargs = kwargs
|
|
42
|
+
self.input_data = None
|
|
43
|
+
self.closed = False
|
|
44
|
+
type(self).instances.append(self)
|
|
45
|
+
|
|
46
|
+
async def process(self, input_data):
|
|
47
|
+
self.input_data = input_data
|
|
48
|
+
return type(self).result_builder(input_data)
|
|
49
|
+
|
|
50
|
+
async def close(self):
|
|
51
|
+
self.closed = True
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@pytest.fixture()
|
|
55
|
+
def fake_processor(monkeypatch):
|
|
56
|
+
FakeProcessor.instances = []
|
|
57
|
+
FakeProcessor.result_builder = _no_lead_results
|
|
58
|
+
monkeypatch.setattr(cli, 'Processor', FakeProcessor)
|
|
59
|
+
return FakeProcessor
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def test_run_exits_without_targets(monkeypatch, capsys, fake_processor):
|
|
63
|
+
monkeypatch.setattr(sys, 'argv', ['yasint'])
|
|
64
|
+
|
|
65
|
+
with pytest.raises(SystemExit) as exc_info:
|
|
66
|
+
cli.run()
|
|
67
|
+
|
|
68
|
+
assert exc_info.value.code == 1
|
|
69
|
+
assert fake_processor.instances == []
|
|
70
|
+
assert 'There are no targets to check!' in capsys.readouterr().out
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def test_run_processes_positional_targets_and_closes_processor(monkeypatch, capsys, fake_processor):
|
|
74
|
+
monkeypatch.setattr(
|
|
75
|
+
sys,
|
|
76
|
+
'argv',
|
|
77
|
+
[
|
|
78
|
+
'yasint',
|
|
79
|
+
'--no-progressbar',
|
|
80
|
+
'--no-color',
|
|
81
|
+
'--proxy',
|
|
82
|
+
'socks5://127.0.0.1:1080',
|
|
83
|
+
'--cookie-jar-file',
|
|
84
|
+
'cookies.txt',
|
|
85
|
+
'login',
|
|
86
|
+
PUBLIC_ID,
|
|
87
|
+
],
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
cli.run()
|
|
91
|
+
|
|
92
|
+
assert len(fake_processor.instances) == 1
|
|
93
|
+
processor = fake_processor.instances[0]
|
|
94
|
+
assert processor.kwargs == {
|
|
95
|
+
'no_progressbar': True,
|
|
96
|
+
'no_color': True,
|
|
97
|
+
'proxy': 'socks5://127.0.0.1:1080',
|
|
98
|
+
'cookie_file': 'cookies.txt',
|
|
99
|
+
}
|
|
100
|
+
assert [(i.value, i.identifier_type) for i in processor.input_data] == [
|
|
101
|
+
('login', 'username'),
|
|
102
|
+
(PUBLIC_ID, 'yandex_public_id'),
|
|
103
|
+
]
|
|
104
|
+
assert processor.closed is True
|
|
105
|
+
|
|
106
|
+
out = capsys.readouterr().out
|
|
107
|
+
assert 'Target: login (username)' in out
|
|
108
|
+
assert f'Target: {PUBLIC_ID} (yandex_public_id)' in out
|
|
109
|
+
assert out.count('Leads found: 0') == 2
|
|
110
|
+
assert 'Total leads found: 0' in out
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def test_run_reads_targets_from_stdin(monkeypatch, fake_processor):
|
|
114
|
+
monkeypatch.setattr(sys, 'argv', ['yasint', '--targets-from-stdin', '--silent', '--no-progressbar'])
|
|
115
|
+
monkeypatch.setattr(sys, 'stdin', io.StringIO('alpha\nbeta@yandex.ru\n'))
|
|
116
|
+
|
|
117
|
+
cli.run()
|
|
118
|
+
|
|
119
|
+
processor = fake_processor.instances[0]
|
|
120
|
+
assert [(i.value, i.identifier_type) for i in processor.input_data] == [
|
|
121
|
+
('alpha', 'username'),
|
|
122
|
+
('beta', 'username'),
|
|
123
|
+
]
|
|
124
|
+
assert processor.closed is True
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def test_run_reads_target_list_and_writes_requested_reports(monkeypatch, capsys, tmp_path, fake_processor):
|
|
128
|
+
target_file = tmp_path / 'targets.txt'
|
|
129
|
+
txt_file = tmp_path / 'report.txt'
|
|
130
|
+
csv_file = tmp_path / 'report.csv'
|
|
131
|
+
target_file.write_text('login\nperson@yandex.ru\n', encoding='utf-8')
|
|
132
|
+
fake_processor.result_builder = _lead_results
|
|
133
|
+
monkeypatch.setattr(
|
|
134
|
+
sys,
|
|
135
|
+
'argv',
|
|
136
|
+
[
|
|
137
|
+
'yasint',
|
|
138
|
+
'--target-list',
|
|
139
|
+
str(target_file),
|
|
140
|
+
'--silent',
|
|
141
|
+
'--no-progressbar',
|
|
142
|
+
'-oT',
|
|
143
|
+
str(txt_file),
|
|
144
|
+
'-oC',
|
|
145
|
+
str(csv_file),
|
|
146
|
+
],
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
cli.run()
|
|
150
|
+
|
|
151
|
+
processor = fake_processor.instances[0]
|
|
152
|
+
assert [i.value for i in processor.input_data] == ['login', 'person']
|
|
153
|
+
|
|
154
|
+
out = capsys.readouterr().out
|
|
155
|
+
assert 'Target:' not in out
|
|
156
|
+
assert f'Results were saved to file {csv_file}' in out
|
|
157
|
+
assert f'Results were saved to file {txt_file}' in out
|
|
158
|
+
|
|
159
|
+
text = txt_file.read_text()
|
|
160
|
+
assert 'Target: login (username)' in text
|
|
161
|
+
assert 'Target: person (username)' in text
|
|
162
|
+
assert 'Leads found: 1' in text
|
|
163
|
+
assert 'Requests:' in text
|
|
164
|
+
assert 'Music: GET https://music.yandex.ru/handlers/library.jsx?owner=login' in text
|
|
165
|
+
|
|
166
|
+
with csv_file.open(newline='') as f:
|
|
167
|
+
rows = list(csv.DictReader(f))
|
|
168
|
+
|
|
169
|
+
assert [row['Target'] for row in rows] == ['login (username)', 'person (username)']
|
|
170
|
+
assert [row['Leads Found'] for row in rows] == ['Yes', 'Yes']
|
|
171
|
+
assert [row['Username'] for row in rows] == ['login', 'person']
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def test_run_writes_auxiliary_reports_for_session_outputs(monkeypatch, capsys, tmp_path, fake_processor):
|
|
175
|
+
session_dir = tmp_path / 'reports' / 'session'
|
|
176
|
+
session_dir.mkdir(parents=True)
|
|
177
|
+
|
|
178
|
+
def session_results(input_data):
|
|
179
|
+
return _lead_results(input_data, session_dir=str(session_dir))
|
|
180
|
+
|
|
181
|
+
fake_processor.result_builder = session_results
|
|
182
|
+
monkeypatch.setattr(sys, 'argv', ['yasint', '--no-progressbar', '--no-color', 'login'])
|
|
183
|
+
|
|
184
|
+
cli.run()
|
|
185
|
+
|
|
186
|
+
aux_txt = session_dir / 'auxiliary_report.txt'
|
|
187
|
+
aux_csv = session_dir / 'auxiliary_report.csv'
|
|
188
|
+
assert aux_txt.exists()
|
|
189
|
+
assert aux_csv.exists()
|
|
190
|
+
assert f'Reports session: {session_dir}' in aux_txt.read_text()
|
|
191
|
+
|
|
192
|
+
out = capsys.readouterr().out
|
|
193
|
+
assert f'Reports session: {session_dir}' in out
|
|
194
|
+
assert f'Results were saved to file {aux_txt}' in out
|
|
195
|
+
assert f'Results were saved to file {aux_csv}' in out
|