How kernel modules is loaded and organized in memory?

Just piecing together various resources from internet:

Advertisements

Linux userspace rootkit detector

Looking through the various rootkit detector:

A-Protect https://github.com/sincoder/A-Protect.git
Blackbone https://github.com/DarthTon/Blackbone.git
chkrootkit https://github.com/Magentron/chkrootkit.git
kjackal https://github.com/dgoulet/kjackal.git
ossec-hids https://github.com/ossec/ossec-hids.git
rootkit.com https://github.com/bowlofstew/rootkit.com.git
rootkit_detector https://github.com/Freedzone/rootkit_detector.git
rootkit-detector https://github.com/CMQY/rootkit-detector.git
ScDetective https://github.com/kedebug/ScDetective.git
wazuh https://github.com/wazuh/wazuh.git

Some are linux, and some are Windows. So here I am proposing more features to add to this technology – linux userspace rootkit detector (not kernel-based rootkit):

1. Dynamic library injection through LD_PRELOAD. So upon the startup of the process, the envionment variable LD_PRELOAD would have been defined. This is not common, but can be easily detected:

/proc/PID/environ will display all the environment variables upon starting up of process.

As you can see above, the environment variables are NULL terminated, and so “grep” will not work – which is newline based, but overcoming this is easy.

2. Network port opening: rootkit may be listening on certain ports waiting for incoming connections. Thus a simple “netstat” should reveal some abnormal listening ports.

3. Network connections: for a server which mainly deals with LAN-based transaction (eg, Oracle database) then all the communications most likely will arise from local communication. But the existence of a rootkit will disrupt this generalization adnd patterns. Some internet IP address in this communication exchanges will likely indicate the existence of internal LAN-based agent communicating with internet-based agents.

4. In dynamic library injection as described in (1) above, you will like to see some weird library files injected into the traditional locations of library files:

Either “lsof” or “cat /proc/PID/smaps” will reveal all the dynamic libraries loaded by the process:

Therefore detect the possible existence of outliers in the dynamic libraries enumeration – for example, the name of the library files can come from some other non-standard directories – is this normal?

BUT do take note that the non-existence of the dynamic files does not mean it is not used – a shellcode can be written to dynamically call dlopen() to load the library file.    (and then you have to use vulnerability to execute the shellcode).  And thereafter dlclose() it after use.

And there are so many other possibilities: what if a process is actively snooping on the keyboard buffer (for each terminal)? what if someone is listening on the mouse?

