實戰 | 某OJ滲透測試記錄
并沒有什么技術含量,純粹就是玩個黑盒的過程。挺有意思的,所以就寫下來了。
起因
群里說,他們那有個 OJ 是用 win-dows 的

當然二話不說上來看看咯。
開整之前大致想出流程,
- 判斷是否容器
- 判斷是否出網
第一因為是用 win-dows 所以有點希望,就來驗證第二個看看。
bypass
先找個時間長點的題目

上去提交代碼。能用的有 C/C++/G++/JAVA/C# 以及 PAS-CAL

試了一下,C/C++ 沒有 win-dows.h,基本的 sys-tem 等函數就直接 re-set 了。
估計有一些防火墻。
運氣好,發現 C# 能執行 api???
這下好說了,shell-code 走起。
直接參考這個
C# 加載 shellcode
https://blog.csdn.net/Jailman/article/details/77574019
提交,運行,之后 cs 上線了

但是 10s 一過就被 k 了。
原本是想找個能自動復制的 shell-code,或者是干脆直接 ex-e2shell-code 然后編碼到代碼里提交上去寫出
結果提交代碼有長度限制,最多 6kb,只能繼續在 shell-code 上整活了。
那么繼續,我們換個思路。
我們把自己復制一個,然后用 api 把自己運行不就行了?
經過測試之后,發現,Cre-ateProcess 這個 api 可以用,shellEx-e-cute 這些倒是被 re-set 了。
那么接下來就簡單了

測試之后發現,只有本體線程上線了。。。復制之后的那個沒上線?這就很尷尬。
現在有 3 個猜測
- Temp 文件夾沒權限
- CreateProcess 并不能運行
- 本體不是 exe 而是某種動態執行的東西,所以復制本體出去壓根不是正確的 PE 文件
總體來說就這三種情況,那么我們該怎么排查呢?
偽黑盒測測
oj 也不是完全黑盒,oj 也是有返回結果的

其中我們只需要關注 Judge Status,Exe.Time,Exe.Memory 這些就行
前兩個我們是可以手動控制結果,后面一個 Mem-ory 是判斷我們程序是否正確運行。
那么接下來就簡單了。我們可以手動一個選擇支 (if),達成某種目標,就給出正確答案,或者超時等等。
我們先判斷程序是否復制到了 Temp 文件夾下面,如果復制到了那么就直接 Sleep 到超時。
if (File.Exists("C:\\WINDOWS\\Temp\\asd.exe"))
{
System.Threading.Thread.Sleep(2000);
return;
}else{return;}
經過測試之后發現,文件不存在。程序并沒有超時,直接 re-turn 了。
繼續判斷擴展名
string filename = System.IO.Path.GetFileName(szPath);
if(Path.GetExtension(fileName)==".exe"){System.Threading.Thread.Sleep(2000);}
發現超時,說明文件確實被編譯成 exe 了。
那么既然 temp 目錄沒有權限,那么我們就直接復制到本地目錄不就行了嘛。
經過修改代碼之后,提交運行。這次倒是上線了兩個。
但是依舊是過了 10s,這兩個程序同時掉線了。預測是被 k 了。
這就很奇怪了。
難道 TMD 學 360 還能判斷進程鏈?還是說有什么組策略?
既然這樣,我們就換個方法,既然它會 k 進程鏈,那么我們就注入到不是我們創建的進程不就行了嘛?
經過測試,Process 這個關鍵字沒被攔截,那么 Process[] processes = Process.GetProcessesByName(processName); 這個方法應該也不會被攔截,試了一下果不其然。
這 oj 真的有做過濾嘛 emmm,不過能調用 api 本來也就很奇怪了吧。
依舊同樣的方法,判斷 ex-plorer.exe 是否存在,然后找到它的 pid。
這里要注意點,可能找到的不一定是 guest 用戶的 ex-plorer 也許是其他用戶的,我們不一定有權限注入。
所以是循環查找。
然后就是遠程線程注入。

很好,自信滿滿,提交運行。
結果:

????
換了 x64/x32 的 shell-code 都不行,msf 的也試過了。全 TMD 都不行。
我本地測試一下也奇怪的奔潰了。但是用 C++ 寫的那份卻可以運行。怪事。
不得已,只能上 CPP 了,還是 CPP 用的順手。
不過在此之前只能祈禱這上面能用內聯匯編
提交了個
#include int main(){__asm{NOP;}return 0;}
上去,發現編譯通過了!!!
不就是不能用 windows.h 嘛,小事。
之前想過,不能用 win-dows.h 最大的問題是什么?不能調用 winapi 嘛。
然而懂計算機的都知道,我們只需要知道函數的地址,然后手動 call 不就能調用了嘛。
和這種情況類似的有什么呢?對,就是 shell-code。直接 PEB 或者 SEH 查找 k32.dll 的地址然后再找到 Load-Li-brary 和 Get-P-ro-cAd-dress 的地址,那么 winapi 不就是隨便用了嗎?
因為僅僅是不能用 windows.h,和我另外一篇 自己動手打造一份熊貓燒香 ,還是有點區別的,至少 str-cat 這些簡單函數都能用,其他的都好說了。
為了節約代碼長度,這次不用上一篇文章的那個方法整結構體了。直接參考
[Windows 下 Shellcode 編寫詳解]
https://xz.aliyun.com/t/2108
中的內聯匯編代碼,抄出來稍微改改就行

然后就是定義 api 然后調用

代碼很長后面我就不截圖了。有了 API 原理就和 C# 版本的一模一樣
一樣的注入 ex-plorer.exe,提交,運行。
感天動地,終于上線了。過了一分鐘也沒被 k。
收尾
現在就是判斷系統版本,先判斷系統版本,sys-tem-info 是不能用的,tasklist 也不行。因為是 guest 權限不是那些 IIS 權限,所以前段時間我用的很爽的各種土豆都用不了,這土豆是真滴好用。啊廢話有點多。
用 C# 隨便寫一個判斷系統版本的丟上去。
這時候確實是 C# 比較舒服。.net 庫還是全的,如果是 CPP 整 winapi 還得弄一堆七七八八。
最后結果是 win7。雖然結果是這么寫的,但是也有可能是 08 之類的東西。因為上傳 shell-code 沒被殺,所以確認是沒有殺軟,直接提交 exp 吧。
有了這個就很簡單了,隨便找個 1458 丟上去,運氣好提權成功。

用 1458 的時候還出了點小意外,詳情可以看我博客里面有個 tgchan-nal。過于丟人就不說了,總之還是換了 8639,提權成功。
接下來就是橫向了,不過我只是為了日 OJ 而來,剩下的就索然無味了,橫向還是日 tw 的 edu 好玩。又沒有法律風險,難度也不是很高,他們的 web 一個個都可以是夢回 2008 年代的畫風。但是意外的洞卻不多,所以又簡單的同時也有難度,啊又跑題了。
總之第一步隨手看個 netstat -an,以及 arp -a,查看其他資產,有 mysql 連接,這種主機肯定存在 MySQL 配置,可以用來橫向。
第二步當然是我們最愛的 ms17010 啦。

em-mmm,這管理員真的有在管學校嘛。
剩下的沒意思,溜了溜了