Here’s what I don’t get: why the many layers of obfuscation in the build phase? (I understand why in the binary linked into ssh.)
Once the first stage, extracting a shell script from one of the „test“ data blobs, has been found it was clear to everybody that something fishy is going on.
It’s inconceivable that I’ve would have found the first stage and just given up, but then it was „only“ a matter of tedious shell reversing…
They could easily done without the „striping“ or „awk RC4“, but that must have complicated their internal testing and development quite a bit.
> It’s inconceivable that I’ve would have found the first stage and just given up
But what you were looking at might not be the first stage.
You might be looking at the modified Makefile. You might be looking at the object files generated during the build. You might be looking at the build logs. You might be investigating a linking failure. The reason for so many layers of obfuscation, is that the attacker had no idea at which layer the good guys would start looking; at each point, they tried to hide in the noise of the corresponding build system step.
In the end, this was caught not at the build steps, but at the runtime injection steps; in a bit of poetic justice, all this obfuscation work caused so much slowdown that the obfuscation itself made it more visible. As tvtropes would say, this was a "Revealing Cover-Up" (https://tvtropes.org/pmwiki/pmwiki.php/Main/RevealingCoverup) (warning: tvtropes can be addictive)
Reduces the attack area through which this could be found, I expect. Without all the obfuscation someone might spot suspicious data in the test data or at some other stage, but this basically forces them to find the single line of suspicious shell script and follow the trail to find the rest of the stuff added to the build process.
> Here’s what I don’t get: why the many layers of obfuscation in the build phase?
For a one of its kind deployment it would probably not matter. However, deploying to multiple targets using the same basic approach would allow all of them to be found once one was discovered. With some mildly confsing but different scripting for each target systematic detection of others becomes more difficult.
Or using a certification authority for users (TrustedUserCAKeys in sshd_config), so that any user that has a signed certificate, and owns the corresponding private key, would be allowed to login. No further updates of authroized_keys files needed.
And, to further automate the ssh login, maybe your LUKS container could have a second (Nth) key-slot being a random key RSA-encrypted with the other machine's identity private key? (https://bjornjohansen.no/encrypt-file-using-ssh-key for examples)
But generally, I really dislike the use of LUKS in this case, as I think a filesystem based encryption (not encrypting whole block devices) would make more sense. I understand that this isn't as mature as LUKS, though.
> Also I’m curious about the 1-bit recording. Is that a thing?
Yes. This homemade GPS receiver uses a simple comparator (1 bit) to sample the signal (after amplification to get the noise floor over the decision threshold).
Here's a paper that shows reflections (Fig. 3, "S11") and insertion loss (Fig. 4, "S12") on coplanar waveguides, when using a sharp 90° bend, a 90° bend with a champfer and the case where the bend is replaced by two successive 45° turns ("final design").
I'm a chip designer and this article kinda cracked me up. For microwave signals on submicron lines, losses get very significant. It seems that PCB design inherits our practices in places these issues aren't so critical.
But then I wonder about applications. If you ignore this rule of thumb, and gang a few hundred boards together sharing a clock... will your signal survive?
Sometimes a 'superstition' is just common sense regarding edge cases - walking under a ladder won't have cosmic effects, but a dropped bucket of paint can leave a mark
That or using discontinuities in impedance intentionally. I've designed and had built a handful of successful UHF planar PCB filters using Sonnet. In a lot of them I use very small changes in trace width as the place to put resonating elements. ie, http://superkuh.com/stepped-impedance-bandstop-filter.html
The difference between square corners and compensated is real. And it gets more real if you're working in generic FR4 with 1.6mm thickness and 2-3mm wide traces for the sweet spot between 50 and 75 ohms.
You can play around with this type of simulations quite easily. Have been using free version of Sonnet planar EM solver [1] for this over the years. Helpful in developing the industry standard magic RF intuition.
The "final design" is the chamfered bend with additional vias, a design with two 45° bends was not studied in this paper. Page 2, second paragraph of section A :
> The final design that includes both the chamfered bend and the vias
ARM Cortex M4 supports adressing individual bits (often registers of hardware peripherals) of memory locations as one additional memory location writing to, or reading from a single bit.
Also Analog Sharc DSPs (which, I think, still are being sold with this architecture, and still used, even though I've used them only 10 years ago) alias their memory four times, depending if you want to access it as 16bit, 32bit, 48 or 64bit data.
Probably so the compiler doesn't just optimize out the statements, seeing as they don't seem to have a visible effect on the program execution because they're never read again.
because writing to one location causes the data to change in another (a system register) you don't want the compiler to assume that data in an IO register can be cached in a CPU register
int result;
for (int i = 0; i < 77232917; i++) {
result = 2 * 2; <----- you basically said result=4 77232917 times
}
return result - 1; <--- and then 4-1=3
The classic division operator makes it hard to write numerical expressions that are supposed to give correct results from arbitrary numerical inputs. For all other operators, one can write down a formula such as xy*2 + z, and the calculated result will be close to the mathematical result (within the limits of numerical accuracy, of course) for any numerical input type (int, long, float, or complex). But division poses a problem: if the expressions for both arguments happen to have an integral type, it implements floor division rather than true division.
-----------------------
To guarantee the correct mathematical behavior in python2, one would probably have to write:
def true_math_div(a,b) :
if type(a) is int or type(a) is long :
a = float(a)
if type(b) is int or type(b) is long :
b = float(b)
return a/b
as a and b could be int, float, complex, or some object defining the method __div__.
Once the first stage, extracting a shell script from one of the „test“ data blobs, has been found it was clear to everybody that something fishy is going on.
It’s inconceivable that I’ve would have found the first stage and just given up, but then it was „only“ a matter of tedious shell reversing…
They could easily done without the „striping“ or „awk RC4“, but that must have complicated their internal testing and development quite a bit.