Bitcoin Forum
August 08, 2025, 12:28:40 PM *
News: Latest Bitcoin Core release: 29.0 [Torrent]
 
  Home Help Search Login Register More  
  Show Posts
Pages: [1]
1  Bitcoin / Project Development / Working With Android on: June 30, 2015, 06:19:33 PM
 Ok, so, I've been doing an in-depth study of bitcoin software. I've looked at the crypto, I've looked at the hasher class and other portions of the more important functions. Windows based programming has a few issues, but nothing I would consider anything serious. there are easy to do work-arounds and a few ready made scripts to help compile code on windows for qt. Linux compiling has far fewer issues than windows and again, there are some ready made scripts even for linux users who want to save a little time when building the daemon. I've been getting familiar with the windows side of compiling qt. I'm already versed in bashing on linux. I have begun to delve into android programming. there seems to be a desire for more android based apps, for phones and tablets.

 Android studio, so far, has given me few issues. The native development kit allows you to write code in different languages, and then compile them for android java. With the ndk, you can write code for a wallet in say c++ and compile it to run on a phone, without actually having to code any java at all. This seems to work fine so far in tests, but running these apps on a phone is not the same from one manufacturer to the next. The difference in hardware between phones is solved by just writing the code in java and compiling it in android studio. The AVD (Android Virtual Device) let's you test code on specific models of phones with a specific hardware setup. So you can see if your app will run on a certain phone, or every phone. Test it against different API's, like Ice Cream Sandwich or Lollipop. Cross-platform compiling using android java and a second language, like c++, can be tested thoroughly to see if it will run correctly. A lot of crypto currency software is cross-platform and can be imported into android studio. There are plugins that support PHP, Python, Ruby, C++, Javascript, JSON and other custom languages. Android could be used to eliminate the need to use a pc/mac at all. (Except for writing code and compiling.)

 I have seen a wallet project for android. I'm not all that familiar with the project and I haven't delved into it's source yet. More than likely I'm just going to start a project from scratch and see where it leads. Most of the projects I've looked at have various vulnerabilities that I have already pointed out. Android libraries have built in functionality and libraries that I believe are better than those found in visual studio and similar IDE. There is better security, a more stable hasher, pretty good networking and a huge community. The documentation also covers almost any problem you might have. A few people have said that the current android wallet works, but not very well. I don't know if that's true or not, as I haven't used it. So, I'll be working on an android wallet, as soon as I finish my first project.

 My first project is a ticker app that shows tickers for just about every exchange on the web. It comes with an internet radio player, my music folder access to play your own custom playlist, ability to sign in to your favorite exchange from within the app, connect using 2fa login, set a favorites list of your favorite tickers/exchanges and when you close the app, it does not stay in memory or active processes. It will clean itself up. Android ndk is good for this, because exchanges use very different api's. Some use Python, some use PHP, some use Ruby, some use JSON and other use Jquery. All of the tickers use some form of GET or POST and the ndk can use api's in all of these languages. Connecting to any exchange should be seamless. Just like using your favorite web browser on your pc or mac.
2  Bitcoin / Mining software (miners) / Bitcoin Research Part 3, Mining on: June 21, 2015, 07:21:34 PM
 This is the third part of my research into crypto currency. This portion of research will cover mining software. There are different forms of mining and different forms of software used to mine. Some mining is hardware based and some software based. Hardware based mining is still software driven.

 Crypto currencies use 2 things: Proof-of-work and Proof-of-stake. Some coins lean more towards proof-of-stake and others towards proof-of-work. There is a big difference between the 2.
The same is said for mining software. Some use one, others use the other. There are ways to set up mining software to reference proof-of-work or stake, but otherwise bypass them altogether and not actually use either of them. For example, bitcoin uses valid proof-of-work as a reference, but bypasses actually using it.

// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2013 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef BITCOIN_MINER_H
#define BITCOIN_MINER_H

#include "primitives/block.h"

#include <stdint.h>

class CBlockIndex;
class CReserveKey;
class CScript;
class CWallet;

struct CBlockTemplate
{
    CBlock block;
    std::vector<CAmount> vTxFees;
    std::vector<int64_t> vTxSigOps;
};

/** Run the miner threads */
void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads);
/** Generate a new block, without valid proof-of-work */
CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn);
CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey);
/** Modify the extranonce in a block */
void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
void UpdateTime(CBlockHeader* block, const CBlockIndex* pindexPrev);

#endif // BITCOIN_MINER_H

  There is nothing wrong with this portion of the software. Generating blocks without p-o-w will save on resource consumption. The small amount saved is negligable and only amounts to a fraction of a fraction of processing power. But if you notice, this particular miner uses fees. Calculating a fee based on the p-o-w per block generated will consume the resources previously saved in bypassing p-o-w for generating new blocks. Because fees are determined on a byte-for-byte basis, the more data you send/receive, the larger the fee, and the more resources needed to calculate the fee. The byte-for-byte fee is not based on the amount of coins in the transaction. It is only based on the total amount of data, or size of the packets/datagrams, sent and received during the transaction(s).

 Bitcoin, for example, determines transactions by highest priority. Priority being determined by the fee rate.

// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "miner.h"

#include "amount.h"
#include "primitives/transaction.h"
#include "hash.h"
#include "main.h"
#include "net.h"
#include "pow.h"
#include "timedata.h"
#include "util.h"
#include "utilmoneystr.h"
#ifdef ENABLE_WALLET
#include "wallet/wallet.h"
#endif

#include <boost/thread.hpp>
#include <boost/tuple/tuple.hpp>

using namespace std;

//////////////////////////////////////////////////////////////////////////////
//
// BitcoinMiner
//

//
// Unconfirmed transactions in the memory pool often depend on other
// transactions in the memory pool. When we select transactions from the
// pool, we select by highest priority or fee rate, so we might consider
// transactions that depend on transactions that aren't yet in the block.
// The COrphan class keeps track of these 'temporary orphans' while
// CreateBlock is figuring out which transactions to include.
//
class COrphan
{
public:
    const CTransaction* ptx;
    set<uint256> setDependsOn;
    CFeeRate feeRate;
    double dPriority;

    COrphan(const CTransaction* ptxIn) : ptx(ptxIn), feeRate(0), dPriority(0)
    {
    }
};

uint64_t nLastBlockTx = 0;
uint64_t nLastBlockSize = 0;

// We want to sort transactions by priority and fee rate, so:
typedef boost::tuple<double, CFeeRate, const CTransaction*> TxPriority;
class TxPriorityCompare
{
    bool byFee;

public:
    TxPriorityCompare(bool _byFee) : byFee(_byFee) { }

    bool operator()(const TxPriority& a, const TxPriority& b)
    {
        if (byFee)
        {
            if (a.get<1>() == b.get<1>())
                return a.get<0>() < b.get<0>();
            return a.get<1>() < b.get<1>();
        }
        else
        {
            if (a.get<0>() == b.get<0>())
                return a.get<1>() < b.get<1>();
            return a.get<0>() < b.get<0>();
        }
    }
};

 Bitcoin does have free transactions based on the minimum block size. But it also ignores free transactions and sets a fee anyway.

// Skip free transactions if we're past the minimum block size:
            const uint256& hash = tx.GetHash();
            double dPriorityDelta = 0;
            CAmount nFeeDelta = 0;
            mempool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta);
            if (fSortedByFee && (dPriorityDelta <= 0) && (nFeeDelta <= 0) && (feeRate < ::minRelayTxFee) && (nBlockSize + nTxSize >= nBlockMinSize))
                continue;

            // Prioritise by fee once past the priority size or we run out of high-priority
            // transactions:
            if (!fSortedByFee &&
                ((nBlockSize + nTxSize >= nBlockPrioritySize) || !AllowFree(dPriority)))
            {
                fSortedByFee = true;
                comparer = TxPriorityCompare(fSortedByFee);
                std::make_heap(vecPriority.begin(), vecPriority.end(), comparer);
            }

            if (!view.HaveInputs(tx))
                continue;

            CAmount nTxFees = view.GetValueIn(tx)-tx.GetValueOut();

            nTxSigOps += GetP2SHSigOpCount(tx, view);
            if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS)
                continue;

            // Note that flags: we don't want to set mempool/IsStandard()
            // policy here, but we still have to ensure that the block we
            // create only contains transactions that are valid in new blocks.
            CValidationState state;
            if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true))
                continue;

            UpdateCoins(tx, state, view, nHeight);

            // Added
            pblock->vtx.push_back(tx);
            pblocktemplate->vTxFees.push_back(nTxFees);
            pblocktemplate->vTxSigOps.push_back(nTxSigOps);
            nBlockSize += nTxSize;
            ++nBlockTx;
            nBlockSigOps += nTxSigOps;
            nFees += nTxFees;

            if (fPrintPriority)
            {
                LogPrintf("priority %.1f fee %s txid %s\n",
                    dPriority, feeRate.ToString(), tx.GetHash().ToString());
            }

            // Add transactions that depend on this one to the priority queue
            if (mapDependers.count(hash))
            {
                BOOST_FOREACH(COrphan* porphan, mapDependers[hash])
                {
                    if (!porphan->setDependsOn.empty())
                    {
                        porphan->setDependsOn.erase(hash);
                        if (porphan->setDependsOn.empty())
                        {
                            vecPriority.push_back(TxPriority(porphan->dPriority, porphan->feeRate, porphan->ptx));
                            std::push_heap(vecPriority.begin(), vecPriority.end(), comparer);
                        }
                    }
                }
            }
        }


 The miner also uses not just the block chain, but also uses the memory pool, where it also dumps to and leaves the left over data there, to fill up available resources with unused data. This data is left over from the blocks and contains all the information contained within the block, or blocks, and any unencrypted data also remains. Windows uses the hard drive swap file for the memory pool, so anyone who can access the swap file can get all of the information on a user they need to perform malicious activity. Not necessarily easy to do, but a possibility that exists.



                    // Has to wait for dependencies
                    if (!porphan)
                    {
                        // Use list for automatic deletion
                        vOrphan.push_back(COrphan(&tx));
                        porphan = &vOrphan.back();
                    }

 As you can see by this snippet of code, there is supposed to be an automatic deletion of orphans, but there is no actual execution of deleting orphans or unused data. So orphaned blocks continue to take up space, leaving less space for legitimate blocks. It will list the orphaned blocks, but do nothing about them.

 There is still a lot of research to complete for mining software. Most of the source is fine. It does what it is intended to do and has checks and balances in place where they should be to ensure valid blocks. The only discrepencies are where fees are concerned and the amount of resources consumed and wasted during transactions and generating blocks. The total amount of resource waste has not yet been determined. On-going tests have not yet been completed in this area. These tests currently cover proof-of-work blocks.

 Proof-of-stake blocks have a lot of similarities and also a lot of differences. P-o-s can be bypassed just as easily as p-o-w, and can also have the same type of resource waste. Fees can also be incurred and enforced on transactions without a user's knowledge. The security of proof-of-work is the same as proof-of-stake. The crypto used is the same. The hasher class/chunker is the same, with a few differences. Some hash out to 64 bits, but chunk it out to 60. Others hash out to 64 bits and chunk out to the same.

 Proof-of-stake's major difference from proof-of-work is the time it takes to mint blocks. Staking relies on the time table used for minting and confirming blocks. Proof-of-work has no such use of a time table for minting or confirming and thus can have any time table the developer chose to use, if any at all. Most proof-of-work seems to only require the fact that some form of "work" was done, but has no need to know when it was done, how long it took or whether it was a valid block or not. Staking requires a valid block, confirmed within a reasonable amount of time. Proof-of-work has little to do with the stake and is usually referenced, but bypassed altogether. Staking is slightly more efficient than proof-of-work. But both come with the same vulnerabilities and the same wasted resources.

 Testing proof-of-stake is also on-going. The amount of resource waste is still yet to be determined.

 Bitcoin miners do not actually run a check on the block, whereas Litecoin does. They have similar headers, with the exception of included libraries and the one actually checking the block and the other does not.

// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2013 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef BITCOIN_MINER_H
#define BITCOIN_MINER_H

#include <stdint.h>

class CBlock;
class CBlockHeader;
class CBlockIndex;
class CReserveKey;
class CScript;
class CWallet;

struct CBlockTemplate;

/** Run the miner threads */
void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads);
/** Generate a new block, without valid proof-of-work */
CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn);
CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey);
/** Modify the extranonce in a block */
void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
/** Check mined block */
bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey);
void UpdateTime(CBlockHeader* block, const CBlockIndex* pindexPrev);

extern double dHashesPerSec;
extern int64_t nHPSTimerStart;

#endif // BITCOIN_MINER_H

 Bitcoin and Litecoin both use the exact same source for their miners. Again, with the exception of which libraries are used and one does a check, the other doesn't. This snippet of Litecoin is the exact same for Bitcoin. Minus the included libraries have a one line difference.

// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "miner.h"

#include "amount.h"
#include "primitives/block.h"
#include "primitives/transaction.h"
#include "hash.h"
#include "crypto/scrypt.h"
#include "main.h"
#include "net.h"
#include "pow.h"
#include "timedata.h"
#include "util.h"
#include "utilmoneystr.h"
#ifdef ENABLE_WALLET
#include "wallet.h"
#endif

#include <boost/thread.hpp>
#include <boost/tuple/tuple.hpp>

using namespace std;

//////////////////////////////////////////////////////////////////////////////
//
// BitcoinMiner
//

//
// Unconfirmed transactions in the memory pool often depend on other
// transactions in the memory pool. When we select transactions from the
// pool, we select by highest priority or fee rate, so we might consider
// transactions that depend on transactions that aren't yet in the block.
// The COrphan class keeps track of these 'temporary orphans' while
// CreateBlock is figuring out which transactions to include.
//
class COrphan
{
public:
    const CTransaction* ptx;
    set<uint256> setDependsOn;
    CFeeRate feeRate;
    double dPriority;

    COrphan(const CTransaction* ptxIn) : ptx(ptxIn), feeRate(0), dPriority(0)
    {
    }
};

uint64_t nLastBlockTx = 0;
uint64_t nLastBlockSize = 0;

// We want to sort transactions by priority and fee rate, so:
typedef boost::tuple<double, CFeeRate, const CTransaction*> TxPriority;
class TxPriorityCompare
{
    bool byFee;

public:
    TxPriorityCompare(bool _byFee) : byFee(_byFee) { }

    bool operator()(const TxPriority& a, const TxPriority& b)
    {
        if (byFee)
        {
            if (a.get<1>() == b.get<1>())
                return a.get<0>() < b.get<0>();
            return a.get<1>() < b.get<1>();
        }
        else
        {
            if (a.get<0>() == b.get<0>())
                return a.get<1>() < b.get<1>();
            return a.get<0>() < b.get<0>();
        }
    }
};

