WithSecureLabs / needle

The iOS Security Testing Framework
https://mobiletools.mwrinfosecurity.com/
Other
1.32k stars 283 forks source link

Module checks if files exist in wrong output directory #31

Closed tghosth closed 7 years ago

tghosth commented 7 years ago

Issue

Module checks if files exist in wrong output directory

Expected behaviour

When you run a module, it should check if files already exist in the output directory which was specified before running the module and warns appropriately.

Actual behaviour

When you run a module, it checks if files already exist in the default/global output directory even if a different output directory was specified before running the module.

See: [D] Setup local output folder: /root/.needle/output in the log below

Note that the files still get saved in the expected directory.

Steps to reproduce

See logs

needle error logs

root@kali:~/Work# python ./needle/needle/needle.py -r blank_config.txt 

             __   _ _______ _______ ______         _______
             | \  | |______ |______ |     \ |      |______
             |  \_| |______ |______ |_____/ |_____ |______

                   Needle v0.0.3 [mwr.to/needle]                  
  [MWR InfoSecurity (@MWRLabs) - Marco Lancini (@LanciniMarco)]   

[*] Loading commands from resource file
[needle] > set IP 192.168.123.102
IP => 192.168.123.102
[needle] > set PORT 22
PORT => 22
[needle] > set DEBUG True
DEBUG => True
[needle] > set VERBOSE True
VERBOSE => True
[needle] > set SETUP_DEVICE False
SETUP_DEVICE => False
[needle] > EOF
[+] Resource file successfully loaded
[needle] > use storage/caching/screenshot
[needle][screenshot] > info

      Name: Screenshot Caching.
      Path: modules/storage/caching/screenshot.py
    Author: @LanciniMarco (@MWRLabs)

Description:
  Test whether if, when the application's process is moved to the background, sensitive information
  could be cached on the file system in the form of a screenshot of the application's main window

Options:
  Name    Current Value         Required  Description
  ------  -------------         --------  -----------
  OUTPUT  /root/.needle/output  yes       Full path of the output file
  PULL    True                  yes       Automatically pull screenshots from device

[needle][screenshot] > set OUTPUT /root/Work/test
OUTPUT => /root/Work/test
[needle][screenshot] > info

      Name: Screenshot Caching.
      Path: modules/storage/caching/screenshot.py
    Author: @LanciniMarco (@MWRLabs)

Description:
  Test whether if, when the application's process is moved to the background, sensitive information
  could be cached on the file system in the form of a screenshot of the application's main window

Options:
  Name    Current Value    Required  Description
  ------  -------------    --------  -----------
  OUTPUT  /root/Work/test  yes       Full path of the output file
  PULL    True             yes       Automatically pull screenshots from device

[needle][screenshot] > run
[D] Setup local output folder: /root/.needle/output
[?] Attention! The folder chosen to store local output is not empty: /root/.needle/output
[?] Do you want to back it up first?
[?] Y: the content will be archived in a different location, then the folder will be emptied
[?] N: no action will be taken (destination files might be overwritten in case of filename clash)
[y/n]: n
[*] Checking connection with device...
[V] Connection not present, creating a new instance
[V] Setting up SSH connection...
[+] Connected to: 192.168.123.102
[V] Creating temp folder: /var/root/needle/
[D] [REMOTE CMD] Remote Command: if [ -d /var/root/needle/ ]; then echo "yes"; else echo "no" ; fi
[D] [REMOTE CMD] Remote Command: mkdir /var/root/needle/
[*] Target app not selected. Launching wizard...
[D] [REMOTE CMD] Remote Command: if [ -f /var/mobile/Library/MobileInstallation/LastLaunchServicesMap.plist ]; then echo "yes"; else echo "no" ; fi
[V] Refreshing list of installed apps...
[D] [REMOTE CMD] Remote Command: /bin/su mobile -c /usr/bin/uicache
[D] [REMOTE CMD] Remote Command: cp /var/mobile/Library/MobileInstallation/LastLaunchServicesMap.plist /var/root/needle/LastLaunchServicesMap.plist
[D] [REMOTE CMD] Remote Command: plutil -convert xml1 /var/root/needle/LastLaunchServicesMap.plist
[D] [REMOTE CMD] Remote Command: cat /var/root/needle/LastLaunchServicesMap.plist
[+] Apps found:
        0 - <<REDACTED>>
        1 - <<REDACTED>>
        2 - com.nutecapps.PortScan
        3 - <<REDACTED>>
        4 - <<REDACTED>>
        5 - <<REDACTED>>
        6 - com.twocanoes.cert
        7 - <<REDACTED>>
