Imagine each and every port that is open on your computer as a potential door to your computer, for malicious person.

Every single door more is one more potential door your attacker can open.

So, what can you do after this?

1. Know your computer networking

To see all of TCP the ports open on your computer, use this command:

1
netstat -tlpn

For UDP ports, use:

1
netatal -ulpn

1.1 What to look for?

First thing you need to look at is at which interface program is listening at.

First figure out which IP is on which interface.

For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
$ ifconfig
enp0s25: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
ether 3c:97:0e:0f:5c:6b txqueuelen 1000 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
device memory 0xe1600000-e1620000
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 1099393 bytes 2018987222 (1.8 GiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1099393 bytes 2018987222 (1.8 GiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
tun0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST> mtu 1304
inet6 fc15:9d75:e614:a0e1:17a0:61d4:341d:b5dd prefixlen 8 scopeid 0x0<global>
inet6 fe80::c39b:ac2a:eac6:6ab9 prefixlen 64 scopeid 0x20<link>
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 500 (UNSPEC)
RX packets 32 bytes 2728 (2.6 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 69 bytes 4400 (4.2 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
wlp2s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.1.17 netmask 255.255.255.0 broadcast 192.168.1.255
inet6 fe80::95de:a8ca:ddb9:ac84 prefixlen 64 scopeid 0x20<link>
ether 1e:93:85:2d:6a:b7 txqueuelen 1000 (Ethernet)
RX packets 3893447 bytes 3986568321 (3.7 GiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 2923905 bytes 733067221 (699.1 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
wwp0s20u4i6: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
ether 02:15:e0:ec:01:00 txqueuelen 1000 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

This is my ifconfig output.

If you do not have ifconfig command, you can also use ip addr.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp0s25: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel state DOWN group default qlen 1000
link/ether 3c:97:0e:0f:5c:6b brd ff:ff:ff:ff:ff:ff
3: wlp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 1e:93:85:2d:6a:b7 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.17/24 brd 192.168.1.255 scope global dynamic noprefixroute wlp2s0
valid_lft 49655sec preferred_lft 49655sec
inet 192.168.1.254/24 brd 192.168.1.255 scope global secondary noprefixroute wlp2s0
valid_lft forever preferred_lft forever
inet6 fe80::95de:a8ca:ddb9:ac84/64 scope link noprefixroute
valid_lft forever preferred_lft forever
4: wwp0s20u4i6: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel state DOWN group default qlen 1000
link/ether 02:15:e0:ec:01:00 brd ff:ff:ff:ff:ff:ff
19: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1304 qdisc fq_codel state UNKNOWN group default qlen 500
link/none
inet6 fc15:9d75:e614:a0e1:17a0:61d4:341d:b5dd/8 scope global
valid_lft forever preferred_lft forever
inet6 fe80::c39b:ac2a:eac6:6ab9/64 scope link stable-privacy
valid_lft forever preferred_lft forever

So, in my case, I am connected to wifi and my IP is 192.168.1.17.

I am also connected to VPN and IP is fc15:9d75:e614:a0e1:17a0:61d4:341d:b5dd.

If application is listening at 0.0.0.0 or ::, that means it is listening on all interfaces.

If application is listening at 127.0.0.1 or ::1, that means it is listening only on a virtual loopback device.

To figure out which application it is, take a look at PID/Program name row.

If there is no name for program, run command as root.

If PID is 1, that probbably means systemd is forwarding file socket to TCP/UDP port.

1.2 What do you want to accomplish?

You probably do dot want applications listening on any other interface except loopback if it does not have to.

Comment and share

When you open your web browser and type pornhub.com into your address bar, what happens in most networks is, your PC asks your router: “Hey, router, what is the address of pornhub.com? “ In case your router knows the address, it will send the response to you. If it does not know, it will ask your ISPs DNS server.

In short, admin of your network, anyone sniffing your network and yourt ISP know you have just visited pornhub…

And, in the case someone is doing MITM attack, they can even change the response to your query.

What the best solution currently is to use dnscrypt.

If you are Arch linux user like myself, you can just install it from the repo:

1
sudo pacman -S dnscrypt-proxy

After that, You need to enable its socker.

1
sudo systemctl enable dnscrypt-proxy.socker

NOTE: Keep in mind that at the momment I am writing this blog post, socket is brocken in the latest version of dnscrypt-proxy, so, you will need to use service instead or to install dnscrypt 2.0.14-2…

When you have enabled dnscrypt-proxy.socker, now, you need to make your computer use DNSCrypt DNS as main DNS.

On arch, we use resolvconf to generate resolv.conf.

To set your DNS to localhost, you need to edit /etc/resolvconf.conf and set:

1
name_servers=127.0.0.1

Only one more thing to do is to change your DNSCrypt DNS servers.

I love to use opennic ones, so, I set them to: (/etc/dnscrypt-proxy/dnscrypt-proxy.toml):

1
server_names = ['opennic-luggs', 'fvz-anyone', 'opennic-famicoman']

Comment and share

When you connect your computer to new network, what it does to acquire networking settings like Gateway, DNS, network mask, etc. is it uses DHCP protocol.

If you ever logged into router settings or tried sniffing DHCP traffic, what you would see is there you can see hostname of computer that is connecting.

Why is that a bad thing? Well, does everyone on network has to know who you are, when you, for example, connect to local coffee shop WiFi?

So, what is the solution?

For linux users (if your distro is using dhcpclient), just comment out hostname line in your /etc/dhcpcd.conf.

Comment and share

I have spent a lot of time thinking about some of the latest social media data leaks and figured out one thing.

People say they care, they get scared when they see what happened, but, they are not scared enough to change anything, they are just ready to blame everyone else.

What happened with Facebook and Cambridge Analytica?

In this post, I am not going to write about what they did with data, but, how did leak happen.

Zuckenbergs story

According to Mark Zuckenberg, data was stolen using Facebook Application with more permissions than required for them to work.

My opinion is that is 100% fault of users even if Facebook could have done validation for Application like that to check if that Application needs what it requires.

I am really sorry, but, you can not just blame someone else for your own carelessness…

“But, I did not leak my own data, they sold it”

Now, we come to even more important point…

According to some, what Zuckenberg said is a lie. They claim Facebook has sold their data.

Guess what? You gave your data willingly to Facebook.

Hacker community has been talking about this for years now.

You are relying on company who is in business of selling your own data for marketing purposes to keep your data safe.

It is your own fault.

What can be improved in your security?

This post is under construction

Now, lets talk about how we can improve security.

Chat

First lets talk about most popular chats.

Facebook

Facebook messenger

According to some, Facebook now uses “end to end encryption” and, they are safe.

For end to end encryption to work, one user needs to be able to encrypt message using one key and another needs to be able to decrypt that message using same or different key, depending on type of encryption algorithm used.

But, who stores the key?

Facebook does. So, there is end to end decryption they can decrypt.

You want proof?

You can read your messages on other devices. And you do not have to store your own key.

Whatsapp

Now, there is whatsapp, where you can read chats only on one device, unless you enable Web Application for whatsapp chat.

Guess what happens then? You are sending those same messages you used end to end encryption on unencrypted to your web browser.

And, that is not even the worst part.

When you are encrypting your messages, whatsapp servers are doing key exchange.

What does that mean?

There can be end to end encryption from you to whatsapp and from whatsapp to your friend, and, you can not ever notice that since you can not verify keys…

But, wait, Whatsapp does not store my chats, or does it?

They say they do not store your chats, but, they do a “backup” for you, so, you do not lose your chats…

Instagram

Instagram does not even claim they have any kind of security.

Viber

Viber is as big of a joke as messenger. Only difference is that they claim they do not store user data.

Comment and share

Hi guys,

This is something I encounter on daily basis, so, I decided to write a little bit about how I solve this problem in javascript.

Let’s say I have Array of objects and want to normalize it for inserting into database.

Some object might miss some data, some arguments might need to be processed, etc. and this code can get really messy sometimes.

What our goal here is to try to avoid putting column list 5 times and try to do it with as less code as possible.

I tried a lot of different ways to do this and this is the one I like the most.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
let people = [
{
name: "Petar Petrovic"
},
{
firstName: "Petar",
lastName: "Petrovic"
},
{
name: "Petar Petrovic",
hasMedicalProblems: true,
someRandomDataWeDoNotNeed: 12231232
}
];
let head = {
"name": function(person){
return person.name | (person.firstName + person.lastName) | "Unknown";
},
"hasMedicalProblems": function(person){
return person.hasMedicalProblems | false;
}
}
people = people.map(function(person){
let newObject = {};
Object.keys(head).forEach(function(key){
newObject[key] = head[key](person);
});
return newObject;
});
console.log(JSON.stringify(people, null, 4));

Comment and share

portforward using ssh

If you ever had to do portforwarding on network that was not yours, you know it can be pain in the ass sometimes and you most probbably do not want to deal with it. o

This method is very easy to do and will allow you to expose your port to public and even stop local computers from sniffing data to and from that port.

How is this done in theory

Well, if you ever used SSH, you probbaly know it is just encrypted tunnel…

What you maybe did not know is that it can carry a lot more than text. (you cna use it to copy files, to open graphical application, as a SOCKS proxy, etc.)

One of things a lot of people do not know about is that you can also use SSH to forward ports from one side of tunnel to another…

Lets say your computer can access some port and someone in network you are connecting to can not…

What you can do is specify port forwarding in SSH configuration.

Let’s say you want to forward local port to WAN…

What happens is remote machine you are connected to will listen on specified port and when someone connect to that port, your computer will connect to local port and data will be tunneled inside SSH.

How to do this in practice

This is actually very simple

1
ssh -R 221:localhost:22 server

This will make server listen on port 221 and when someone connects to it, you will connect to localhost:22 and connection will be established.

One small trick is that in OpenSSH (implementation of SSH cost often used) server will listen only on loopback interface (localhost) and not on other interfaces.

To solve this, we need to add:

1
GatewayPorts yes

to the end of /etc/ssh/sshd_config and restart SSH server. (systemctl restart sshd for SystemD or service ssh restart)

Comment and share

phpfbsession

phpfbsession

Script for maintaining session from browser for facebook automation

Adding session

First, you need to get cookies from your web browser.

To do that, I would recommend cookies.txt

After you got your cookies, you should run:

1
php addAccount.php

Now, paste cookies and pres Enter twice!

Keeping session in working order?

To keep session in working order make sure you do not log out in browser or simply delete cookies in browser.

How to get something from facebook?

1
2
3
4
5
6
7
8
9
10
11
<?php
require_once("./vendor/autoload.php");
require_once("./Config.php");
require_once("./Parser.php");
$config = new Config;
$parser = new Parser($config->get("accounts"));
echo $parser->get("https://www.facebook.com/");

CLI menu

If you prefer to run CLI menu, you can do so by:

1
php index.php

Troubleshooting

I have problem with session, what do I do?

1
php checkAccounts.php

If problem stays, just delete that account from config.json and readd it.

Authors

Comment and share

Hi guys,

I created a few applications that stream torrents, so, I get asked quite a bit about it.

Today I am going to write a little bit about how it works and how to utilize it.

Where do I get torrents from?

First of all, to get torrents, you can use search engine/file someone sent you/create your own torrent…

So, what torrent file/megnet link is?

When you get torrent in any form, what you actually get is hash of that torrent.

It can be either looked up on Torrent trackers (web services) or DHT (distributed hash table).

The part that is actually looked up is hash of that torrent.

That hash is used to identify and verify that data integrity.

What do we do with data from tracker/DHT?

What we get from DHT is list of peers that have torrent we are looking for.

What happens next is we download data about torrent from those peers. (File list, sizes, etc.)

Ok, how do we download files now?

What is happening now is we are reaching out to peers and they are offering parts they have.

For streaming, we are simply accepting parts that are near area we need and deny those that we do not need at the momment.

How can we implement it?

If you are writing your application in Node.JS, what I would recommend to you is torrent-stream package. It has very simple API and it is very easy to pass it through HTTP layer.

If you are writing your application in any other language, I would recommend using peerflix which is CLI version of torrent-stream.

Comment and share

Audio scaling

Hi guys, what I had to do few days ago is dynamically change speed of audio playback.

Terminology

Sample is sound amplitude.

Audio file is just encoded/compressed list of samples.

Samplerate is number of samples per second. (the one I will be using is 44100)

Buffer is Array of samples that are going to go out of your speaker. (Common sizes are 256, 512, 1024, etc. sample rates)

What did I end up using?

Technology I was using for that is Web Audio API.

AudioNode

AudioNode is basicaly Object which you pipe audio into and/or get audio out of it.

AudioNodes connect to each other just like any audio equipment would in real life.

For example you maybe have microphone, speaker, spectrum analyzer with passthrough and amplifier.

You can connect for example microphone -> amplifier -> spectrum analyzer -> speaker

Getting audio inside system

What most of the people in Web Audio API would use if they wanted to play music inside it is MediaElementAudioSourceNode (implementation of AudioNode that gets sound from HTML5 audio tag).

It simply plays audio and that is it.

Problem with this one is that it is impossible to change speed. (might be possible to slow it down, but I did not find any ways to make it play music faster)

decodeAudioData

What I ended up doing is getting mp3 using XHR as ArrayBuffer and running decodeAudioData from audio context on it.

That gave me back buffer containing whole audio:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
module.exports = function(url){
return new Promise((resolve, reject) => {
const audioCtx = new (window.AudioContext || window.webkitAudioContext)(); // Getting audio context. Anything you do with Web Audio API requires use of audio context
const xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'arraybuffer'; // This will make sure I get response in format I need for passing it to Web Audio API
xhr.onload = function(e) {
var audioData = xhr.response;
audioCtx.decodeAudioData(audioData, function(buffer) { // This will decode that audio file and return buffer using callback.
resolve(buffer);
}, function(e){
reject(e);
});
};
xhr.send();
});
}

What I can do now is take data from buffer at any rate.

Scaling audio using input audio buffer

Now that I have list of amplitudes I can play that audio back.

Web Audio API does not have any way to generate sound, just process it (at least I did not find anything like that).

What I ended up doing is using ScriptProcessor (AudioNode for transforming sound).

I did not hook up any audio sources to it, just hooked it up to sink.

transformationFunction is function that is getting called each time you need to process audio. Inside it I am taking audio from music buffer and putting it into output buffer.

Calculating sample in output buffer

What I have is huge buffer that contains song and I have very small buffer I am writing to.

I have counter i which tells me where I am inside input buffer.

What I do is iterate inside output buffer and calculate what I want to take from input buffer for that sample.

Let’s say playback speed is 1.5.

What I need to put into output buffer are samples 1.5, 3, 4.5, etc.

But, there are samples 1 and 2, and there is no sample 1.5, what do I do now?

Well, what you can do is:

1
sample = 0.5 * input[0] + 0.5 * input[1];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
module.exports = function(audioCtx, buffer, outputNode){
let i = 0;
let cnt = 0;
let speed = {
speed: 1,
playing: 1,
buffer: undefined,
transformationFunction: function(audioProcessingEvent) {
let outputBuffer = audioProcessingEvent.outputBuffer;
let buffer = speed.buffer;
let oldI = i;
let end = false;
for(chan = 0; chan < 2; chan++){
i = oldI;
let position = 0;
let input = buffer.getChannelData(chan);
let out = outputBuffer.getChannelData(chan);
do {
i += speed.speed * speed.playing;
if(i < 0 || i >= input.length){
end = true;
speed.playing = false;
}
if(!end){
let floor = Math.floor(i);
let diff = i - floor;
out[position] = input[floor] * diff + input[floor + 1] * (1 - diff);
} else {
out[position] = 0;
}
position++;
} while(position < out.length);
}
},
init: function(audioCtx, buffer, outputNode){
const scriptNode = audioCtx.createScriptProcessor(512, 0, 2);
speed.buffer = buffer;
scriptNode.onaudioprocess = speed.transformationFunction;
scriptNode.connect(outputNode);
return speed;
}
}
return speed.init(audioCtx, buffer, outputNode);
}

Comment and share

Dokku

Dokku is extremly simple PaaS (platform as a service) .
Philosophy of this software is quite simple. It is as simple as possible clone of Heroku.

Advantage of system like this is that you do not have to (but you can) think about container application is going to run inside but only about application itself. All you need to do is git push and Dokku will make fully functional container out of it and deploy it.

What happends when I do git push?

First thing you need to know about Dokku, Heroku and similar software is that they use something called buildpacks. Buildpack is collection of additional software required to build and run your application. For example there is PHP buildpack that contains PHP, ngginx, apache, composer, etc.


What is buildpack and how do we use it?

Buildpack is collection of 3 scripts with specific role.

  • bin/detect - Role of this script is to detect if that buildpack was developed to be used with application like yours. This one is skiped if user already defined buildpack and is used for autodetect of language only.

  • bin/compile - Role of this script is to prepare your application for running (installing dependencies, building, minification or stuff like that)

  • bin/release - Role of this script is to tell which commands should you run to start this container.


As you have probbably already figured out, first we need to figure out which buildpack should be used for your application.

It can be either specified by user or detected by Dokku/Heroku/etc. by running all buildpacks against script until detect script returns true.

After that, compile script is run to prepare your application for deployment,

After that, for Dokku to be able to know how to run container, release return list of commands.

Example:

1
web: node index.js

If your application does not have Procfile, the one from release script will be used.

There is just one step left after this… Image is commited and ran.

The only remaining whing is communication between your application and outside world. For anyone to be able to connect to your application from outside, your application needs to listen on specific port.
For default http port, dokku is setting global variable called PORT to port number. (And nginx is used to proxy to your application)

You can also configure Dokku to forward other ports to your application.

What are advantages of system like this?

There are a lot advantages but thrse are the ones that got me to switch:

  • Consistent enviroment - You are sure your application will act the same way on any server that uses Dokku.

  • Easy deployment and fast first time configuration

  • There is big community and a lot of plugins for it.

Comment and share

Nemanja Nedeljković

I am just crazy guy who wants to be best fullstack developer.


Freelancer


Belgrade, Serbia