This is my code:
public class DatabaseHandler : MonoBehaviour
{
string url = "https://fakeid.firebaseio.com/";
void Start()
{
StartCoroutine(GetLevelsCoroutine());
}
IEnumerator GetLevelsCoroutine()
{
using (UnityWebRequest www = UnityWebRequest.Get(url))
{
www.SetRequestHeader("X-Firebase-Decoding", "1");
yield return www.SendWebRequest();
if (www.isDone)
{
Debug.Log(www.error);
string result = www.downloadHandler.text;
Debug.Log(result);
}
}
}
}
The result variable is null and the www.error is "unknown error"
I have been trying different things in order to fix this but, I just can't figure out what's causing this error, since it's just a generic error.
I have also read that this may be an unitywebrequest bug, if it is so, are there any alternatives?
Finally found the solution to the problem. (It only occurs on some Linux OS)
Unity only officially supports Ubuntu Linux, so it is looking (and failing to find) the certificate store where it would expect it to be. You can work around on Fedora by creating a symbolic link:
mkdir -p /etc/ssl/certs && ln -s /etc/pki/tls/certs/ca-bundle.crt /etc/ssl/certs/ca-certificates.crt
This is the source where I got it from: https://forum.unity.com/threads/ubuntu-headless-build-tls-handshake-fails.546704/
It seems like you're trying to get JSON from the Firebase Realtime Database through its REST API. Requests to the REST API must end in .json, otherwise Firebase interprets them as requests to open the console on that location. So UnityWebRequest.Get(url+.json)
I'm fairly new to Groovy & SoapUING. I hope someone can help me figure out and fix this error. Thanks!
What I'm trying to do: Iterate through each db row item in a table and use that as input to make a HTTPBuilder request (GET or POST) either as a query in path (add baseURL/path/hello) or through parameters(add baseURL/path?searchNode="hello"). The baseURL is something like this https://search-test-env.ser.com.
Where I'm getting stuck: When I try to post a request through HTTPBuilder.
Error: PKIX Path Building Failed
Other related information:
Using ReadyAPI to run the scripts. Code is in Groovy.
Recently imported the httpbuilder jar into ReadyAPI/lib folder along with some dependencies. Of the dependencies available with httpbuilder, ReadyAPI already had few so I only picked up the ones missing. Additional jar names: ojdbc6, ojdbc6_g, signpost-commonshttp4-1.2.1.1, ezmorph-1.0.6, json-lib-2.3-jdk15, xml-resolver-1.2, signpost-core-1.2.1.1, appengine-api-1.0-sdk-1.3.8, nekohtml-1.9.16, http-builder-0.7, http-builder-0.7-sources, http-builder-0.7-javadoc.
The Service works with a manual request without groovy (simple GET on the baseURL/path) and it also works with query by string or by parameter.
The certificate is already available in the Keystore. Tried using keytool (available in ReadyAPI/bin folder) command through cmd but receiving a filenotfound error). Tried to import into the ReadyAPI\jre\lib\security.
Code:
def qryPrmRqstHTTPBldr( pBaseUrl, pPath, pQuery, pMethod ) {
def ret = null
def http = new HTTPBuilder()
def meth
if ( pMethod == 'GET') {
meth = Method.GET
}
else if ( pMethod == 'POST') {
meth = Method.POST
}
// perform a GET/POST request, expecting TEXT response
http.request(pBaseUrl, meth, ContentType.TEXT) { req ->
uri.path = pPath
uri.query = pQuery
/*
headers.'User-Agent' = 'Apache-HttpClient/4.5.1 (Java/1.8.0_66)'
headers.'Host' = 'xxx-xx-xxx.xxx.xxx'
headers.'Accept-Encoding' = 'gzip,deflate'
headers.'Connection' = 'Keep-Alive'
*/
log.info System.getProperty("java.runtime.version")
log.info System.getProperty("javax.net.ssl.trustStore")
log.info System.getProperty("javax.net.ssl.keyStore")
log.info System.getProperty("java.home")
log.info System.getProperty("java.class.path")
// response handler for a success response code
response.success = { resp, reader ->
println "response status: ${resp.statusLine}"
println 'Headers: -----------'
ret = reader.getText()
println 'Response data: -----'
println ret
println '--------------------'
}
}
return ret
}
Running this code throws the PKIX Path Building Failed error (no stack trace available) and the content for each property:
System.getProperty("java.runtime.version") // 1.8.0_66-b17
System.getProperty("javax.net.ssl.trustStore") // null
System.getProperty("javax.net.ssl.keyStore") // null
System.getProperty("java.home") // c:\program files\smartbear\readyapi-1.6.0\jre
System.getProperty("java.class.path") // C:\Program Files\SmartBear\ReadyAPI-1.6.0\.install4j\i4jruntime.jar;......
The problem
PKIX path building failed error is thrown when your client can not construct a trust path to your server certificate. This basically means that in your trust store there isn't the certificate authority which issues the end entity certificate or a intermediate certificate for your server certificate; and it's needed to build the certificate chain.
In your case javax.net.ssl.trustStore it's not defined, due System.getProperty("javax.net.ssl.trustStore") is null; so from JSSE
If the system property: javax.net.ssl.trustStore is defined, then the
TrustManagerFactory attempts to find a file using the filename
specified by that system property, and uses that file for the
KeyStore. If the javax.net.ssl.trustStorePassword system property is
also defined, its value is used to check the integrity of the data in
the truststore before opening it. If javax.net.ssl.trustStore is
defined but the specified file does not exist, then a default
TrustManager using an empty keystore is created.
If the javax.net.ssl.trustStore system property was not specified,
then if the file <java-home>/lib/security/jssecacerts exists, that
file is used. (See The Installation Directory for
information about what refers to.)
Otherwise, If the file
<java-home>/lib/security/cacerts exists, that file is used.
The solution
Then to solve the problem you need to add the required certificates to JRE_HOME/lib/security/jssecacerts if exists or to JRE_HOME/lib/security/cacerts if not from the Java which are you using to run the Groovy scripts.
The correct way: Add the certificate authority of your server certificate in the trust store. Then make sure that your server correctly serves all certificate chain until CA: intermediate certificates (if needed) until the end entity server certificate.
The brute force way: If you've some problems setting up the trust store or you're not sure if the server is pushing the chain certificates... simply put directly the server certificate in the trust store. This is not the "purist" way but since you're only testing this will works.
How to do it
Download the CA server certificate and load it to the trust store using keytool with the follow command (the default password for cacerts is changeit):
keytool -import -alias <someAlias> -file <certificatePath> -keystore <trustStorePath>
Here there is one of my answers with a bit more detail about how to load the certificate.
I know it's rarely used, but is it possible to access the client certificate in Snap?
If not, is it possible using a different web stack?
This is not available to you in Snap's snap-server package, which I'm assuming is how you're running your server.
Buuuuut it's not difficult to build, either by forking or as a separate module (you'll have to copy some code over, though, since some internal values you'll need aren't exported). bindHttps, located in Snap.Internal.Http.Server.TLS, is what you want to target. This function is largely a wrapper around calls to OpenSSL.Session from the HsOpenSSL library, which itself is a loose wrapper around the OpenSSL library.
Lucky for us OpenSSL has full support for client certificates. You simply have to set the verification mode to SSL_VERIFY_PEER. There are other knobs you can fiddle with too. You also have to make sure you install a certificate chain to actually verify the client certificate against. Chain of trust and all that jazz. For reference, see how nginx does it.
Even better, this function is exposed in HsOpenSSL as the function contextSetVerificationMode :: SSLContext -> VerificationMode -> IO (). You'll notice that ctx :: SSLContext exists in the definition of Snap's bindHttps. All you'll have to do is either copy or fork that module and introduce your calls.
It would look something like this (unverified code alert):
± % diff -u /tmp/{old,new}
--- /tmp/old 2016-04-11 11:02:42.000000000 -0400
+++ /tmp/new 2016-04-11 11:02:56.000000000 -0400
## -19,6 +19,7 ##
ctx <- SSL.context
SSL.contextSetPrivateKeyFile ctx key
+ SSL.contextSetVerificationMode ctx (SSL.VerifyPeer True True (Just (\_ _ -> return True)))
if chainCert
then SSL.contextSetCertificateChainFile ctx cert
else SSL.contextSetCertificateFile ctx cert
The first boolean tells OpenSSL to fail if no client certificate is present. The second boolean tells OpenSSL that the client certificate is only needed on the first request and no longer needed on renegotiations. The third value is a callback. I think the right thing to do is to just return True in the callback. It's what nginx does, anyway.
Would it be possible to block Tor users? (https://www.torproject.org/)
Due to the nature of the site I run I should do all I can to stop multiple accounts and block certain locations. Tor is worse than proxies - a total nightmare...
Tor is much easier to block than other open proxies since the list of exit IP addresses is known and published. Read the answer at https://www.torproject.org/docs/faq-abuse.html.en#Bans and if you still want to block users from accessing your site you could use https://www.torproject.org/projects/tordnsel.html.en or the Bulk Exit List exporting tool.
If you use the Bulk Exit List exporting tool be sure to get a fresh list often and expire the old blocks since the list of IP addresses change.
Blocking Tor is wrong because (ab)users and IP addresses are not the same. By blocking Tor you will also block legitimate users and harmless restricted Tor exit nodes configured with conservative exit policies.
For example, if you concerned about attacks on SSH (port 22) then blocking only Tor will do little to increase security. What you really might need is dynamic synchronised blacklist like http://denyhosts.sourceforge.net/ that track offenders disregarding of their affiliation with Tor.
Denyhosts will automatically block Tor exit nodes that allow Tor to access port 22 without unnecessary denying access to anonymous users and operators of Tor exit nodes who never let offenders to attack your SSH services.
The Tor Project actually provides its own list here:
https://check.torproject.org/exit-addresses
In .NET it's possible and simple. I have implemented it on my site.
Let's say your site has an external IP address of 192.168.0.5 for argument's sake. Real TOR IP address at the time of posting: 95.215.44.97
Imports System.Net
Imports System.Net.Sockets
Imports System.Web
Private Function IsTorExitNode(sIP As String) As Boolean
' Reverse your IP (97.44.215.95) then pass to the string, I have just created it as one for this example
Try
Dim strTor As String = "97.44.215.95.80.5.0.168.192.ip-port.exitlist.torproject.org"
Dim host As IPHostEntry = Dns.GetHostEntry(strTor)
If host.AddressList.Length = 0 Then
Return False
Else
If host.AddressList(0).ToString() = "127.0.0.2" Then
Return True
Else
Return False
End If
End If
Catch ex As SocketException
Return False
End Try
End Function
Breakdown
Reversed IP address: 97.44.215.95
Port: 80
Reversed IP address: (your external site IP address)
If the address is a TorExitNode it will return 127.0.0.2.
In your Global.asax file, you can use the Application_Start to check if IP address returns true and then redirect them away from your site:
If IsTorExitNode("97.44.215.95") = True Then Response.Redirect("http://www.google.co.uk")
Now, as soon as they hit your site they are redirected away from it.
TOR has a list of IP addresses, but obviously they change all the time so using my function would be the best way as it's always real-time.
You can use the TorDNSEL service to perform a live query about whether a specific IP address is a Tor exit node. You query the service via a specially-formed DNS request.
Here is some sample PHP code that performs the lookup:
function isTorExitNode() {
$serverPort = $_SERVER['SERVER_PORT'];
$remoteAddr = reverseIp(getClientIp());
$serverAddr = reverseIp($_SERVER['SERVER_ADDR']);
$placeholders = '%s.%s.%s.ip-port.exitlist.torproject.org';
$name = sprintf($placeholders, $remoteAddr, $serverPort, $serverAddr);
return ( gethostbyname($name) === '127.0.0.2' );
}
function getClientIp() {
if (isset($_SERVER['HTTP_CF_CONNECTING_IP'])) {
return $_SERVER['HTTP_CF_CONNECTING_IP'];
}
return $_SERVER['REMOTE_ADDR'];
}
function reverseIp($ip) {
$ipParts = explode('.', $ip);
return $ipParts[3] . '.' . $ipParts[2] . '.' .
$ipParts[1] . '.' . $ipParts[0];
}
if (!isTorExitNode()) {
// Do nothing
} else {
Die("Sorry, You cannot use TOR network!!!");
}
Important Notes:
This example supports IPv4 addresses only, not IPv6.
It could take a couple of seconds to get a response, so be careful about introducing delays into your site rendering.
Since TorDNSEL was deprecated and replaced by a new system in april 2020 [1], most of the answers in this thread are outdated.
After a bit of wrangling I came up with this code that uses the new checker. What it does is it reverses the ip octets and creates a URL for the new checker, then performs a DNS request and checks wether or not the first answer has the "127.0.0.2" IP. If this is the case, the user is deemed to come from Tor, otherwise it returns false.
function IsTorExitPoint(){
$dns_record = dns_get_record(ReverseIPOctets($_SERVER['REMOTE_ADDR']).".dnsel.torproject.org.");
if ($dns_record && $dns_record[0] && $dns_record[0]["ip"] == "127.0.0.2") {
return true;
} else {
return false;
}
}
function ReverseIPOctets($inputip){
$ipoc = explode(".",$inputip);
return $ipoc[3].".".$ipoc[2].".".$ipoc[1].".".$ipoc[0];
}
[1] https://lists.torproject.org/pipermail/tor-project/2020-March/002759.html
PD: It's been a while since I've posted an answer to stackoverflow, so please bear with me and help me improve if possible.
It's a fact, that the best application defence is its code and security, not a firewall blocklist. If it's an essential matter for you to have real true users - you have to use two-factor authentication. Blocklists are totally useless nowadays.
Here (see https://github.com/RD17/DeTor) is a simple REST API to determine whether a request was made from TOR network or not.
The request is:
curl -X GET http://detor.ambar.cloud/.
The response is:
{
"sourceIp": "104.200.20.46",
"destIp": "89.207.89.82",
"destPort": "8080",
"found": true
}
As a bonus you can add a badge to your site to detect whether a user comes from TOR or not:
<img src="http://detor.ambar.cloud/badge" />
(This was written for a PHP specific question that was subsequently deleted and linked here as a duplicate).
Disclaimer: Consider the impact of blocking all Tor users as raised in the best answer here. Consider only blocking functions such as registration, payment, comments etc and not a blanket block on everything.
--
Here are two pure PHP solutions. The first downloads and caches a Tor node list and compares the visitor IP against the list. The second uses the Tor DNS Exit List project to determine if the visitor is using Tor via DNS lookups.
Method #1 (Checking IP against a Tor relay list):
Using the following set of functions we can determine if an IP belongs to the Tor network by checking it against a dynamic exit list that gets downloaded and cached for 10 minutes. Feel free to use this list but please cache for 10 minutes when possible.
Where you want to enforce the Tor check, you can simply use:
$isTorUser = isTorUser($_SERVER['REMOTE_ADDR']);
if ($isTorUser) {
// blocking action
}
Here is the code which you can put in a separate functions file and include when you want to run the check. Note, you may want to adjust some of it to change the path to the cache file.
<?php
function isTorUser($ip)
{
$list = getTorExitList();
if (arrayBinarySearch($ip, $list) !== false) {
return true;
} else {
return false;
}
}
function getTorExitList()
{
$path = __DIR__ . '/tor-list.cache';
if ( file_exists($path) && time() - filemtime($path) < 600 ) {
$list = include $path;
if ($list && is_array($list)) {
return $list;
}
}
$data = file('https://www2.openinternet.io/tor/tor-exit-list.txt');
if (!$data) {
return array();
}
$list = array();
foreach($data as $line) {
$line = trim($line);
if ($line == '' || $line[0] == '#') continue;
list($nick, $ip) = explode("\t", $line);
$list[] = $ip;
}
sort($list);
file_put_contents($path, sprintf("<?php return %s;", var_export($list, true)));
return $list;
}
/**
* Perform binary search of a sorted array.
* Credit: http://php.net/manual/en/function.array-search.php#39115
*
* Tested by VigilanTor for accuracy and efficiency
*
* #param string $needle String to search for
* #param array $haystack Array to search within
* #return boolean|number false if not found, or index if found
*/
function arrayBinarySearch($needle, $haystack)
{
$high = count($haystack);
$low = 0;
while ($high - $low > 1){
$probe = ($high + $low) / 2;
if ($haystack[$probe] < $needle){
$low = $probe;
} else{
$high = $probe;
}
}
if ($high == count($haystack) || $haystack[$high] != $needle) {
return false;
} else {
return $high;
}
}
Method #2 (Checking IP against the Tor DNS Exit List Project):
The DNS exit check is a bit more robust in that it takes into account the relay's exit policy and looks at what IP and port on your server the client is connecting to and if such exit traffic is permitted, it will return a match. The potential downfall is that if the DNS project is down temporarily, DNS requests can hang before timing out slowing things down.
For this example, I will use a class from a library I wrote and maintain called TorUtils.
First, you'll need to install it with Composer using composer require dapphp/torutils and include the standard vendor/autoloader.php code in your application.
The code for the check:
$isTor = false;
try {
// check for Tor using the remote (client IP)
if (TorDNSEL::isTor($_SERVER['REMOTE_ADDR'])) {
// do something special for Tor users
} else {
// not using Tor, educate them! :-D
}
} catch (\Exception $ex) {
// This would likely be a timeout, or possibly a malformed DNS response
error_log("Tor DNSEL query failed: " . $ex->getMessage());
}
if ($isTor) {
// blocking action
}
Additional Considerations
If your application uses PHP sessions, I'd highly suggest caching the "isTorUser" response into the session (along with the source IP) and only run the check initially or when the IP changes (e.g. $_SERVER['REMOTE_ADDR'] != $_SESSION['last_remote_addr']) as not to perform many duplicated lookups. Even though they try to be very efficient, it's a waste to do over and over for the same IP.
I found a list of all the Tor nodes updated every half an hour: https://www.dan.me.uk/tornodes
This SHOULD include the exit, entries and bridge nodes used to connect and browse through Tor.
Use this Perl script to gather the IP addresses from a downloaded webpage:
perl -lne 'print $& if /(\d+\.){3}\d+/' downloadedwebpage.html > listofips.out
It will give you a list of IP addresses , one per line. I have tried to find something that will do this without the Perl script, but after many hours searching I could not find one.
I hope this helps.
I also found some good information here too on the same site:
https://www.dan.me.uk/dnsbl
Detecting Tor traffic is rather easy. The main way to do this is to monitor the Tor exit node list and compare the IP against the list.
I had the need to do such a thing recently and built a small Ruby gem to keep the list of exit nodes up to date and provide a simple way to detect exit nodes. I also wrote a small executable you can use to detect exit nodes.
The gem is open source and can be found here: tor-guard
Installing the gem is simple enough:
$ gem install tor-guard
Using the library in your own Ruby code can be done as follows:
require 'tor-guard'
if TorGuard.exit_node?('108.56.199.13')
puts "Yep, it's an exit node!"
end
The executable is also easy to use:
$ tg 108.56.199.13 && echo "Yep, it's an exit node"
It is possible due to the tor project publishing a list of exit proxies.
The list of exit proxies can be downloaded directly from the project at https://check.torproject.org/exit-addresses in space delimited text form.
I have written a python script to add iptables rules for all exit nodes that reject all packets from them. You can find the script on github here: https://github.com/vab/torblock
If the Tor Project ever decides to stop publishing a list of exit nodes it will be possible to block them. Code would just need to be written to connect to the tor network and discover the exit nodes.
Yes, and in fact here is a script that will do it for all of your windows machines. Like others mentioned above, it's as simple as blocking all the exit nodes, but that takes a little work.
https://github.com/Austin-Src/BlockTor
I have already curated the tor nodes and tor exit nodes list which keep updating hourly. Please refer to https://github.com/SecOps-Institute/Tor-IP-Addresses
You can do a git pull every hour and get the most updated list.
For whatever reason I wasn't able to find another answer on here, as of now (20 Shevat 5781 (from Creation)) that has this particular link, so here it is:
https://check.torproject.org/torbulkexitlist
I got it by downloading Tor, then opening up a find my IP address website, then navigating to that IP address (it happens to be http://195.176.3.20/, if you navigate to it you should find the list also), and navigating to it....
I'm trying achieve two things with DCOM (Out of process)
Set the process wide authentication using CoInitializeSecurity and its parameter pAuthList.
Using cloaking to change the caller's identity in special situations (COM calls)
My thoughts:
AFAIK the auth info structure contains the default authentication information (like username and password for RPC_C_AUTHN_WINNT) for all new COM calls. So instead of the process token the information in the auth structure should be used by COM.
However, all COM calls/connections are always using the process' identity instead of the applied default one.
Usually, one can use CoSetProxyBlanket to change the auth info for a proxy. This works for me. My question here is whether it must or must not work if I impersonate the token myself and call the COM function. I've read in various MSDN articles that applying EOAC_DYNAMIC_CLOAKING to CoInitializeSecurity should make it working. However, my manually "impersonated COM calls always shows the process identity on the server side.
The client looks like this (Delphi)
var
authList : SOLE_AUTHENTICATION_LIST;
authidentity : SEC_WINNT_AUTH_IDENTITY_W;
authInfo : array[0..1] of SOLE_AUTHENTICATION_INFO;
pcAuthSvc : DWORD;
asAuthSvc : array[0..0] of SOLE_AUTHENTICATION_SERVICE;
Token : TJwSecurityToken;
begin
ZeroMemory( #authidentity, sizeof(authidentity) );
authidentity.User := 'Testbenutzer';
authidentity.UserLength := Length('Testbenutzer');
authidentity.Domain := '';
authidentity.DomainLength := 0;
authidentity.Password := 'test';
authidentity.PasswordLength := 4;
authidentity.Flags := SEC_WINNT_AUTH_IDENTITY_UNICODE;
ZeroMemory( #authInfo, sizeof( authInfo ) );
// NTLM Settings
authInfo[0].dwAuthnSvc := RPC_C_AUTHN_WINNT;
authInfo[0].dwAuthzSvc := RPC_C_AUTHZ_NONE;
authInfo[0].pAuthInfo := #authidentity;
authList.cAuthInfo := 1;
authList.aAuthInfo := #authInfo;
OleCheck(CoInitializeSecurity(
NULL, // Security descriptor
-1, // Count of entries in asAuthSvc
NULL, // asAuthSvc array
NULL, // Reserved for future use
RPC_C_AUTHN_LEVEL_CONNECT, // Authentication level
RPC_C_IMP_LEVEL_IMPERSONATE, // Impersonation level
#authList, // Authentication Information
DWORd(EOAC_DYNAMIC_CLOAKING), // Additional capabilities
NULL // Reserved
));
//create COM object
int := CoSecurityTestObj.Create;
int.TestCall;
The server also has set the flag EOAC_DYNAMIC_CLOAKING. It uses CoImpersonateClient to get the thread token and the username. It also uses CoQueryClientBlanket to get the authInfo (as SEC_WINNT_AUTH_IDENTITY_W structure). However both calls always return the process identity of the client.
Also impersonating manually doesn't work (2.):
Token := TJwSecurityToken.CreateLogonUser(authidentity.User, '', authidentity.Password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT);
Token.ImpersonateLoggedOnUser;
int := CoSecurityTestObj.Create;
int.TestCall;
Questions again:
Am I wrong or why is the default auth info structure (WinNT with username and password) not used as default authentication in each COM connection/call ?
Am I wrong or why doesn't manual impersonation work? Be aware that I tested number 2. separately so number 1. cannot interfere.
This is basic work for the JEDI Windows Security Code Library which I extend to support COM security. So your help will go GPL/MPL.
References:
Cloaking:
http://msdn.microsoft.com/en-us/library/ms683778%28VS.85%29.aspx
http://msdn.microsoft.com/en-us/library/cc246058%28PROT.10%29.aspx
http://alt.pluralsight.com/wiki/default.aspx/Keith.GuideBook/WhatIsCoInitializeSecurity.html
CoInitializeSecurity and pAuthInfo
http://www.codeguru.cn/vc&mfc/apracticalguideusingvisualcandatl/93.htm
Getting security blanket (server side)
http://www.codeguru.cn/vc&mfc/apracticalguideusingvisualcandatl/92.htm
Have you tried calling CoInitializeSecurity() with RPC_C_AUTHN_LEVEL_CALL instead of RPC_C_AUTHN_LEVEL_CONNECT?
Usually when I create DCOM clients I create COSERVERINFO and pass to CoCreateInstanceEx() with security credentials, remembering to call CoSetProxyBlanket() on all interfaces.