void UpdateTime(CBlockHeader* pblock, const CBlockIndex* pindexPrev)
{
    pblock->nTime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());

    // Updating time can change work required on testnet:
    if (Params().AllowMinDifficultyBlocks())
        pblock->nBits = GetNextWorkRequired(pindexPrev, pblock);
}

CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
{
    // Create new block
    auto_ptr<CBlockTemplate> pblocktemplate(new CBlockTemplate());
    if(!pblocktemplate.get())
        return NULL;
    CBlock *pblock = &pblocktemplate->block; // pointer for convenience

    // -regtest only: allow overriding block.nVersion with
    // -blockversion=N to test forking scenarios
    if (Params().MineBlocksOnDemand())
        pblock->nVersion = GetArg("-blockversion", pblock->nVersion);

    // Create coinbase tx
    CMutableTransaction txNew;
    txNew.vin.resize(1);
    txNew.vin[0].prevout.SetNull();
    txNew.vout.resize(1);
    txNew.vout[0].scriptPubKey = scriptPubKeyIn;

    // Add dummy coinbase tx as first transaction
    pblock->vtx.push_back(CTransaction());
    pblocktemplate->vTxFees.push_back(-1); // updated at end
    pblocktemplate->vTxSigOps.push_back(-1); // updated at end


 In a line-by-line comparison, most code blocks were exactly identical, even down to the commenting. Exact word for word comments and source. So any vulnerabilities and flaws found within Bitcoin, are exactly the same in Litecoin. At least within the mining software. Performing your own line-by-line comparison to source found on Github will verify these results.
3  Alternate cryptocurrencies / Altcoin Discussion / Bitcoin and Litecoin Research Part 2 on: June 19, 2015, 07:51:51 PM
 This is the second part of my research into Bitcoins. This part will cover IRC connections, hidden channels and backdoors, if they exist. There are several Bitcoin wallets that use an IRC connection for node discovery. This is not an incorrect way to discover nodes or wallets connected to the network, but it does come with vulnerabilities. Some of these vulnerabilities are well known to malicious users and are easy to exploit.

 One of the typical IRC connections used is irc.lfnet.com. Litecoin, for example, uses this connection, but also points to: pelican.heliacal.net. The connection is not hidden, but does have a vulnerability present. A user's I.P. address is made public. If the current connection is not available, a different IRC channel can be used. While this helps keep connections alive, it could be made a little more secure. This block of litecoin code shows how it connects to IRC.

// Hybrid IRC used by lfnet always returns IP when you userhost yourself,
    // but in case another IRC is ever used this should work.
    printf("GetIPFromIRC() got userhost %s\n", strHost.c_str());
    CNetAddr addr(strHost, true);
    if (!addr.IsValid())
        return false;
    ipRet = addr;

    return true;
}



void ThreadIRCSeed(void* parg)
{
    IMPLEMENT_RANDOMIZE_STACK(ThreadIRCSeed(parg));

    // Make this thread recognisable as the IRC seeding thread
    RenameThread("bitcoin-ircseed");

    try
    {
        ThreadIRCSeed2(parg);
    }
    catch (std::exception& e) {
        PrintExceptionContinue(&e, "ThreadIRCSeed()");
    } catch (...) {
        PrintExceptionContinue(NULL, "ThreadIRCSeed()");
    }
    printf("ThreadIRCSeed exited\n");
}