Doing a “dmesg|grep hda”, I can find a lot of references to /devices/pci* indicating things like /sound/cardx/inputy, or devices/*sound/card0/input0 – these are called “devfs”.

Two techniques are available:   Linux notification API and devices capturing program via devfs.

If you issue a “lsof” you can easily estimate how many mouse and keyboard listening processes are there:

image1.png

How to install Oracle Database based on dockerfiles and images from Oracle

Download all the dockerfiles:

https://github.com/oracle/docker-images

Navigate to :

docker-images/OracleDatabase/SingleInstance/dockerfiles

Download Oracle Database (12.2.0.1) from www.oracle.com:

and copy it to the directory (12.2.0.1):

Noticed the file name “linuxx64_12201_database.zip” is given by Oracle, which the script will recognize.
This is the main command that start everything (-v is for version, -e is for Enterprise Edition):

bash buildDockerImage.sh  -v 12.2.0.1 -e

Output of installation is here (https://gist.github.com/tthtlc/d9825431eb13a4337c723411172b73da).

Upon completion of installation, a new docker image will be created:

docker images

REPOSITORY                       TAG                     IMAGE ID            CREATED             SIZE
oracle/database                  12.2.0.1-ee             49712d6a0946        3 hours ago         13.3 GB

And given the image ID above, we will connect via (and notice the password is given here):

docker run -it 49712d6a0946

ORACLE PASSWORD FOR SYS, SYSTEM AND PDBADMIN: anZERbg7P9k=1

LSNRCTL for Linux: Version 12.2.0.1.0 – Production on 30-MAR-2018 08:03:44

Copyright (c) 1991, 2016, Oracle.  All rights reserved.

Starting /opt/oracle/product/12.2.0.1/dbhome_1/bin/tnslsnr: please wait…

TNSLSNR for Linux: Version 12.2.0.1.0 – Production
System parameter file is /opt/oracle/product/12.2.0.1/dbhome_1/network/admin/listener.ora
Log messages written to /opt/oracle/diag/tnslsnr/8f14eca8ba12/listener/alert/log.xml
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1)))
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=0.0.0.0)(PORT=1521)))

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1)))
STATUS of the LISTENER
————————
Alias                     LISTENER
Version                   TNSLSNR for Linux: Version 12.2.0.1.0 – Production
Start Date                30-MAR-2018 08:03:46
Uptime                    0 days 0 hr. 0 min. 2 sec
Trace Level               off
Security                  ON: Local OS Authentication
SNMP                      OFF
Listener Parameter File   /opt/oracle/product/12.2.0.1/dbhome_1/network/admin/listener.ora
Listener Log File         /opt/oracle/diag/tnslsnr/8f14eca8ba12/listener/alert/log.xml
Listening Endpoints Summary…
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=0.0.0.0)(PORT=1521)))
The listener supports no services
The command completed successfully
[WARNING] [DBT-10102] The listener configuration is not selected for the database. EM DB Express URL will not be accessible.
CAUSE: The database should be registered with a listener in order to access the EM DB Express URL.
ACTION: Select a listener to be registered or created with the database.
Copying database files
1% complete
13% complete
25% complete
Creating and starting Oracle instance
26% complete
30% complete
31% complete

It will continue to configure the database.

Checking the container ID:

docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
8f14eca8ba12        49712d6a0946        “/bin/sh -c ‘exec …”   11 minutes ago      Up 11 minutes       1521/tcp, 5500/tcp   nostalgic_murdock

Connecting to it:

docker exec -it 8f14eca8ba12 bash

[oracle@8f14eca8ba12 ~]$ df
Filesystem     1K-blocks      Used Available Use% Mounted on
none           825567656 304142320 479465912  39% /
tmpfs           16478564         0  16478564   0% /dev
tmpfs           16478564         0  16478564   0% /sys/fs/cgroup
/dev/sda2      825567656 304142320 479465912  39% /etc/hosts
shm                65536         0     65536   0% /dev/shm
tmpfs           16478564         0  16478564   0% /sys/firmware

[oracle@8f14eca8ba12 ~]$ ps -ef|grep orac
oracle       1     0  0 08:03 ?        00:00:00 /bin/bash /opt/oracle/runOracle.sh
oracle      27     1  0 08:03 ?        00:00:00 /opt/oracle/product/LISTENER -inherit
oracle    2310     1  0 08:12 ?        00:00:00 ora_pmon_ORCLCDB
oracle    2312     1  0 08:12 ?        00:00:00 ora_clmn_ORCLCDB
oracle    2314     1  0 08:12 ?        00:00:00 ora_psp0_ORCLCDB
xxxxx
oracle    2818     1  0 08:12 ?        00:00:00 ora_qm02_ORCLCDB
oracle    2822     1  0 08:12 ?        00:00:00 ora_q002_ORCLCDB
oracle    2824     1  0 08:12 ?        00:00:00 ora_q003_ORCLCDB
oracle    2879     1  0 08:12 ?        00:00:00 tail -f /opt/oracle/diag/rdbms/orclcdb/ORCLCDB/trace/alert_ORCLCDB.log
oracle    2915     1  0 08:13 ?        00:00:00 ora_w002_ORCLCDB
oracle    2930     0  0 08:15 ?        00:00:00 bash
oracle    2949  2930  0 08:15 ?        00:00:00 ps -ef
oracle    2950  2930  0 08:15 ?        00:00:00 grep –color=auto orac

Finding out the TNS service name:

cd $ORACLE_HOME

cd network/admin/

cat tnsnames.ora

ORCLCDB=localhost:1521/ORCLCDB

ORCLPDB1=
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 0.0.0.0)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = ORCLPDB1)
)
)

So “ORCLCDB” is the name.

sqlplus system/anZERbg7P9k=1@ORCLCDB

SQL*Plus: Release 12.2.0.1.0 Production on Fri Mar 30 08:17:29 2018

Copyright (c) 1982, 2016, Oracle.  All rights reserved.

Connected to:
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 – 64bit Production

SQL> desc sys.tab$
Name                       Null?    Type
—————————————– ——– —————————-
OBJ#                       NOT NULL NUMBER
DATAOBJ#                        NUMBER
TS#                       NOT NULL NUMBER
FILE#                       NOT NULL NUMBER
BLOCK#                    NOT NULL NUMBER
BOBJ#                            NUMBER
TAB#                            NUMBER
COLS                       NOT NULL NUMBER
CLUCOLS                        NUMBER
PCTFREE$                   NOT NULL NUMBER
PCTUSED$                   NOT NULL NUMBER

SQL> select count(*) from sys.tab$;

COUNT(*)
———-
2149

Worked.

Now when you stop the container from another session:

Then the main session (which is this screen:   https://gist.github.com/tthtlc/8e0a04ff958e0d0a12b6395195579a1c) will automatically shutdown the database.

https://gist.github.com/tthtlc/930e4264c602f4b7eea027ab71a5fd77

But when you start up the stopped container, every Oracle processes will startup automatically.
docker ps -a
docker start 8f14eca8ba12
docker psCONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
8f14eca8ba12        49712d6a0946        “/bin/sh -c ‘exec …”   27 minutes ago      Up 3 seconds        1521/tcp, 5500/tcp   nostalgic_murdockdocker exec -it 8f14eca8ba12 bash

[oracle@8f14eca8ba12 ~]$ ps -ef|grep ora
oracle       1     0  0 08:30 ?        00:00:00 /bin/bash /opt/oracle/runOracle.sh
oracle      13     1  0 08:30 ?        00:00:00 /opt/oracle/product/LISTENER -inherit
oracle      20     1  0 08:31 ?        00:00:00 ora_pmon_ORCLCDB
oracle      22     1  0 08:31 ?        00:00:00 ora_clmn_ORCLCDB
oracle      24     1  0 08:31 ?        00:00:00 ora_psp0_ORCLCDB
oracle      26     1  0 08:31 ?        00:00:00 ora_vktm_ORCLCDB
oracle      30     1  0 08:31 ?        00:00:00 ora_gen0_ORCLCDB
oracle      32     1  5 08:31 ?        00:00:00 ora_mman_ORCLCDB

[oracle@8f14eca8ba12 ~]$ sqlplus system/anZERbg7P9k=1@ORCLCDB

Connected to:
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 – 64bit Production

SQL>

Successful.

And in case we may forget the password, let us just change it to default:

sqlplus system/anZERbg7P9k=1@ORCLCDB

SQL> show user
USER is “SYSTEM”
SQL> alter user system identified by manager;

User altered.

sqlplus sys/anZERbg7P9k=1@ORCLCDB as sysdba

SQL> show user
USER is “SYS”

SQL> alter user sys identified by manager;

User altered.

 Completed:

Parallella: booting up parabuntu

https://www.parallella.org/

https://www.parallella.org/wp-content/uploads/2014/11/parallella-board-22-609×400.jpg

https://www.parallella.org/wp-content/uploads/2014/11/P16000-01-A1_1024x10241-609×400.jpg

And manual:

https://www.parallella.org/docs/parallella_manual.pdf

Images ready for flashing to sdcard:

https://github.com/parallella/parabuntu/releases

Installing on the SD card (using “dd” command) and letting it run (output is captured in the UART through usb2serial ftdi cable):

The bootup log is here:

https://gist.github.com/tthtlc/c7e267d7fbf95d3d366146233b28554f

First install “openssh-server” on the device instead:

apt-get update

apt-get install openssh-server

And next is to plugin the network UTP cable into the RJ45 port and start downloading examples.

Downloading examples to try:

(https://www.parallella.org/2016/01/21/creating-an-fpga-accelerator-in-15-minutes/)

The following are needed:

apt-get install iverilog

apt-get install gtkwave

git clone https://github.com/parallella/oh

Setting up env:

source setenv.sh

and then running example “./run.sh accelerator”:

Another example source:

git clone https://github.com/parallella/parallella-examples.git
cat /proc/cpuinfo
 processor : 0
 model name : ARMv7 Processor rev 0 (v7l)
 BogoMIPS : 1332.01
 Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpd32
 CPU implementer : 0x41
 CPU architecture: 7
 CPU variant : 0x3
 CPU part : 0xc09
 CPU revision : 0

processor : 1
 model name : ARMv7 Processor rev 0 (v7l)
 BogoMIPS : 1332.01
 Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpd32
 CPU implementer : 0x41
 CPU architecture: 7
 CPU variant : 0x3
 CPU part : 0xc09
 CPU revision : 0

Hardware : Xilinx Zynq Platform
 Revision : 0003
 Serial : 0000000000000000

Accessing other CPUs will require some custom programming.

References:

https://www.parallella.org/2015/04/05/parallella-chronicles-part-six-moving-multiple-bytes-simply/

Kernel source code static analysis with clang: lots of false positive

Clicked the above to see the details (below):

Steps in compiling Linux kernel with LLVM scan-build/scan-view:

1. change the "Makefile" – all "gcc" should be replaced by "clang", and similarly for "g++" to "clang++".
2. copy .config from somewhere, (eg, Ubuntu) and "make oldconfig" to autogenerate the .config file.

3. then "make kernel" to make sure compilation completes fine.

4. then "make clean" and "scan-build make kernel" to building using clang.

5. view the output:

scan-view –allow-all-hosts –no-browser –debug /tmp/scan-build-2018-03-21-001413-5298-1

Just focusing on the memory leak:

So LLVM knows alloc_and_copy_xxx() allocate memory resources.

now how is the conclusion of leakage at 27 achieved?

since memory is always freed as the last line indicated, no leakage is possible.

So the reason is because free_ftrace_hash() is not associated with free() of memory as allocated earlier.

Looking at next one:

Similarly, kfree() is not known to do freeing of memory resources.

And the following is clearly wrong too:

(kfree() is deallocator).

References:

https://clang-analyzer.llvm.org/

https://clang-analyzer.llvm.org/scan-build.html

https://clang-analyzer.llvm.org/

http://btorpey.github.io/blog/2015/04/27/static-analysis-with-clang/

powerpc linux kernel board bring-up problem

Reading this forum:

https://forum.kernelnewbies.org/read.php?18,118113,118113#msg-118113

And to requote the problem here:

Hi everyone!

I got lucky and got an embedded linux internshipsmiling smiley

I’m trying to port linux to an existing board that is currently using vxWorks.
The board uses an mpc8572e processor which contains two e500v2 cores. Basically, the entry point in vmlinux
is arch/powerpc/kernel/head_fsl_booke.S

We are using the simpleboot bootwrapper which works just fine (simpleboot passes the device tree address and jump right into the gunziped vmlinux which is located at 0x0 physical).

head_fsl_booke.S include arch/powerpc/kernel/fsl_booke_entry_mapping.S and we just crash at line 223 (rfi instruction)
of fsl_booke_entry_mapping.S

215 lis r7,MSR_KERNEL@h
216 ori r7,r7,MSR_KERNEL@l
217 bl 1f /* Find our address */
218 1: mflr r9
219 rlwimi r6,r9,0,20,31
220 addi r6,r6,(2f – 1b)
221 mtspr SPRN_SRR0,r6
222 mtspr SPRN_SRR1,r7
223 rfi /* start execution out of TLB1[0] entry */