Please select a number: 2
[+] Target app: com.nutecapps.PortScan
[*] Retrieving app's metadata...
[D] [REMOTE CMD] Remote Command: cp '/private/var/mobile/Containers/Bundle/Application/0D252B74-8FE9-48D6-B907-0EAFA3EA5C8F/Port Scan.app/Info.plist' /var/root/needle/Info.plist
[D] [REMOTE CMD] Remote Command: plutil -convert xml1 /var/root/needle/Info.plist
[D] [REMOTE CMD] Remote Command: cat /var/root/needle/Info.plist
[D] [REMOTE CMD] Remote Command: lipo -info '/private/var/mobile/Containers/Bundle/Application/0D252B74-8FE9-48D6-B907-0EAFA3EA5C8F/Port Scan.app/Port Scan'
[V] Creating timestamp file...
[D] [REMOTE CMD] Remote Command: touch /var/root/needle/timestamp-caching-snapshot
[*] Launching the app...
[D] [REMOTE CMD] Remote Command: open com.nutecapps.PortScan
[*] Background the app by hitting the home button, then press enter: 

[*] Checking for new screenshots...
[D] [REMOTE CMD] Remote Command: find /private/var/mobile/Containers/Data/Application/15023E12-2E57-470F-98E9-F357653417FC/Library/Caches/Snapshots/ -type f -newer /var/root/needle/timestamp-caching-snapshot | sort -u
[+] Screenshots found:
[+]     /private/var/mobile/Containers/Data/Application/15023E12-2E57-470F-98E9-F357653417FC/Library/Caches/Snapshots/com.nutecapps.PortScan/0420DAF9-2E57-403B-B262-BD085DD757E3@2x.png
[+]     /private/var/mobile/Containers/Data/Application/15023E12-2E57-470F-98E9-F357653417FC/Library/Caches/Snapshots/com.nutecapps.PortScan/downscaled/E0DD704E-7DF5-430D-8B2C-11C93544EE85@2x.png
[+] Retrieving screenshots and saving them in: /root/Work/test
[D] Downloading: "/private/var/mobile/Containers/Data/Application/15023E12-2E57-470F-98E9-F357653417FC/Library/Caches/Snapshots/com.nutecapps.PortScan/0420DAF9-2E57-403B-B262-BD085DD757E3@2x.png" -> "/root/Work/test/0420DAF9-2E57-403B-B262-BD085DD757E3@2x.png"
[D] [LOCAL CMD] Local Command: sshpass -p "alpine" scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -P 22 root@192.168.123.102:"/private/var/mobile/Containers/Data/Application/15023E12-2E57-470F-98E9-F357653417FC/Library/Caches/Snapshots/com.nutecapps.PortScan/0420DAF9-2E57-403B-B262-BD085DD757E3@2x.png" "/root/Work/test/0420DAF9-2E57-403B-B262-BD085DD757E3@2x.png"
[D] [LOCAL CMD] Local Command: eog "/root/Work/test/0420DAF9-2E57-403B-B262-BD085DD757E3@2x.png"
[D] Downloading: "/private/var/mobile/Containers/Data/Application/15023E12-2E57-470F-98E9-F357653417FC/Library/Caches/Snapshots/com.nutecapps.PortScan/downscaled/E0DD704E-7DF5-430D-8B2C-11C93544EE85@2x.png" -> "/root/Work/test/E0DD704E-7DF5-430D-8B2C-11C93544EE85@2x.png"
[D] [LOCAL CMD] Local Command: sshpass -p "alpine" scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -P 22 root@192.168.123.102:"/private/var/mobile/Containers/Data/Application/15023E12-2E57-470F-98E9-F357653417FC/Library/Caches/Snapshots/com.nutecapps.PortScan/downscaled/E0DD704E-7DF5-430D-8B2C-11C93544EE85@2x.png" "/root/Work/test/E0DD704E-7DF5-430D-8B2C-11C93544EE85@2x.png"
[D] [LOCAL CMD] Local Command: eog "/root/Work/test/E0DD704E-7DF5-430D-8B2C-11C93544EE85@2x.png"