void ThreadIRCSeed2(void* parg)
{
    /* Dont advertise on IRC if we don't allow incoming connections */
    if (mapArgs.count("-connect") || fNoListen)
        return;

    if (!GetBoolArg("-irc", false))
        return;

    printf("ThreadIRCSeed started\n");
    int nErrorWait = 10;
    int nRetryWait = 10;

    while (!fShutdown)
    {
        CService addrConnect("irc.lfnet.org", 6667, true);

        SOCKET hSocket;
        if (!ConnectSocket(addrConnect, hSocket))
        {
         addrConnect = CService("pelican.heliacal.net", 6667, true);
         if (!ConnectSocket(addrConnect, hSocket))
         {
            printf("IRC connect failed\n");
            nErrorWait = nErrorWait * 11 / 10;
            if (Wait(nErrorWait += 60))
               continue;
            else
               return;
         }
        }

        if (!RecvUntil(hSocket, "Found your hostname", "using your IP address instead", "Couldn't look up your hostname", "ignoring hostname"))
        {
            closesocket(hSocket);
            hSocket = INVALID_SOCKET;
            nErrorWait = nErrorWait * 11 / 10;
            if (Wait(nErrorWait += 60))
                continue;
            else
                return;
        }

        CNetAddr addrIPv4("1.2.3.4"); // arbitrary IPv4 address to make GetLocal prefer IPv4 addresses
        CService addrLocal;
        string strMyName;
        if (GetLocal(addrLocal, &addrIPv4))
            strMyName = EncodeAddress(GetLocalAddress(&addrConnect));
        if (strMyName == "")
            strMyName = strprintf("x%"PRI64u"", GetRand(1000000000));

        Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str());
        Send(hSocket, strprintf("USER %s 8 * : %s\r", strMyName.c_str(), strMyName.c_str()).c_str());

        int nRet = RecvUntil(hSocket, " 004 ", " 433 ");
        if (nRet != 1)
        {
            closesocket(hSocket);
            hSocket = INVALID_SOCKET;
            if (nRet == 2)
            {
                printf("IRC name already in use\n");
                Wait(10);
                continue;
            }
            nErrorWait = nErrorWait * 11 / 10;
            if (Wait(nErrorWait += 60))
                continue;
            else
                return;
        }
        MilliSleep(500);

        // Get our external IP from the IRC server and re-nick before joining the channel
        CNetAddr addrFromIRC;
        if (GetIPFromIRC(hSocket, strMyName, addrFromIRC))
        {
            printf("GetIPFromIRC() returned %s\n", addrFromIRC.ToString().c_str());
            if (addrFromIRC.IsRoutable())
            {
                // IRC lets you to re-nick
                AddLocal(addrFromIRC, LOCAL_IRC);
                strMyName = EncodeAddress(GetLocalAddress(&addrConnect));
                Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str());
            }
        }

 Another vulnerability here is the seeding aspect. Seeding implies that the connection is available for downloading from. Just like torrent files are seeded to share, so are connections like this. With the right scripts in place, it is possible to download the user's data, and potentially misuse it. Not all of the IRC connections used by crypto currencies are malicious. The vulnerabilities that exist within these connections are in need of being corrected. Any IRC servers being used to host these connections should only be administrated by trusted individuals that you know, and have a reputation of being honest. If you use a connection that you are unsure of, or is ran anonymously, you run the risk of being exploited. Once a connection is open as a seed, a firewall is little protection. Some antivirus programs will be effective against malware being passed through the connection. But any connection allowed through the firewall, is open to exploitation.

 I would recommend researching a particular IRC connection, before using any software that connects to it. Look for who owns the server, who is the administrator and if there has been any previous incidents involving the server. Blind acceptance of the security of a given server is foolish. Blind acceptance of the claim of anonymity and security of a given network is also foolish. Again, if you don't know who runs the server, you run the risk of getting exploited.

 There is a seed filter set up, but it is limited to only a specific set of addresses. Any address not listed bypasses the filter and thus could be used to exploit connections. By limiting the number of addresses to check for suspicion, it limits the protection of the filter. Instead of filtering by I.P. only, there could be additional checks in place to check for suspicious activity on any connection, not just those specified.

#!/usr/bin/env python
#
# Generate seeds.txt from Pieter's DNS seeder
#

NSEEDS=512

MAX_SEEDS_PER_ASN=2

MIN_BLOCKS = 337600

# These are hosts that have been observed to be behaving strangely (e.g.
# aggressively connecting to every node).
SUSPICIOUS_HOSTS = set([
    "130.211.129.106", "178.63.107.226",
    "83.81.130.26", "88.198.17.7", "148.251.238.178", "176.9.46.6",
    "54.173.72.127", "54.174.10.182", "54.183.64.54", "54.194.231.211",
    "54.66.214.167", "54.66.220.137", "54.67.33.14", "54.77.251.214",
    "54.94.195.96", "54.94.200.247"
])

import re
import sys
import dns.resolver

PATTERN_IPV4 = re.compile(r"^((\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})):9333$")
PATTERN_AGENT = re.compile(r"^(\/Satoshi:0.8.6\/|\/Satoshi:0.9.(2|3)\/|\/Satoshi:0.10.\d{1,2}\/)$")

def parseline(line):
    sline = line.split()
    if len(sline) < 11:
       return None
    # Match only IPv4
    m = PATTERN_IPV4.match(sline[0])
    if m is None:
        return None
    # Do IPv4 sanity check
    ip = 0
    for i in range(0,4):
        if int(m.group(i+2)) < 0 or int(m.group(i+2)) > 255:
            return None
        ip = ip + (int(m.group(i+2)) << (8*(3-i)))
    if ip == 0:
        return None
    # Skip bad results.
    if sline[1] == 0:
        return None
    # Extract uptime %.
    uptime30 = float(sline[7][:-1])
    # Extract Unix timestamp of last success.
    lastsuccess = int(sline[2])
    # Extract protocol version.
    version = int(sline[10])
    # Extract user agent.
    agent = sline[11][1:-1]
    # Extract service flags.
    service = int(sline[9], 16)
    # Extract blocks.
    blocks = int(sline[8])
    # Construct result.
    return {
        'ip': m.group(1),
        'ipnum': ip,
        'uptime': uptime30,
        'lastsuccess': lastsuccess,
        'version': version,
        'agent': agent,
        'service': service,
        'blocks': blocks,
    }

# Based on Greg Maxwell's seed_filter.py
def filterbyasn(ips, max_per_asn, max_total):
    result = []
    asn_count = {}
    for ip in ips:
        if len(result) == max_total:
            break
        try:
            asn = int([x.to_text() for x in dns.resolver.query('.'.join(reversed(ip['ip'].split('.'))) + '.origin.asn.cymru.com', 'TXT').response.answer][0].split('\"')[1].split(' ')[0])
            if asn not in asn_count:
                asn_count[asn] = 0
            if asn_count[asn] == max_per_asn:
                continue
            asn_count[asn] += 1
            result.append(ip)
        except:
            sys.stderr.write('ERR: Could not resolve ASN for "' + ip['ip'] + '"\n')
    return result