rfi at line 223 causes us to jump to 0xc000_0264 while we want to jump to 0x000_0264.
This is not caused by our mmu, we are basically loading 0xc000_0264 in srr0

It’s related to the following config fields in our defconfig:
CONFIG_PAGE_OFFSET=0xc0000000 <—-
CONFIG_PHYSICAL_START=0x00000000
CONFIG_PHYSICAL_ALIGN=0x04000000
CONFIG_TASK_SIZE=0xc0000000
CONFIG_KERNEL_START=0xc00000000 <—–

I tried to set CONFIG_KERNEL_START and CONFIG_PAGE_OFFSET to 0x0 but this would not compile:
arch/powerpc/include/asm/processor.h:100:2: error: #error User TASK_SIZE overlaps with KERNEL_START address

By the way CONFIG_TASK_SIZE=0xc0000000

Also, my debugger cannot map anything because all the symbols in vmlinux are at 0xcxxx_xxxx but we are at 0x0xxx_xxxx

Pretty much all the ports that uses the simpleboot bootwrapper are gunzipping vmlinux at 0x0 but I can easily change that
and I tried to send vmlinux at 0xc000_0000 and it solved this particular issue but then the mmu mapping just does not work
because simpleboot extract our device tree at about 0x0011_0000 and we need vmlinux and the device tree to be inside a 64Mb page (also tried to hack fsl_booke_entry_mapping.S to create a 4GB tlb entry based at 0x0 and this was causing other issues…)