Environment

Workstation Operating System

Kali 2016.2

Python Version

2.7.12+

Python Packages (pip freeze)

root@kali:~/Work# pip freeze
Warning: cannot find svn location for chirp===daily-20160717
adns-python==1.2.1
AdvancedHTTPServer==2.0.5
alembic==0.8.7.dev0
anyjson==0.3.3
argcomplete==1.0.0
argh==0.26.1
attrs==16.0.0
backports-abc==0.4
backports.ssl-match-hostname==3.5.0.1
basemap==1.0.7
BBQSQL==1.0
BeautifulSoup==3.2.1
beautifulsoup4==4.5.1
blessings==1.6
BlindElephant==1.0
blinker==1.3
boltons==16.2.2
capstone==3.0.4
certifi==2016.2.28
cffi==1.7.0
chardet==2.3.0
Cheetah==2.4.4
## FIXME: could not find svn URL in dependency_links for this package:
chirp===daily-20160717
clamd==1.0.1
click==6.6
cluster==1.3.3
colorama==0.3.7
ConfigArgParse==0.10.0
configobj==5.0.6
configparser==3.3.0.post2
construct==2.5.2
couchdbkit==0.6.5
cryptography==1.5
cycler==0.10.0
d2to1==0.2.12
dap==2.2.6.7
darts.util.lru==0.5
decorator==4.0.6
defusedxml==0.4.1
dicttoxml==1.6.6
dissy==9
distorm3==3.3.4
dnspython==1.14.0
docutils==0.12
easygui==0.96
Elixir==0.7.1
enum34==1.1.6
esmre==0.3.1
feedparser==5.1.3
Flask==0.11.1
FormEncode==1.3.0
frida==7.3.5
funkload==1.16.1
fuse-python==0.2.1
future==0.15.2
futures==3.0.5
GeoIP==1.3.2
geoip2==2.2.0
geojson==1.3.1
gevent==1.1.1
gitdb==0.6.4
GitPython==2.0.5
greenlet==0.4.10
guess-language-spirit==0.5.2
h2==2.1.1
halberd==0.2.4
hpack==2.3.0
html2text==2016.5.29
html5lib==0.999
http-parser==0.8.3
httplib2==0.9.1
httpretty==0.8.14
hyperframe==3.2.0
icalendar==3.8
idna==2.1
impacket==0.9.13
ipaddr==2.1.11
ipaddress==1.0.16
IPy==0.83
ipython==2.4.1
itsdangerous==0.24
jdcal==1.0
Jinja2==2.8
jsonpickle==0.9.3
jsonrpclib==0.1.3
keepnote==0.7.8
killerbee==1.0
lxml==3.6.4
M2Crypto==0.24.0
Mako==1.0.4
Markdown==2.6.6
MarkupSafe==0.23
matplotlib==1.5.2rc2
maxminddb==1.2.1
mechanize==0.2.5
mercurial==3.8.4
metaconfig==0.1.4a1
mitmproxy==0.17.1
mockito==0.5.2
msgpack-python==0.4.8
mysqlclient==1.3.7
nassl==0.12
ndg-httpsclient==0.4.2
netaddr==0.7.18
NfSpy==1.0
nltk==3.2.1
numpy==1.11.1rc1
olefile==0.42.1
openpyxl==2.3.0
PAM==0.4.2
paramiko==2.0.0
passlib==1.6.5
Paste==2.0.3
PasteDeploy==1.5.2
PasteScript==1.7.5
pathtools==0.1.2
pcapy==0.10.8
pdfminer==20140328
pefile==2016.3.28
pexpect==4.2.0
phply==0.9.1
Pillow==3.3.0
pluginbase==0.4
ply==3.7
prettytable==0.7.2
prompt-toolkit==1.0.7
psutil==4.2.0
psycopg2==2.6.2
ptyprocess==0.5.1
py==1.4.31
pyasn1==0.1.9
pyasn1-modules==0.0.7
pybloomfiltermmap==0.3.15
pycparser==2.14
pycrypto==2.6.1
pycryptopp==0.6.0.1206569328141510525648634803928199668821045408958
pycurl==7.43.0
pydns==2.3.6
pyenchant==1.6.7
PyGithub==1.23.0
Pygments==2.1.3
pygobject==3.20.1
pyinotify==0.9.6
pylibemu==0.3.3
pymssql==1.0.2
pyOpenSSL==16.0.0
pyotp==2.1.1
pyparsing==2.1.8
pyPdf==1.13
PyPDF2==1.26.0
pyperclip==1.5.27
pyregfi==1.0.1.0
pyrit==0.4.0
pyscard==1.9.4
pyserial==3.1
pysnmp==4.3.2
pysnmp-apps==0.3.2
pysnmp-mibs==0.1.3
PySocks==1.5.7
pysqlite==2.7.0
pytest==2.9.2
python-apt==1.1.0b4
python-dateutil==2.4.2
python-debian==0.1.29
python-debianbts==2.6.1
python-editor==0.4
python-Levenshtein==0.12.0
python-ntlm==1.1.0
python-openid==2.2.5
python-pam==1.8.2
python-ptrace==0.7
pytz==2015.7
pyusb==1.0.0b2
PyX==0.12.1
pyxdg==0.25
PyYAML==3.11
qrcode==5.3
readline==6.2.4.1
reportbug==6.6.6
requests==2.10.0
restkit==4.2.2
rfidiot==1.0
roman==2.0.0
ruamel.ordereddict==0.4.9
scapy==2.3.2
scgi==1.13
scipy==0.18.0
service-identity==16.0.0
simplegeneric==0.8.1
simplejson==3.8.2
singledispatch==3.4.0.3
six==1.10.0
slowaes==0.1a1
smmap==0.9.0
smoke-zephyr==1.0.2
SOAPpy==0.12.22
socketpool==0.5.3
SQLAlchemy==1.0.14
sshtunnel==0.1.0
stopit==1.1.0
tblib==1.3.0
tcpwatch==1.3.1
Tempita==0.5.2
termcolor==1.1.0
tornado==4.4.1
Twisted==16.3.0
tzlocal==1.2.2
urllib3==1.15.1
urwid==1.3.1
uTidylib==0.3
vinetto==0.7b0
volatility==2.5
vulndb==0.0.19
wafw00f==0.9.3
wapiti==2.3.0
watchdog==0.8.3
wcwidth==0.1.7
webunit==1.3.10
Werkzeug==0.11.10
wfuzz==0.0.0
Whoosh==2.7.0
wstools==0.4.3
wxPython==3.0.2.0
wxPython-common==3.0.2.0
xdot==0.5
XlsxWriter==0.7.3
xmlbuilder==1.0
yara-python==3.5.0
zenmap==7.25b2
zim==0.65
zope.interface==4.2.0