def main():
    lines = sys.stdin.readlines()
    ips = [parseline(line) for line in lines]

    # Skip entries with valid IPv4 address.
    ips = [ip for ip in ips if ip is not None]
    # Skip entries from suspicious hosts.
    ips = [ip for ip in ips if ip['ip'] not in SUSPICIOUS_HOSTS]
    # Enforce minimal number of blocks.
    ips = [ip for ip in ips if ip['blocks'] >= MIN_BLOCKS]
    # Require service bit 1.

 Using a filter does add to the protection of a connection. More IRC connections could be using filters to help reduce the number of malicious connections. Filtering out known suspicious connections helps, but additional filters need to be implemented. This particular filter checks IPv4 and should be changed to also include IPv6 connections.


 Netcoin uses a very similar IRC connection to litecoin. Many portions of code mirror litecoin or have striking similarities.

// Hybrid IRC used by lfnet always returns IP when you userhost yourself,
    // but in case another IRC is ever used this should work.
    printf("GetIPFromIRC() got userhost %s\n", strHost.c_str());
    CNetAddr addr(strHost, true);
    if (!addr.IsValid())
        return false;
    ipRet = addr;

    return true;
}



void ThreadIRCSeed(void* parg)
{
    IMPLEMENT_RANDOMIZE_STACK(ThreadIRCSeed(parg));

    // Make this thread recognisable as the IRC seeding thread
    RenameThread("bitcoin-ircseed");

    try
    {
        ThreadIRCSeed2(parg);
    }
    catch (std::exception& e) {
        PrintExceptionContinue(&e, "ThreadIRCSeed()");
    } catch (...) {
        PrintExceptionContinue(NULL, "ThreadIRCSeed()");
    }
    printf("ThreadIRCSeed exited\n");
}

void ThreadIRCSeed2(void* parg)
{
    /* Dont advertise on IRC if we don't allow incoming connections */
    if (mapArgs.count("-connect") || fNoListen)
        return;

    if (!GetBoolArg("-irc", false))
        return;

    printf("ThreadIRCSeed started\n");
    int nErrorWait = 10;
    int nRetryWait = 10;

    while (!fShutdown)
    {
        CService addrConnect("irc.lfnet.org", 6667, true);

        SOCKET hSocket;
        if (!ConnectSocket(addrConnect, hSocket))
        {
         addrConnect = CService("pelican.heliacal.net", 6667, true);
         if (!ConnectSocket(addrConnect, hSocket))
         {
            printf("IRC connect failed\n");
            nErrorWait = nErrorWait * 11 / 10;
            if (Wait(nErrorWait += 60))
               continue;
            else
               return;
         }
        }

        if (!RecvUntil(hSocket, "Found your hostname", "using your IP address instead", "Couldn't look up your hostname", "ignoring hostname"))
        {
            closesocket(hSocket);
            hSocket = INVALID_SOCKET;
            nErrorWait = nErrorWait * 11 / 10;
            if (Wait(nErrorWait += 60))
                continue;
            else
                return;
        }

 The same lfnet server is used, which is not unusual. It also uses the same pelican.heliacal.net connection used by litecoin. There are a lot of similarities between these 2 coins. They have the same vulnerabilities present and also employ the same seeding architecture. I.P. addresses of users are made public and may be exploited in the same fashion as previously pointed out in litecoin. Multiple coins are being passed through the same server, on the same channel and being operated by the same person. There was talk that the IRC functions are merely leftover from previous projects. This is false. None of the IRC has been commented out or changed. It points to a server that is still active and is sniffing seed traffic. Further research will be required to identify if this is a malicious connection or not.
4  Bitcoin / Development & Technical Discussion / Bitcoin Research Report, Part 1 on: June 17, 2015, 05:05:02 PM
 The primary purpose of this report is to clarify errors, identify vulnerabilities, determine the benefits versus the drawbacks of a particular coin and to help eliminate the threat of scam artists, liars and thieves.

 The first thing I looked at is the crypto. Encryption is a good thing for privacy and security. Converting, or hashing, output strings, makes it a lot more difficult for outsiders to view or use the information. Higher levels of encryption add to the difficulty in manipulating the information.

 Bitcoin uses the SHA256 library for crypto. A 256 bit encryption algorithm is a decent strength encryption. In this case however, it does not use a true 256 bit. It actually uses layers of 16 bit, 32 bit and 64 bit. The 16 bit layer actually hashes out to 20 bits. The total output for all layers is in the neighborhood of 256 bits, but total output (sum), is not the same as a true 256 bit output. It is dramatically easier to crack a single layer of 20, 32 and 64 bits compared to a single 256 bit string.

 The use of open source crypto is good for debugging, teaching purposes, identifying common errors and etcetra. But being the double-edged sword, it also allows nefarious programmers to get the information they need to crack it. In the case of SHA256, the hasher works as it should. The conversion process adequately converts the output. But, the chunker, that divides up the output into chunks for converting, only actually chunks out to 30 and 60 bits. Leaving 2 and 4 bits respectively, to hang in limbo. These bits are potentially passed through the network unencrypted.

 Some would argue that it's only the last 4 bits, and won't matter. Well, it's only the lottery, and you were given the last 4 numbers of the winning number for free. You only have to come up with a few more numbers to hit it big. Assuming that the last 2 and 4 bits left over from the chunker are included in the previous bit for conversion, then the last chunk becomes 3 and 5  bits, instead of the 1 bit at a time to be converted. It's possible that the last chunk is discarded for irregularities, thus remaining unencrypted. Or, it does get converted, but does not improve the encryption or reduce the chances of a successful crack. This is easily fixed by recoding the chunker to actually chunk out to the full 32 and 64 bits, as indicated in the output from source. There could also be minor adjustments for efficiency and less resource consumption, but these are not any kind of mandatory changes nor are required for this crypto to work properly.

 Here is the source for the bitcoin header. As you can see, it clearly uses 16, 32 and 64 bit outputs.

// Copyright (c) 2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef BITCOIN_CRYPTO_COMMON_H
#define BITCOIN_CRYPTO_COMMON_H

#if defined(HAVE_CONFIG_H)
#include "bitcoin-config.h"
#endif

#include <stdint.h>

#include "compat/endian.h"

uint16_t static inline ReadLE16(const unsigned char* ptr)
{
    return le16toh(*((uint16_t*)ptr));
}

uint32_t static inline ReadLE32(const unsigned char* ptr)
{
    return le32toh(*((uint32_t*)ptr));
}

uint64_t static inline ReadLE64(const unsigned char* ptr)
{
    return le64toh(*((uint64_t*)ptr));
}

void static inline WriteLE16(unsigned char* ptr, uint16_t x)
{
    *((uint16_t*)ptr) = htole16(x);
}

void static inline WriteLE32(unsigned char* ptr, uint32_t x)
{
    *((uint32_t*)ptr) = htole32(x);
}

void static inline WriteLE64(unsigned char* ptr, uint64_t x)
{
    *((uint64_t*)ptr) = htole64(x);
}

uint32_t static inline ReadBE32(const unsigned char* ptr)
{
    return be32toh(*((uint32_t*)ptr));
}

uint64_t static inline ReadBE64(const unsigned char* ptr)
{
    return be64toh(*((uint64_t*)ptr));
}

void static inline WriteBE32(unsigned char* ptr, uint32_t x)
{
    *((uint32_t*)ptr) = htobe32(x);
}

void static inline WriteBE64(unsigned char* ptr, uint64_t x)
{
    *((uint64_t*)ptr) = htobe64(x);
}

#endif // BITCOIN_CRYPTO_COMMON_H


 Another example, taken from source, is the output of one of the layers as 20 bits. Elsewhere in source it starts as a 16 bit layer, but actually outputs to 20. This is ok.
// Copyright (c) 2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef BITCOIN_CRYPTO_SHA1_H
#define BITCOIN_CRYPTO_SHA1_H

#include <stdint.h>
#include <stdlib.h>

/** A hasher class for SHA1. */
class CSHA1
{
private:
    uint32_t s[5];
    unsigned char buf[64];
    size_t bytes;

public:
    static const size_t OUTPUT_SIZE = 20;

    CSHA1();
    CSHA1& Write(const unsigned char* data, size_t len);
    void Finalize(unsigned char hash[OUTPUT_SIZE]);
    CSHA1& Reset();
};

#endif // BITCOIN_CRYPTO_SHA1_H

Here is the 32 bit output:

// Copyright (c) 2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef BITCOIN_CRYPTO_SHA256_H
#define BITCOIN_CRYPTO_SHA256_H

#include <stdint.h>
#include <stdlib.h>

/** A hasher class for SHA-256. */
class CSHA256
{
private:
    uint32_t s[8];
    unsigned char buf[64];
    size_t bytes;

public:
    static const size_t OUTPUT_SIZE = 32;

    CSHA256();
    CSHA256& Write(const unsigned char* data, size_t len);
    void Finalize(unsigned char hash[OUTPUT_SIZE]);
    CSHA256& Reset();
};

#endif // BITCOIN_CRYPTO_SHA256_H

 The algorithm used works. The library used that the crypto is based on, works as it should. The names were made to be a bit misleading, but more than likely, that is to try and deter would-be crackers from trying to crack the encryption and get in. Because this deals with money, I would recommend that the crypto is written out to be a full 256 bit layer, or even use the 512 bit. The reality is, anything less than 256 bit can be cracked by a child with a brute forcer, and time.
 
  All of this can be found on Github. Look here for the crypto source and see for yourself: https://github.com/bitcoin/bitcoin/tree/master/src/crypto
5  Alternate cryptocurrencies / Altcoin Discussion / Re: Putting Scammers On Notice on: June 15, 2015, 10:12:36 PM
 I'm not here for friends. I'm here to clean up the mess. Or at least attempt to. Obviously there are already trolls trying to claim I'm a scammer. To hide the fact that they are scoundrels, liars and thieves. You will refute facts based on source. You will refute facts based on cited references. You will lie, you will argue and you will debase anyone who does not go along with your lies and nonsense. So say what you will. Facts will prove who is full of it and who is not. Facts will prove who is the scumbag and who is not.
 So argue, complain, cry to whomever you think will listen. I don't care. Hell, I recommend you go ask around about me. Or just go ahead and be the brainless dolts I know you to be and make it even easier for me to humiliate you in public. I won't hide. I don't run. And best of all, you don't know anyone good enough to take me on.

 And to you who claim that my statement about devs who try to collect money upfront is harsh, it's a fact. Either you're one of the scum who steal from honest people, or you're just seriously misinformed about how programming works. Especially with FREE, OPEN SOURCE software that does not cost a dime to get or to use.
6  Alternate cryptocurrencies / Altcoin Discussion / Putting Scammers On Notice on: June 15, 2015, 07:20:40 PM
 I've been a developer for many years. A friend encouraged me to look into Bitcoin. Well, crypto currency in general really. I've been reading through forums, looking at sources from both Sourceforge and Github, compiling libraries and trying to keep up on current news and trends involving crypto currency. I do like many of the features offered by various coins. I think that crypto currency has a big future. What I don't like is how many scam artists have sprung up. I'm also not impressed by the "developers" who just copy and pasted someone else's code into a compiler and did nothing but change some names to attempt to look different. I've noticed that there are also poorly coded coins and wallets. Mostly made by scam artists, "skids" and thieves hoping to make a quick dollar at everyone else's expense.

 I think the crypto (SHA256) is ok, but several coins actually only use the library. They hash out to 32 bit and 64 bit strings and do not actually use 256 bit strings. The hasher leaves unused bits of data in your RAM that can quickly build up and max out resource consumption. This can be solved with a simple flush added. The encryption however needs to be written out to the full 256 bit strings. The chunker also falls short in some coins, actually only converting 60 bits of the 64 bits it will output. Which leaves 4 bits "in limbo". These bits may be simply hashed with the previous bit, making the last chunk actually 5 bits, rather than 1. It may also just pass the data unencrypted. I've seen some coins that are addressing the issue, but many coins are not.

Using IRC for node detection is not a bad idea. However, the channels used for many coins leave data unencrypted and vulnerable. The wallets actually seed your information. It publicly posts your I.P. address and user information and makes a log file. The IRC channels must be maintained on a regular basis or else everyone whose wallet uses that channel is at serious risk. Not to mention that if the owner of the server shuts it down, you have a wallet that is worthless until fixed. Because the IRC server seeds your wallet and information, the owner of the server can take coins out of your wallet if they wanted to. Or even set up so that others to do the dirty work, while giving the appearance that they had no idea what happened. Not all of the IRC connections used are fraudulent. But any use of IRC is a vulnerability if not back-ended properly, and not put on a secure server, on a secure network, operated by a trusted network administrator on a domain that is actively maintained.

 I'll be posting screen captures from source and articles designed to point out the good stuff and the bad. I have been doing extensive testing and debugging, in hopes of improving and optimizing crypto currency/wallets. I would like to also bring the light of day to scams and schemes designed to steal from you. I'm very sure that all the wrong people will be angry that I've gotten involved. I'm sure that they have friends that they will try to get involved, in an effort to "scare" me away. Good luck with that. I like the technology and the potential for innovations and pioneering technologies. there are good people in the community that should not have to deal with so many scams and liars. Where there is money, there are thieves. Hard to get rid of them all. But if we can make it more difficult for them to steal and more difficult for them to pull of scams, then the community will prosper more.

 When dealing with "developers", if they ask for money upfront, it's a scam. If you are a developer, then you already have the IDE and any software libraries needed. You have already worked on a similar project and are familiar with the rules and regulations, what clients expect and you know how to be professional. Any deviation from this is a red flag. Only liars, thieves, scammers and frauds want money up front for what they claim is the cost of starting the project. Or they "run out of code" as I heard tell once. How do you run out of code? Who in their right mind believed them when they said that? People make mistakes. Nothing wrong with making a mistake. Learning from said mistake is what matters more. Many people in the community cannot read code and do not know exactly what went into development. So it's easy for the fraud developer to say whatever they want. You really don't know if what they say is true or not. So you just take them at their word. And then they take your money and run.

 As I continue to delve into the sources of many coins and wallet types, I will be posting all of my research findings to this forum, as well as others. The more informed and educated the community gets, the better prepared it will be to deal with threats. I've been at this a very long time. I've dealt with skids and scammers before, on many occasions. None of them have lasted long after I put them on blast. Any scammers on this forum, you are on notice. I'm going to show everyone exactly what kind of scum you are. Which will allow the legitimate developers to do the work they need to do. And allow the community to get a better product and a better experience.
Pages: [1]
Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!