Got any idea?

The details I cannot help.   But my suggested steps of action are as follows:

First is to get the cross-compiler for e500v2 (ppc):

https://www.nxp.com/docs/en/supporting-information/WBNR_FTF10_NET_F0676.pdf

http://zeromq.org/build:powerpc

https://community.nxp.com/thread/310153

Next is to compile uboot for the board:

https://github.com/theopolis/u-boot-sboot

which is support board itself (mpc8572e).   Next is the emulator, but not sure if it works? (though it indicated support for mpc8572e)

https://github.com/tycho/pearpc

And to understand how uboot can startup the PPC CPU, you will need to know PPC hardware knowledge specific to e500v2 and all the bootup details:
And then only the final steps is the understanding of Linux kernel itself, and its bootup requirements:

 

Internals of ptrace(): from the malware perspective

After reading a few questions on ptrace():

https://stackoverflow.com/questions/24573247/ptrace-how-can-i-stop-getting-traced-in-child-process

https://stackoverflow.com/questions/29804846/where-would-the-cpu-context-interrupted-by-ptrace-be-userspace-stack-or-kernel?rq=1

https://stackoverflow.com/questions/27930589/when-using-getregs-does-ptrace-get-only-userspace-stack-rsp-or-both-kernel-and/48626668#48626668