Device iOS Version

9.2

marco-lancini commented 7 years ago

Hi @tghosth, thanks for reporting this. Needle now supports a new global option (OUTPUT_FOLDER) which can be used to define what folder is going to be used globally to store the output created by the modules. In addition, there is still the possibility to customize the output of each module by modifying its local OUTPUT variable.

Now, the first module run after startup will trigger a check that will test if the global output folder exists and is empty. This does not apply to the folders/files specified manually in the options of a module (especially cause it can be tedious to manually confirm the operation every time).

Does it make any sense to you? I would like to hear your opinion as well.

tghosth commented 7 years ago

hi @marco-lancini, firstly I think the global output feature is a great idea and will save a lot of time :)

However, if I run a module having specified a different output folder, it doesn't make sense to me that it checks the global output folder. To my mind, it should check the global output folder the first time it uses the global output folder and if I run a module with a different folder, the check should be deferred.

Thanks,

marco-lancini commented 7 years ago

Just deferred or would you suggest to check also that "different" folder?

tghosth commented 7 years ago

Good question. One idea would be to have a global option that basically controls whether the user gets prompted about non-empty output directories and that applies everywhere.

marco-lancini commented 7 years ago

Hi @tghosth, do you still want to implement this?

tghosth commented 7 years ago

To be honest I don't remember what the most recent version does for this. You could leave this open as a low priority fix or just close it for now if you prefer. Unfortunately I won't have time to look at it in the next few weeks...