> For the complete documentation index, see [llms.txt](https://sayonara.gitbook.io/writeups/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://sayonara.gitbook.io/writeups/ctf/nullcon-hackim-ctf-goa-2023/web/ipfilter.md).

# &#x20;IPfilter

### <mark style="color:blue;">Challenge Description</mark>

<div align="left"><figure><img src="/files/bk7SVnZnsVtvJoaa4HFb" alt=""><figcaption></figcaption></figure></div>

<div align="left"><figure><img src="/files/d9K1LX7A4VBK0XB6WwbW" alt=""><figcaption></figcaption></figure></div>

let's view source code and it give us a hint

<div align="left"><figure><img src="/files/vnAFild6ZcoIVdhfOPcy" alt=""><figcaption></figcaption></figure></div>

so let's use the parameter ?src in the url&#x20;

and it reveals `php code`

<div align="left"><figure><img src="/files/vyAGuobmh1mb6GORVC7U" alt=""><figcaption></figcaption></figure></div>

```php
<?php
        error_reporting(0);
        function fetch_backend($ip) {
            if(is_bad_ip($ip)) {
                return "This IP is not allowed!";
            }
            return file_get_contents("http://". $ip . "/");
        }
        function is_bad_ip($ip) {
            if(!preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/', $ip)) {
                // IP must be in X.Y.Z.Q format
                return true;
            }
            $frontend = gethostbyname(gethostname());
            $backend = gethostbyname("ipfilter_backend");
            $subnet = long2ip(ip2long($frontend) & ip2long("255.255.255.0"));
            $bcast = long2ip(ip2long($frontend) | ~ip2long("255.255.255.0"));

            if(isset($_GET['debug_filter'])) {
                echo "<pre>";
                echo "IP: " . $ip . "<br>";
                echo "Frontend: " . $frontend . "<br>";
                echo "Backend: " . $backend . "<br>";
                echo "Subnet:" . $subnet . "<br>";
                echo "Broadcast:" . $bcast . "<br>";
                echo  "</pre>";
            }

            if(inet_pton($ip) < (int) inet_pton($subnet)) {
                // Do not go below the subnet!
                return true;
            }
            if(! (inet_pton($ip) < inet_pton($bcast))) {
                // Do not go above the subnet!
                return true;
            }
            if($ip == $backend) {
                // Do not allow the backend with our secrets ;-)
                return true;
            }
            return false;
        }
        if(isset($_GET['fetch_backend']) ) {
            echo fetch_backend($_GET['bip']);
        }
        if(isset($_GET['src'])) {
            highlight_file(__FILE__);
        }
        // with <3 from @gehaxelt
    ?>
```

Testing with any IP gets you the backend server IP you need to provide.

<div align="left"><figure><img src="/files/9kZzJ4Qym1Ve4apdPvWN" alt=""><figcaption></figcaption></figure></div>

so 192.168.112.3 is the backend ip we want to fetch from the flag but unfortunately it's filtering ip and restrict access to this ip

<div align="left"><figure><img src="/files/pDivrJTc0Jk0VnZ3bhjT" alt=""><figcaption></figcaption></figure></div>

Bypassing the filter is easy because unlike the other checks, it just compares strings.\
`192.168.112.3 != 192.168.112.003` but obviously still resolves to the same machine.

#### <mark style="color:red;">**vulnerable php code snippet**</mark>&#x20;

```php
if ($ip == $backend) {
    // Do not allow the backend with our secrets ;-)
    return true;
}
```

[**https://www.hacksparrow.com/networking/many-faces-of-ip-address.html**](https://www.hacksparrow.com/networking/many-faces-of-ip-address.html) here specifies all the different ways to specify IPs that also works on browsers.

<div align="left"><figure><img src="/files/S7BnHNQ1W6SYqePKlDgb" alt=""><figcaption></figcaption></figure></div>

### <mark style="color:blue;">Flag</mark>

```
ENO{Another_Fl4G_something_IP_STuff!} 
```