I realize there is a great lack of understanding of the power and depth of ptrace().

First I shall describe all the power of ptrace():

a. When you ptrace() another program (called debuggee), the debuggee basically will stopped completely (in userspace) and let you do whatever you want with his registers, memory, and essentially everything in userspace.

http://man7.org/linux/man-pages/man2/ptrace.2.html

b. You can legally do anything that is read-only. But if you modify the register, then be aware of the consequences.

c. Malware writer likes to use ptrace(), but why and how?

This is because with ptrace(), you can essentially redirect the debuggee to call malloc(), and given the newly allocated memory, insert a new program into the newly allocated memory (making sure the pages are marked readable and executable), and redirect some existing codes to that memory for execution and then let the debuggee continue execution.

There is a lot more details then that, requiring many ptrace() calls for its complete implementation. And various names are given for it, libraries injection is one of them.

https://github.com/gaffe23/linux-inject

https://shunix.com/shared-library-injection-in-android/   (Android and other Linux shared the same kernel, or almost).

d. A syscall, by definition, is an atomic operation: this means that if it start in userspace, it will end up in userspace. It should not terminate its execution in the kernel, unless it has encountered some blocking kernel functions. An example is “kmalloc()”, which can block, and thus immediately the execution thread will be queued and to be replaced by the next tasks for execution on the CPU.

e. For security reasons, kernel execute at ring 0, and userspace is at ring 3. So by design, userspace will never be able to see any of the values on the registers or memory IN THE KERNEL. Anything to be displayed must be specifically read and transfer over from kernel to userspace.

f. The relationship between the debugger and debuggee, is a highly interlocking one:   when one is executing, you have to ensure the other is blocked and waiting for exception.   Ie, when you ptrace() the debuggee, the debugger will immediately go into a waiting mode (blocking), so that when the debuggee enter a blocking instruction, execution will return back to the debugger, and only when it is in the waiting mode will he be able to catch it.   And vice versa – it can really get very complicated between waiting and continue execution etc.

References:

c – How to detect if the current process is being run by GDB? – Stack Overflow

https://stackoverflow.com/questions/3596781/how-to-detect-if-the-current-process-is-being-run-by-gdb

Accessing data in the RAM of one process from second process

https://stackoverflow.com/questions/27853198/accessing-data-in-the-ram-of-one-process-from-second-process/27853327#27853327

%d bloggers like this: