That band said: Welcome to the jungle, welcome to the jungle, nananana na niii niii… yes. Here we go.
Let’s start with the LinkedIn romanticizing: bazillions of positions — but no real opportunities. If you don’t know the secret of that industry, I’ll tell it to you: you need to know someone, who knows someone, who knows someone… otherwise, you’re in limbo.
After many years working in the IT industry, with experience in Open Source, the Linux kernel, and a bunch of security, I found myself in limbo. The process of getting attention from a company starts only if your resume gets noticed — in the era of AI screening? Forget it! Unless, of course, you’re not playing by the rules. If you’re familiar with the regex-match concept, you’ll get it very quickly. These days, that’s what it’s all about. It reminds me of my past days working at a local company, where I was asked to triage good candidates for a position. The one I chose? The one with no experience, but who was very motivated to learn and was passionate about it. Yep — no regex-match in his resume. A couple of years later, that person became a very active member of the open source community, making history and becoming an excellent professional. Why am I telling you this? Because it’s not about whether you match or not — it’s all about potential, about whether you’re willing, whether you have passion. It’s about opportunities.
But I’m probably romanticizing that too, we live in an unequal world with stupid wars around us. Opportunity is, of course, a joke. Well, back to the jungle to watch that terrible reality show.
In Git the CVE-2024-32002 is regarding a RCE (remote code execution) vulnerability that can be exploited through repositories with sub-modules. I won’t go deep in the CVE itself, as there are good sources around in how to exploit it and how it works, such like this [1]. The idea here is to step-by-step show how you could set an EXT4 file system with case-insensitive enabled. First of all, it is important to mentioned that this feature was introduced in Linux 5.2 [2]. Hence you need to check if you system supports it. For this, just type:
$ cat /sys/fs/ext4/features/casefold
It should show: supported. Now if your system supports it, let’s create a file system EXT4 with that feature enabled. But instead to format a whole partition to have it. Let’s use a block device using Loop device. Follow these steps:
# Create a file to be your block device
$ dd if=/dev/zero of=filename bs=1024 count=51200
# After that the filename was created with blocks of 1024 size in total of ~51M.
# Now, check which loop device is available:
$ losetup -f
# output example: /dev/loop1
#Create the the block device with the available loop device
$ losetup /dev/loop1 filename
# where filename is the block file you created using dd
Now that you have a loop device the next step is to create the file system with casefold enabled and mount it in some point.
$ mkfs -t ext4 -O casefold /dev/loop1
# create the poc directory where you'll mount it in /mnt/poc
# remember to set the permissions to you
# chown -R your_user:your_user_group poc
# e.g: chown -R corecode:corecode poc
$ mount -t ext4 /dev/loop1 /mnt/poc
# check if was mounted
$ df -h /dev/loop1
# check that device/fs supports case insensitive looking for
# Filesystem features: ... filetype needs_recovery extent 64bit flex_bg casefold <--
$ sudo tune2fs -l /dev/loop1
# Now you have a folder set with that file system mounted. To enable case insensitive in a folder you need to:
$ chattr +F directory
# If you want to check which a given directory is case-insensitive supported:
$ lsattr .
# output: ----------------F--- directory
In order to reproduce the Git CVE-2024-32002 PoC you can grab the script in here and give it a try. Pro-tip: change the execute program session to something Linux understand: e.g: cal or gnome-calculator or whatever you want.
If you are familiar with Bash scripting you probably knows what trap is and does. If not, here is a quick summary of it:
“trap signals and other events.
Defines and activates handlers to be run when the shell receives signals or other conditions“
If you read or type Bash script you already either was trap on it or added some to handle within a specific situation. These days I’m translating a bash code into python and found it, so decided to implement a trap that handles with that specific situation. Bash code was something like:
Situation is basically you create a temporary directory and want to have it delete in case a signal happens. The way Bash does is basically signal handling, so to do it in Python is quite easy.
import os
import signal
import tempfile
def trap(tmpdir):
# the handler func
def remove_dir(signum, stack):
os.rmdir(tmpdir)
signals = []
for n, i in enumerate(signal.Signals):
# 1 to 15 signal except sgkill (9)
if int(i) != 9:
signals.append(i)
if n+1 == 15:
break
# if any of these signals is triggered
# calls the handler func.
for i in signals:
signal.signal(i, remove_dir)
# testing ...
if __name__ == "__main__":
# creates a tempdif into current . dir
tmpdir = tempfile.mkdtemp('','','.')
trap(tmpdir)
while True:
pass
Ok, I know that starting it with a title like “int sign bit field issue” induces one to think that there is an issue with all this by definition.There is an issue, but in reality if one knows how the types works s|he probably won’t make this mistake at all, so, it’s not C fault, but the programmer that doesn’t care about computer arch or C specifications. But what is the so called issue? Let’s see.
Just imagine someone decides to create its own bool type. We know that stdbool exists today, but in the past it wasn’t there at all. Because this, many were those that created their own bool type. Now imagine that someone decides to save bits usage, what is a very altruist way to think, for sure. Imagine that s|he does like this:
Did you spot anything that need to be care about? If not, no problem, this post is exactly about it. Let’s look at line 8. It declares a variable of type t_bool and shrinks it to a bit field of size 1 (one bit: 0 or 1). So far so good. The idea here was to use just one 1 bit to define a bool, since we just need either 1 or 0 bit set. But…I said but. If you run this program you’ll see that when a TRUE is set to b.a it is not truly true, well, in C it is kind of, since anything diff than zero is true expression. But if you have a function that returns TRUE and you need to check it against the b.a value? Yep, it is here where the things get messy.
If you run this program you’ll see something like:
-1 0 Ooopsie!!!
Yep. Definitely there is something wrong. See that I did declared explicitly t_bool as a signed int, but remember that if you say just int it is already a signed int. Ok, ok, but what is the point with the signed? Exactly. A signed type needs one bit to set the sign. Did you get the “AHA” ? Let’s show using a image 🙂
Let’s just simplify that a int size is 2 or 4 bytes arch depending. As the image shows a byte has 8 bits, and in a sign int one of the bits is used to set the sign.
In our code, we set type bool to be a 1 bit size. But wait, it is a sign int what happen with the sign? Exactly, nothing, it will be there, the real question would be: what happen with the value? It’s used to set the sign bit. That is why when you run that program you’ll see b.a = TRUE as -1 not 1, because you are setting the bit sign to 1, that means a negative sign.
There is plenty of vulnerabilities found around that are about signed and unsigned types. Some of them mostly happen because C is a kind of hard language in the sense of you need to know exactly what are you doing, and well, sorry for that, in the last years with all these high level languages developers get to be very slack and careless about how things works closely to the hardware (as C does).
References: This post was based on that twitter post.
I would say because it’s an often mistake, mainly when you are refactoring or backporting code. The way it is simple makes it worth. Though, if one don’t understand a bit of PHP internals would make that mistake often for sure, keep reading and you see why.
The story is full of simple bugs that caused mess all around the IT world. Do you remember the “goto fail” in Apple SSL? Remember it in here and you’ll have a clear idea that some bugs are quite simple but can cause quite a disaster. Like I used to say in the programming classes: “a small bug can cause a spaceship to crash into an innocent house, and you don’t want it at all!”.
But what CVE-2021-21708 is for?
when using filter functions with FILTER_VALIDATE_FLOAT filter and min/max limits, if the filter fails, there is a possibility to trigger use of allocated memory after free, which can result it crashes, and potentially in overwrite of other memory chunks and RCE.
Sounds weirdo and alien to you? Better if we show the code so:
switch (is_numeric_string(num, p - num, &lval, &dval, 0)) {
case IS_LONG:
zval_ptr_dtor(value);
if ((min_range_set && (lval < min_range)) || (max_range_set && (lval > max_range))) {
goto error;
}
ZVAL_DOUBLE(value, (double)lval);
To be more clear, take a look in line 3. zval_ptr_dtor(value); If it is not clear yet, let me clarify what this function does:
zval_ptr_dtor will first decrement its refcount by one. If the refcount is 0 after decrementing by one, it will call zval_dtor to release tmp->value, and then call the efree_rel() function to remove the zval type structure pointed to by tmp. The occupied memory space is released.
What if it is not 0 after subtracting one? Then zval_ptr_dtor will not release tmp->value and tmp itself, but notify the GC garbage collector, and then return.
All that description can be translated basically in: it does deallocate memory for value. And as you can see in the following code line 4 if it fails it goto error and let behind a piece of object that will soon be allocated to whatever, creating the use-after free bug/vulnerability. This type of vulnerability could possibly cause a crash (denial of service) and unexpected behaves. To make it more scared there is even a PoC to it. The way upstream fixed it was simply removing zval_ptr_dtor from 3 and adding above ZVAL_DOUBLE so it will deallocate and reinitialize value again. Elegant, isn’t?
In the last three years (by the eyes of this blogger) Ubuntu has showed more and more to the world that for sure Security matters! This post will list you the amazing things Security team at Ubuntu has made happens to make the life of normal users and pay customers better. The first one is all about be aware, about get trend info, and if you are too busy to keep reading notes and blogs, you will love to know Ubuntu Security Team has a podcast fulled of info about what is trend, what the team is doing what were the last dragons they found at the bugs caves and so on. The podcast is made by these two amazing guys at our team: Alex Murray (the Security Tech Leader) and Joe McManus (Engineering Director at Security). Go for it and take a listen and get the knowledge at Ubuntu Security Podcast.
Second one is about be aware of your system and security bugs/patch needed. Ubuntu has a brand new tool called cvescan:
CVEScan analyzes an Ubuntu system to check whether all available security patches have been installed. CVEScan produces a clear, concise report that tells you which, if any, security patches an Ubuntu system may be missing.
I could talk more about it, but go there play with it and it will talk for itself. More info about and steps to install here .
The third one is about updates. There is nothing worst than see a vulnerability be dropped over the internet and see that your system is vulnerable mainly if you run critical software/products in your work, for fun or so on. Ubuntu does hundreds of security updates in months and you can follow the notices about them at the Ubuntu Security Notes website. But if you are looking for standards ways to be aware of it you can go nuts and check another brand new thing Ubuntu has made available the Ubuntu Oval. If you are not familiar of OVAL, here a short description of it:
Open Vulnerability and Assessment Language is an international, information security, community standard to promote open and publicly available security content, and to standardize the transfer of this information across the entire spectrum of security tools and services.
Basically using the OVAL you can achieve things like see if you system needs an update/patch, quite same as it is in CVEScan, the difference here is that OVAL is made for machines consuming and spit some beauty/info html report, while CVEScan already presents you with a beautiful report at your terminal screen and was made for humans to consuming.
Last but not least Extend Security Maintenance (ESM). How about continue to receive security updates after your LTS release goes EOL? That is the exactly idea behind Ubuntu ESM. Just imagine you are using Xenial and can’t move to a new brand release right now, but you can’t let your system insecure, so that was made for you! If you sign for this you will keep receiving a set of updates for a give list of packages without concern about security breaches.
As you can see there are bunch happening in terms of Security in Ubuntu, this list is just a small subset of the great adventure Ubuntu is doing at security lands, and so far it sounds great. Sounds Ubuntu Security is in very good hands and that is why you should choice Ubuntu, for sure!
If you work with security IT you probably know what is OVAL. It stands for Open Vulnerability and Assessment Language. It was created to standardize the ways to assess and report machines/system states regarding vulnerabilities or just a given desired setting. Remember that there are bunch certifications with bunch of requirements for some settings at the system to follow a given ‘pattern’, e.g: if apache is installed it must be running in port 443. With the definition of a OVAL file you are able to scan your system and say if it is vulnerable to an issue or if it pass in a given certification requirements.
Disclaim:If you don’t like crazy XML please stop here. But if you can stand it a bit, let’s go on.
OVAL language is based on a couple of XML schemes that gives your/or the coder the ability to say what to look at the system and test if it is match or not. I know, it sounds quite like voodoo without to see any code. I’ll give a simple example. Imagine your machine uses a package version, and it happens that version be vulnerable to a security issue . If you don’t keep an eye or create you own script to check for vuls you will never know about it till your distro secure update it (mostly of the cases normal users don’t care about it at all. So, that is more for system admins). OVAL creates a set of information basically saying what to check at your system against what is defined at the OVAL scheme. Sounds confuse? Let’s see the code – for propose of this post/article I will skip all the header info and focus at the action/body of the thing. You can grab more info about it at the references at the bottom of this post.
<definitions>
<definition class="inventory" id="oval:ubuntu.xenial:def:500" version="1">
<metadata>
<title>Check if it is Ubuntu 16.04 that is installed.</title>
<description></description>
</metadata>
<criteria>
<criterion test_ref="oval:xenial:tst:500" comment="Ubuntu 16.04 is installed." />
</criteria>
</definition>
<definition id="oval:xenial:def:501" version="1" class="patch">
<metadata>
<title>Test if Pillow is vulnerable to CVE-2020-10177</title>
<affected family="unix">
<platform>Ubuntu 16.04</platform>
</affected>
<reference source="Mitre" ref_url="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-10177"/>
<description>Pillow before 7.1.0 has multiple out-of-bounds reads in libImaging/FliDecode.c.</description>
</metadata>
<criteria>
<criterion test_ref="oval:xenial:tst:501" comment="test if Ubuntu 16.04 is installed at my system" />
</criteria>
</definition>
<tests>
<ind:textfilecontent54_test check="at least one" check_existence="at_least_one_exists" id="oval:xenial:tst:500" version="1" comment="Ubuntu 16.04 LTS is installed.">
<ind:object object_ref="oval:xenial:obj:500" />
<ind:state state_ref="oval:xenial:ste:500" />
</ind:textfilecontent54_test>
<linux:dpkginfo_test id="oval:xenial:tst:501" version="1" check_existence="at_least_one_exists" check="at least one" comment="?">
<linux:object object_ref="oval:xenial:obj:501"/>
<linux:state state_ref="oval:xenial:ste:501"/>
</linux:dpkginfo_test>
</tests>
<objects>
<ind:textfilecontent54_object id="oval:xenial:obj:500" version="1">
<ind:filepath datatype="string">/etc/lsb-release</ind:filepath>
<ind:pattern operation="pattern match">^[\s\S]*DISTRIB_CODENAME=([a-z]+)$</ind:pattern>
<ind:instance datatype="int">1</ind:instance>
</ind:textfilecontent54_object>
<linux:dpkginfo_object id="oval:xenial:obj:501" version="1">
<linux:name var_ref="oval:xenial:var:501" var_check="at least one" />
</linux:dpkginfo_object>
</objects>
<states>
<ind:textfilecontent54_state id="oval:xenial:ste:500" version="1" comment="Ubuntu 16.04 LTS">
<ind:subexpression datatype="string" operation="equals">xenial</ind:subexpression>
</ind:textfilecontent54_state>
<linux:dpkginfo_state id="oval:xenial:ste:501" version="1">
<linux:evr datatype="evr_string" operation="less than">3.1.2-0ubuntu1.4</linux:evr>
</linux:dpkginfo_state>
</states>
<variables>
<constant_variable id="oval:xenial:var:501" version="1" datatype="string" comment="?">
<value>python-pil</value>
<value>python3-pil</value>
</constant_variable>
</variables>
Now that we have a snippet of what it looks like. Let’s explain the basic pieces and how it works. We can basically defined the OVAL files in five pieces: definitions, tests, objects, states and variables.
definitions: basically says some overview information about what you want to check. I won’t go deep in details here about the attributes, but let’s explain just two of them. In this example we are using class=inventory and in the second definition class=patch. As the name suggests inventory is used to defined something regarding your asset , in this case, what distro you have installed. Patch one, is used to check if a patch was applied at the system. We will understand how it does it in the next steps, but you can read more detailed info here.
tests: defines what tests we want to do, using a specific schema (by example, in debian system it can use dpkg, in rhel systems rpminfo, and so on).
objects: aggregates the info that will be checked, exactly like an object it keeps the tracks about the state and variables we want to check for a test.
states: the state you want to check against. In our case we want to look if the version in our system is less than the version in state, if it so we need to patch the system, because it is vulnerable.
variables: defines a set of constants variables to check against.
Disclaim: keep in mind these ^ definitions are mostly how I did abstracted it. To have a real/exact detailed explanation check here.
Now let’s explain what this ugly XML should do. Line 2 stands for a definition of what system we have, and to run the scan tools we need to know if the system we have installed are the one defined there. In our case Ubuntu Xenial. Line 7 we have the criteria to be check for this definition. In there we have a “pointer” to the test that should be run by the scan. If you jump to test id 500 you will see that it does some references to object 500 and state 500. Jumping in object 500 first we see that what it basically does is define where to check a given pattern. Jump in state 500 (and that is why some people hates OVAL – that keeping jumping thing just remember it was create for tools to read, not human beings) you will see that it is expecting to find the “xenial” name when checking in /etc/lsb-release for. Cool right? We got the bits of how it works. Now for the second definition, to check if a package in our system has a version that is vulnerable to some CVE was report in Mitre, it’s quite the same steps. The only differences here is that is checks in the variables, by the name of the binaries and look in the state 501 to see if these binaries has a version “less than” 3.1.2-0ubuntu1.4, if so, the scan returns true and your system needs a patch/a security update.
To run a scan in this OVAL file ( you can grab that test file here) you will need the oscap tool. To install it at Ubuntu 16.04: sudo apt-get install libopenscap8. After this, just run:
As you can see at the image above. My system is true for xenial and the need of the patch for Pillow package is false. So, I’m not vulnerable to this CVE. You can run it in your system, let’s say Bionic or other release, and you will see it saying false for the release.
That is it. OVAL is a quite nice standard to grab information and check systems in a several aspects. As said before, keep in mind XML files were made for machines/tools read, so if you get dizzy looking into these it’s quite the expected, as XML is a mess .
Hope you got the bits about what why it’s so trend now and the usages and importance of it. Keep in mind it was just a quick and superficial explanation of how it works. If you disagree with any thing explained here, please drop a comment. If you want to go deep in the dark of these XML schemes just consult the references bellow. Thanks =)!
These days I did a presentation in a local event (Poticon 2018). It was about some silly security pranks and I was surprised when I asked about disk encryption and/or grub password and only one person hands up. The majority didn’t use any measure to protect their machines. You may asking why I got so surprised or concerned and the answer is simple: init=/bin/bash into your grub config plus mount -n -o remount,rw /; passwd. Yep, if you got it you know exactly what I meaning. A machine without any protect is completely vulnerable to someone change your root password and worst than that. If you do a fresh install and select you user to be into the adm group or sudo group the password you pick will work for you user do a sudo and become root, but if someone change your root password by falling into /bin/bash from grub you’ll probably never realize that your root passwd changed unless you ssh as root to your machine and, of course, be blocked to get into it.